• Show log

    Commit

  • Hash : c51065e3
    Author : Roberto Tyley
    Date : 2011-10-24T14:39:03

    Tolerate zlib deflation with window size < 32Kb
    
    libgit2 currently identifies loose objects as corrupt if they've been
    deflated using a window size less than 32Kb, because the
    is_zlib_compressed_data() function doesn't recognise the header
    byte as a zlib header. This patch makes the method tolerant of
    all valid window sizes (15-bit to 8-bit) - but doesn't sacrifice
    it's accuracy in distingushing the standard loose-object format
    from the experimental (now abandoned) format. It's based on a patch
    which has been merged into C-Git master branch:
    
    https://github.com/git/git/commit/7f684a2aff636f44a506
    
    On memory constrained systems zlib may use a much smaller window
    size - working on Agit, I found that Android uses a 4KB window;
    giving a header byte of 0x48, not 0x78. Consequently all loose
    objects generated by the Android platform appear 'corrupt' :(
    
    It might appear that this patch changes isStandardFormat() to the
    point where it could incorrectly identify the experimental format as
    the standard one, but the two criteria (bitmask & checksum) can only
    give a false result for an experimental object where both of the
    following are true:
    
    1) object size is exactly 8 bytes when uncompressed (bitmask)
    2) [single-byte in-pack git type&size header] * 256
       + [1st byte of the following zlib header] % 31 = 0 (checksum)
    
    As it happens, for all possible combinations of valid object type
    (1-4) and window bits (0-7), the only time when the checksum will be
    divisible by 31 is for 0x1838 - ie object type *1*, a Commit - which,
    due the fields all Commit objects must contain, could never be as
    small as 8 bytes in size.
    
    Given this, the combination of the two criteria (bitmask & checksum)
    always correctly determines the buffer format, and is more tolerant
    than the previous version.
    
    References:
    
    Android uses a 4KB window for deflation:
    http://android.git.kernel.org/?p=platform/libcore.git;a=blob;f=luni/src/main/native/java_util_zip_Deflater.cpp;h=c0b2feff196e63a7b85d97cf9ae5bb258
    
    Code snippet searching for false positives with the zlib checksum:
    https://gist.github.com/1118177
    
    Change-Id: Ifd84cd2bd6b46f087c9984fb4cbd8309f483dec0