Skip to content

qgustavor/patcher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Patcher

A file patcher that works in the browser. Intended to be used by anyone who distributes any kind of file and wants to provide a simple page where people can have old files patched easily without having to download binaries or patches.

How it works

  1. User opens one or more files in the tool
  2. The tool generates a keyed Blake3 hash of each file
  3. The first 6 bytes of the hash are Base64-URL encoded and used to fetch a patch file (that's in order to provide a bit of anonymity in case someone opens a unknown file)
  4. If there's a patch available then it's downloaded, decrypted and decompressed (patches are encrypted by default in case someone prefers the patch contents to be hidden)
  5. The patch is applied and the fixed file is downloaded.

Demo

You can test it here.

Test it with jquery-3.4.0.min.js to get jquery-3.4.1.min.js or with vue@2.6.0 to get vue@2.6.10.

Limitations

  • It's made for modern browsers: it will not work in older browsers.
  • It uses Streams API to process large files without needing to handle entire files in memory. In browsers that don't fully support this API the browser can crash out of memory.
  • It also uses Native File System API for loading and saving files from directories but only in few supported browsers.
  • There are some cases where the patching code isn't efficient resulting in large patches. It often happen with compressed files or most of the file contents changed.
  • Privacy could be improved by reducing the hash identifier from 6 bytes to something lower, then allowing multiple patches to account for the collisions, but it wasn't implemented for the sake of simplicity.

How to use

Copy the code from the repository, delete the sample patches, generate new patches using generate-patch.html then host those somewhere. One easy way to do this is forking this repository, editing the fork in the web interface and enabling GitHub Pages in the settings.

It's good to change styling of both index.html and generate-patch.html pages adding some logo or changing colors as you prefer.

You can also translate index.html to your language or edit it as you prefer. A Portuguese translation is available as pt.html. If you want to disable encryption or compression you can edit main.js and generate-patch.html removing encryption and decryption steps. To allow patching large files those are chunked in 8 MiB parts. You can change this variable in generate-patch.html. Using larger chunks will result in smaller patches but those can crash browsers out of memory.

If you already have some kind of backend you can replace this line with a fetch() to your backend, something like await fetch('/save-patch.php?name=' + window.encodeURIComponent(patchName), { method: 'POST', body: ciphertext }). Remember to use some kind of authentication.

Libraries used