{"id":16911002,"url":"https://github.com/thoughtpolice/minibsdiff","last_synced_at":"2025-03-17T07:30:53.333Z","repository":{"id":4512656,"uuid":"5652388","full_name":"thoughtpolice/minibsdiff","owner":"thoughtpolice","description":"A miniature, portable version of bsdiff.","archived":false,"fork":false,"pushed_at":"2017-10-31T14:30:41.000Z","size":75,"stargazers_count":126,"open_issues_count":3,"forks_count":29,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-02-27T19:34:07.831Z","etag":null,"topics":["bsdiff","compression"],"latest_commit_sha":null,"homepage":"http://daemonology.net/bsdiff/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thoughtpolice.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-09-02T22:26:57.000Z","updated_at":"2024-12-27T22:02:44.000Z","dependencies_parsed_at":"2022-09-02T21:20:34.905Z","dependency_job_id":null,"html_url":"https://github.com/thoughtpolice/minibsdiff","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtpolice%2Fminibsdiff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtpolice%2Fminibsdiff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtpolice%2Fminibsdiff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thoughtpolice%2Fminibsdiff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thoughtpolice","download_url":"https://codeload.github.com/thoughtpolice/minibsdiff/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243848021,"owners_count":20357482,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bsdiff","compression"],"created_at":"2024-10-13T19:04:08.446Z","updated_at":"2025-03-17T07:30:53.063Z","avatar_url":"https://github.com/thoughtpolice.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# minibsdiff: a miniature, portable version of bsdiff [![Build Status][]](http://travis-ci.org/thoughtpolice/minibsdiff)\n\n[Build Status]: https://secure.travis-ci.org/thoughtpolice/minibsdiff.png?branch=master\n\nColin Percival's [bsdiff][] is a popular tool for creating and applying patches\nto binary software. This is a stripped down copy of `bsdiff` that's designed to\nbe portable and reusable as a library in your own software (if you wanted to\nsay, create your own update system.) Many people end up reusing bsdiff (it's\nstable, well-known, works great, and has a good license,) but I haven't found a\nstandalone copy of the library somewhere that I could easily reuse, so I made it.\n\nThis code is based on [bsdiff v4.3](http://www.daemonology.net/bsdiff/bsdiff-4.3.tar.gz).\n\nThe main differences:\n\n  * Control and data blocks in the patch output are not `bzip2` compressed.\n    You'll have to apply your own compression method. **This is a very\n    important part of bsdiff's design, and if you don't apply a compression\n    method at some level when using this library, it won't buy you anything**.\n    Please see the 'Usage' section below.\n\n  * Patches produced by this library are incompatible with those produced by\n    the classic bsdiff tool. (The header format has changed appropriately so\n    they are both incompatible with each other.) You're encouraged to change\n    this when using the library yourself - see 'Usage' below.\n\n  * The code has been refactored into a reusable API (documented below)\n    consisting of a few simple functions in `bsdiff.h` and `bspatch.h`. It\n    should be easily usable from any programming language. It has zero external\n    dependencies.\n\n  * It works everywhere (even under MSVC.)\n\n  * There's a simple example included that should show you how to get started.\n\n  * Because there are no external dependencies and it's so small, **minibsdiff\n    is great place to start if you need to customize bsdiff yourself**! You'll\n    inevitably want to do this as time goes on, and most of the work is done\n    for you.\n\n# Usage\n\n## Building\n\nCopy `bsdiff.{c,h}`, `bspatch.{c,h}`, `minibsdiff-config.h` and\n`{stdbool,stdint}-msvc.h` in your source tree and you're ready to go. You\nshouldn't need any special build settings for it to Just Work(TM).\n\n## API\n\n```c\n#include \"bsdiff.h\"\n#include \"bspatch.h\"\n\n/*-\n * Determine the maximum size of a patch between two files. This function\n * should be used to allocate a buffer big enough for `bsdiff` to store\n * its output in.\n */\noff_t bsdiff_patchsize_max(off_t oldsize, off_t newsize);\n\n/*-\n * Create a binary patch from the buffers pointed to by oldp and newp (with\n * respective sizes,) and store the result in the buffer pointed to by 'patch'.\n *\n * The input pointer 'patch' must not be NULL, and the size of the buffer must\n * be at least 'bsdiff_patchsize_max(new,old)' in length.\n *\n * Returns -1 if `patch` is NULL, the 'patch' buffer is not large enough, or if\n * memory cannot be allocated.\n * Otherwise, the return value is the size of the patch that was put in the\n * 'patch' buffer.\n *\n * This function is memory-intensive, and requires max(17*n,9*n+m)+O(1) bytes\n * of memory, where n is the size of the new file and m is the size of the old\n * file. It runs in O((n+m) log n) time.\n */\nint bsdiff(u_char* oldp, off_t oldsize,\n           u_char* newp, off_t newsize,\n           u_char* patch, off_t patchsize);\n\n/*-\n * Determine if the buffer pointed to by `patch` of a given `size` is\n * a valid patch.\n */\nbool bspatch_valid_header(u_char* patch, ssize_t patchsz);\n\n/*-\n * Determine the size of the new file that will result from applying\n * a patch. Returns -1 if the patch header is invalid, otherwise returns\n * the size of the new file.\n */\nssize_t bspatch_newsize(u_char* patch, ssize_t patchsize);\n\n/*-\n * Apply a patch stored in 'patch' to 'oldp', result in 'newp', and store the\n * result in 'newp'.\n *\n * The input pointers must not be NULL.\n *\n * The size of 'newp', represented by 'newsz', must be at least\n * 'bspatch_newsize(oldsz,patchsz)' bytes in length.\n *\n * Returns -1 if memory can't be allocated, or the input pointers are NULL.\n * Returns -2 if the patch header is invalid. Returns -3 if the patch itself is\n * corrupt.\n * Otherwise, returns 0.\n *\n * This function requires n+m+O(1) bytes of memory, where n is the size of the\n * old file and m is the size of the new file. It does no allocations.\n * It runs in O(n+m) time.\n */\nint bspatch(u_char* oldp,  ssize_t oldsz,\n            u_char* patch, ssize_t patchsz,\n            u_char* newp,  ssize_t newsz);\n\n```\n\n## Building the example program.\n\nFor an full example of using the API, see `minibsdiff.c`, which roughly\nreimplements the standard `bsdiff/bspatch` in a single tool (without\ncompression.) To build it:\n\n  * Running `make` on Linux or OS X. If you have MinGW installed and on\n    your `PATH` then you can do `make MinGW=YES` which will build an\n    `.exe` on Windows.\n\n  * There is a `CMakeLists.txt` file you can use to generate Ninja, MSVC or\n    MinGW makefile projects for Windows as well. You can of course use `cmake`\n    on Linux/OS X as well.\n\n## Customization notes.\n\nYou can change the patch file's magic number by modifying `BSDIFF_CONFIG_MAGIC`\nin `minibsdiff-config.h`. It must be 8 bytes long (anything beyond that will be\nignored.) This library by default has the magic number `MBSDIF43`.\n\n---\n\n**You should really, really, really compress the output in some way**. Whether\nor not you do that directly in the diff/patch routines or on the result you get\nfrom calling them is irrelevant. If you don't do this, **bsdiff will buy you\nnothing**.\n\nBriefly, bsdiff is based on the concept of finding approximate matches between\ntwo executable files, and calculating and storing their bytewise differences in\nthe patch file. The patch format is roughly composed of a control block\nspecifying how to add and insert changes from the new executable into the old\none, and a difference block actually composed of the differences.\n\nBinary updates to software packages tend to have disproportionate amounts of\nbinary-level differences from just a few source code changes. The key\nobservation however is that most code is still the same, but *relocated* in\nsuch a way that things like internal pointers are always offset in a\npredictable manner.  For example, if you have a single translation unit with 5\nfunctions, and you fix a small bug in this code and ship it to users, the\n*symbolic representation* has not changed all that much, but the change will\nresult in *executable* differences affecting all 5 functions, such that e.g.\nrelative pointers must all be adjusted properly, across all of them.\n\nBut even then, many of these 'relocations' will be small (a byte or two,) and\nmore than that, they will often be very regular, meaning the differences are\nhighly redundant, and thus compressible.\n\nAs a result, an uncompressed patch from bsdiff is roughly on par with the new\nfile in size, but compression can reduce it's size dramatically due to repeated\ndata in the differences (by a factor of 10x or 20x.) In fact, without some sort\nof compression, it practically defeats the purpose of using it in the first\nplace!\n\nNot having compression by default is still a feature, though - it keeps the\nlibrary simple and portable, and you can layer it in however you want because\nthe source is small and easy to hack. But realistically, you'll **always** want\nto compress it at one point or another in the Real World.\n\nHere are some good compression libraries you might be interested in:\n\n  * [zlib](http://www.zlib.net)\n  * [gzip](http://www.gzip.org)\n  * [lz4](http://code.google.com/p/lz4)\n  * [snappy](http://code.google.com/p/snappy)\n  * [quicklz](http://www.quicklz.com)\n\nIn my non-scientific experiments, **bzip at compression level 9 gives the best\noutput size** out of all the ones listed above. It's obviously worth\nsacrificing compression time/speed for smaller updates that decompress quickly.\n\n# Join in\n\nFile bugs in the GitHub [issue tracker][].\n\nMaster [git repository][gh]:\n\n* `git clone https://github.com/thoughtpolice/minibsdiff.git`\n\nThere's also a [BitBucket mirror][bb]:\n\n* `git clone https://bitbucket.org/thoughtpolice/minibsdiff.git`\n\nIf you're going to submit a pull request or send a patch, **sign off on your\nchanges** by using `git commit -s`. I manage the `Signed-off-by` field like\ngit: by signing off, you acknowledge that the code you are submitting for\ninclusion abides by the license of the project. An `Acked-by` field states that\nsomeone has reviewed this code, and at the very least it is not completely\ninsane.\n\n# Authors\n\nSee [AUTHORS.txt](https://raw.github.com/thoughtpolice/minibsdiff/master/AUTHORS.txt).\n\n# License\n\n2-clause BSD. See `LICENSE.txt` for terms of copyright and redistribution.\n\n[bsdiff]: http://www.daemonology.net/bsdiff/\n[issue tracker]: http://github.com/thoughtpolice/minibsdiff/issues\n[gh]: http://github.com/thoughtpolice/minibsdiff\n[bb]: http://bitbucket.org/thoughtpolice/minibsdiff\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthoughtpolice%2Fminibsdiff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthoughtpolice%2Fminibsdiff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthoughtpolice%2Fminibsdiff/lists"}