{"thread":{"id":"28015","subject":"[PATCH] Tolerate zlib deflation with window size < 32Kb","startedAt":"2011-08-03T22:32:10Z","lastAt":"2011-08-08T20:07:43Z","messageCount":8,"participants":["roberto.tyley@gmail.com","Junio C Hamano","Roberto Tyley","Sverre Rabbelier"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"172826","messageId":"1312410730-12261-1-git-send-email-roberto.tyley@gmail.com","threadId":"28015","inReplyTo":null,"subject":"[PATCH] Tolerate zlib deflation with window size < 32Kb","fromName":"","fromEmail":"roberto.tyley@gmail.com","sentAt":"2011-08-03T22:32:10Z","receivedAt":"2011-08-03T22:32:10Z","isPatch":true,"sender":{"key":"roberto.tyley@gmail.com","avatar":"https://avatars.githubusercontent.com/u/52038?v=4"},"body":"From: Roberto Tyley <roberto.tyley@guardian.co.uk>\n\nGit currently reports loose objects as 'corrupt' if they've been\ndeflated using a window size less than 32Kb, because the\nexperimental_loose_object() function doesn't recognise the header\nbyte as a zlib header. This patch makes the function tolerant of\nall valid window sizes (15-bit to 8-bit) - but doesn't sacrifice\nit's accuracy in distingushing the standard loose-object format\nfrom the experimental (now abandoned) format.\n\nOn memory constrained systems zlib may use a much smaller window\nsize - working on Agit, I found that Android uses a 4KB window;\ngiving a header byte of 0x48, not 0x78. Consequently all loose\nobjects generated appear 'corrupt', which is why Agit is a read-only\nGit client at this time - I don't want my client to generate Git\nrepos that other clients treat as broken :(\n\nThis patch makes Git tolerant of different deflate settings - it\nmight appear that it changes experimental_loose_object() to the point\nwhere it could incorrectly identify the experimental format as the\nstandard one, but the two criteria (bitmask & checksum) can only\ngive a false result for an experimental object where both of the\nfollowing are true:\n\n1) object size is exactly 8 bytes when uncompressed (bitmask)\n2) [single-byte in-pack git type&size header] * 256\n   + [1st byte of the following zlib header] % 31 = 0 (checksum)\n\nAs it happens, for all possible combinations of valid object type\n(1-4) and window bits (0-7), the only time when the checksum will be\ndivisible by 31 is for 0x1838 - ie object type *1*, a Commit - which,\ndue the fields all Commit objects must contain, could never be as\nsmall as 8 bytes in size.\n\nGiven this, the combination of the two criteria (bitmask & checksum)\nalways correctly determines the buffer format, and is more tolerant\nthan the previous version.\n\nThe alternative to this patch is simply removing support for the\nexperimental format, which I am also totally cool with.\n\n\nReferences:\n\nAndroid uses a 4KB window for deflation:\nhttp://android.git.kernel.org/?p=platform/libcore.git;a=blob;f=luni/src/main/native/java_util_zip_Deflater.cpp;h=c0b2feff196e63a7b85d97cf9ae5bb2583409c28;hb=refs/heads/gingerbread#l53\n\nCode snippet searching for false positives with the zlib checksum:\nhttps://gist.github.com/1118177\n\n\nSigned-off-by: Roberto Tyley <roberto.tyley@guardian.co.uk>\n---\n sha1_file.c |   32 ++++++++++++++++++++++++++------\n 1 files changed, 26 insertions(+), 6 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 89d7e5e..2083e8b 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1217,14 +1217,34 @@ static int experimental_loose_object(unsigned char *map)\n \tunsigned int word;\n \n \t/*\n-\t * Is it a zlib-compressed buffer? If so, the first byte\n-\t * must be 0x78 (15-bit window size, deflated), and the\n-\t * first 16-bit word is evenly divisible by 31. If so,\n-\t * we are looking at the official format, not the experimental\n-\t * one.\n+\t * We must determine if the buffer contains the standard\n+\t * zlib-deflated stream or the experimental format based\n+\t * on the in-pack object format. Compare the header byte\n+\t * for each format:\n+\t *\n+\t * RFC1950 zlib w/ deflate : 0www1000 : 0 <= www <= 7\n+\t * Experimental pack-based : Stttssss : ttt = 1,2,3,4\n+\t *\n+\t * If bit 7 is clear and bits 0-3 equal 8, the buffer MUST be\n+\t * in standard loose-object format, UNLESS it is a Git-pack\n+\t * format object *exactly* 8 bytes in size when inflated.\n+\t *\n+\t * However, RFC1950 also specifies that the 1st 16-bit word\n+\t * must be divisible by 31 - this checksum tells us our buffer\n+\t * is in the standard format, giving a false positive only if\n+\t * the 1st word of the Git-pack format object happens to be\n+\t * divisible by 31, ie:\n+\t *      ((byte0 * 256) + byte1) % 31 = 0\n+\t *   =>        0ttt10000www1000 % 31 = 0\n+\t *\n+\t * As it happens, this case can only arise for www=3 & ttt=1\n+\t * - ie, a Commit object, which would have to be 8 bytes in\n+\t * size. As no Commit can be that small, we find that the\n+\t * combination of these two criteria (bitmask & checksum)\n+\t * can always correctly determine the buffer format.\n \t */\n \tword = (map[0] << 8) + map[1];\n-\tif (map[0] == 0x78 && !(word % 31))\n+\tif ((map[0] & 0x88) == 0x08 && !(word % 31))\n \t\treturn 0;\n \telse\n \t\treturn 1;\n-- \n1.7.4.1\n"},{"id":"172829","messageId":"7vsjpi82x7.fsf@alter.siamese.dyndns.org","threadId":"28015","inReplyTo":"1312410730-12261-1-git-send-email-roberto.tyley@gmail.com","subject":"Re: [PATCH] Tolerate zlib deflation with window size < 32Kb","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-03T23:56:36Z","receivedAt":"2011-08-03T23:56:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"roberto.tyley@gmail.com writes:\n\n> +\t * We must determine if the buffer contains the standard\n> +\t * zlib-deflated stream or the experimental format based\n> +\t * on the in-pack object format. Compare the header byte\n> +\t * for each format:\n> +\t *\n> +\t * RFC1950 zlib w/ deflate : 0www1000 : 0 <= www <= 7\n> +\t * Experimental pack-based : Stttssss : ttt = 1,2,3,4\n> +\t *\n> +\t * If bit 7 is clear and bits 0-3 equal 8, the buffer MUST be\n> +\t * in standard loose-object format, UNLESS it is a Git-pack\n> +\t * format object *exactly* 8 bytes in size when inflated.\n> +\t *\n> +\t * However, RFC1950 also specifies that the 1st 16-bit word\n> +\t * must be divisible by 31 - this checksum tells us our buffer\n> +\t * is in the standard format, giving a false positive only if\n> +\t * the 1st word of the Git-pack format object happens to be\n> +\t * divisible by 31, ie:\n> +\t *      ((byte0 * 256) + byte1) % 31 = 0\n> +\t *   =>        0ttt10000www1000 % 31 = 0\n> +\t *\n> +\t * As it happens, this case can only arise for www=3 & ttt=1\n> +\t * - ie, a Commit object, which would have to be 8 bytes in\n> +\t * size. As no Commit can be that small, we find that the\n> +\t * combination of these two criteria (bitmask & checksum)\n> +\t * can always correctly determine the buffer format.\n>  \t */\n>  \tword = (map[0] << 8) + map[1];\n> -\tif (map[0] == 0x78 && !(word % 31))\n> +\tif ((map[0] & 0x88) == 0x08 && !(word % 31))\n\nAre you sure about this 0x88? Isn't it 0x8F or something?\n\n>  \t\treturn 0;\n>  \telse\n>  \t\treturn 1;\n"},{"id":"172890","messageId":"CAFY1edZLAjVRs0LUx6CvD9i5aZu6kZ1ecJdUsvZgmtGkajOqow@mail.gmail.com","threadId":"28015","inReplyTo":"CAFY1edZyO7oYDi+tV2mxbhBHY_cf2F0bD7+KF9rxmKYygSFAjA@mail.gmail.com","subject":"Re: [PATCH] Tolerate zlib deflation with window size < 32Kb","fromName":"Roberto Tyley","fromEmail":"roberto.tyley@gmail.com","sentAt":"2011-08-04T07:40:56Z","receivedAt":"2011-08-04T07:40:56Z","isPatch":true,"sender":{"key":"roberto.tyley@gmail.com","avatar":"https://avatars.githubusercontent.com/u/52038?v=4"},"body":"On 4 August 2011 00:56, Junio C Hamano <gitster@pobox.com> wrote:\n> roberto.tyley@gmail.com writes:\n> > -     if (map[0] == 0x78 && !(word % 31))\n> > +     if ((map[0] & 0x88) == 0x08 && !(word % 31))\n>\n> Are you sure about this 0x88? Isn't it 0x8F or something?\n\nAh- yes, you're right - the bitmask should be 0x8F, because the\nlower nibble of a deflated zlib stream is 8 (8=deflate) and we want\nto match all 4 bits.\n\nThankfully the rest of the logic still applies - I'll submit an\nupdated patch in a minute, once I've conquered my embarrassment :-)\n"},{"id":"172891","messageId":"CAGdFq_jZNWxZmxuG_04O4CzdX_ipg-RDruiqdsKDXBxAaApoRw@mail.gmail.com","threadId":"28015","inReplyTo":"CAFY1edZLAjVRs0LUx6CvD9i5aZu6kZ1ecJdUsvZgmtGkajOqow@mail.gmail.com","subject":"Re: [PATCH] Tolerate zlib deflation with window size < 32Kb","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2011-08-04T07:45:20Z","receivedAt":"2011-08-04T07:45:20Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Thu, Aug 4, 2011 at 09:40, Roberto Tyley <roberto.tyley@gmail.com> wrote:\n> Thankfully the rest of the logic still applies - I'll submit an\n> updated patch in a minute, once I've conquered my embarrassment :-)\n\nPerhaps you can include a test to increase confidence that it works now? :)\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"172934","messageId":"7vhb5x5cgo.fsf@alter.siamese.dyndns.org","threadId":"28015","inReplyTo":"CAFY1edZyO7oYDi+tV2mxbhBHY_cf2F0bD7+KF9rxmKYygSFAjA@mail.gmail.com","subject":"Re: [PATCH] Tolerate zlib deflation with window size < 32Kb","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-04T17:11:03Z","receivedAt":"2011-08-04T17:11:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Roberto Tyley <roberto.tyley@gmail.com> writes:\n\n> On 4 August 2011 00:56, Junio C Hamano <gitster@pobox.com> wrote:\n>\n>> roberto.tyley@gmail.com writes:\n>> > -     if (map[0] == 0x78 && !(word % 31))\n>> > +     if ((map[0] & 0x88) == 0x08 && !(word % 31))\n>>\n>> Are you sure about this 0x88? Isn't it 0x8F or something?\n>\n>\n> Ah- yes, you're right - the bitmask should be 0x8F, because the\n> lower nibble of a deflated zlib stream is 8 (8=deflate) and we want\n> to match all 4 bits.\n>\n> Thankfully the rest of the logic still applies - I'll submit an\n> updated patch in a minute, once I've conquered my embarrassment :-)\n\nHeh, don't get embarrassed. It was your well-written in-code comment that\nhelped me to follow the new logic well enough to spot it.\n"},{"id":"173100","messageId":"1312742773-26373-1-git-send-email-roberto.tyley@gmail.com","threadId":"28015","inReplyTo":"7vhb5x5cgo.fsf@alter.siamese.dyndns.org","subject":"[PATCH v2] Tolerate zlib deflation with window size < 32Kb","fromName":"","fromEmail":"roberto.tyley@gmail.com","sentAt":"2011-08-07T18:46:13Z","receivedAt":"2011-08-07T18:46:13Z","isPatch":true,"sender":{"key":"roberto.tyley@gmail.com","avatar":"https://avatars.githubusercontent.com/u/52038?v=4"},"body":"From: Roberto Tyley <roberto.tyley@guardian.co.uk>\n\nGit currently reports loose objects as 'corrupt' if they've been\ndeflated using a window size less than 32Kb, because the\nexperimental_loose_object() function doesn't recognise the header\nbyte as a zlib header. This patch makes the function tolerant of\nall valid window sizes (15-bit to 8-bit) - but doesn't sacrifice\nit's accuracy in distingushing the standard loose-object format\nfrom the experimental (now abandoned) format.\n\nOn memory constrained systems zlib may use a much smaller window\nsize - working on Agit, I found that Android uses a 4KB window;\ngiving a header byte of 0x48, not 0x78. Consequently all loose\nobjects generated appear 'corrupt', which is why Agit is a read-only\nGit client at this time - I don't want my client to generate Git\nrepos that other clients treat as broken :(\n\nThis patch makes Git tolerant of different deflate settings - it\nmight appear that it changes experimental_loose_object() to the point\nwhere it could incorrectly identify the experimental format as the\nstandard one, but the two criteria (bitmask & checksum) can only\ngive a false result for an experimental object where both of the\nfollowing are true:\n\n1) object size is exactly 8 bytes when uncompressed (bitmask)\n2) [single-byte in-pack git type&size header] * 256\n   + [1st byte of the following zlib header] % 31 = 0 (checksum)\n\nAs it happens, for all possible combinations of valid object type\n(1-4) and window bits (0-7), the only time when the checksum will be\ndivisible by 31 is for 0x1838 - ie object type *1*, a Commit - which,\ndue the fields all Commit objects must contain, could never be as\nsmall as 8 bytes in size.\n\nGiven this, the combination of the two criteria (bitmask & checksum)\nalways correctly determines the buffer format, and is more tolerant\nthan the previous version.\n\nThe alternative to this patch is simply removing support for the\nexperimental format, which I am also totally cool with.\n\nReferences:\n\nAndroid uses a 4KB window for deflation:\nhttp://android.git.kernel.org/?p=platform/libcore.git;a=blob;f=luni/src/main/native/java_util_zip_Deflater.cpp;h=c0b2feff196e63a7b85d97cf9ae5bb2583409c28;hb=refs/heads/gingerbread#l53\n\nCode snippet searching for false positives with the zlib checksum:\nhttps://gist.github.com/1118177\n\nSigned-off-by: Roberto Tyley <roberto.tyley@guardian.co.uk>\n---\n\nThis updated patch contains the corrected 0x8F bitmask, and also\nprovides tests to ensure that the experimental & standard format\nheaders are still correctly identified and parsed.\n\nAs Git doesn't generate the old experimental format anymore, the\ntests include a set of loose objects in that format created using\nGit v1.4.3, as well as two objects generated on the Android platform\nusing a reduced-size window buffer for deflation.\n\n\n sha1_file.c                                        |   32 ++++++++--\n t/t1013-loose-object-format.sh                     |   66 ++++++++++++++++++++\n .../14/9cedb5c46929d18e0f118e9fa31927487af3b6      |  Bin 0 -> 117 bytes\n .../16/56f9233d999f61ef23ef390b9c71d75399f435      |  Bin 0 -> 17 bytes\n .../1e/72a6b2c4a577ab0338860fa9fe87f761fc9bbd      |  Bin 0 -> 18 bytes\n .../25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99      |  Bin 0 -> 19 bytes\n .../2e/65efe2a145dda7ee51d1741299f848e5bf752e      |  Bin 0 -> 10 bytes\n .../6b/aee0540ea990d9761a3eb9ab183003a71c3696      |  Bin 0 -> 181 bytes\n .../70/e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd      |  Bin 0 -> 26 bytes\n .../76/e7fa9941f4d5f97f64fea65a2cba436bc79cbb      |  Bin 0 -> 155 bytes\n .../78/75c6237d3fcdd0ac2f0decc7d3fa6a50b66c09      |  Bin 0 -> 139 bytes\n .../7a/37b887a73791d12d26c0d3e39568a8fb0fa6e8      |  Bin 0 -> 54 bytes\n .../85/df50785d62d3b05ab03d9cbf7e4a0b49449730      |  Bin 0 -> 13 bytes\n .../8d/4e360d6c70fbd72411991c02a09c442cf7a9fa      |  Bin 0 -> 156 bytes\n .../95/b1625de3ba8b2214d1e0d0591138aea733f64f      |  Bin 0 -> 252 bytes\n .../9a/e9e86b7bd6cb1472d9373702d8249973da0832      |  Bin 0 -> 11 bytes\n .../bd/15045f6ce8ff75747562173640456a394412c8      |  Bin 0 -> 34 bytes\n .../e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391      |  Bin 0 -> 9 bytes\n .../f8/16d5255855ac160652ee5253b06cd8ee14165a      |  Bin 0 -> 116 bytes\n 19 files changed, 92 insertions(+), 6 deletions(-)\n create mode 100755 t/t1013-loose-object-format.sh\n create mode 100644 t/t1013/objects/14/9cedb5c46929d18e0f118e9fa31927487af3b6\n create mode 100644 t/t1013/objects/16/56f9233d999f61ef23ef390b9c71d75399f435\n create mode 100644 t/t1013/objects/1e/72a6b2c4a577ab0338860fa9fe87f761fc9bbd\n create mode 100644 t/t1013/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99\n create mode 100644 t/t1013/objects/2e/65efe2a145dda7ee51d1741299f848e5bf752e\n create mode 100644 t/t1013/objects/6b/aee0540ea990d9761a3eb9ab183003a71c3696\n create mode 100644 t/t1013/objects/70/e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd\n create mode 100644 t/t1013/objects/76/e7fa9941f4d5f97f64fea65a2cba436bc79cbb\n create mode 100644 t/t1013/objects/78/75c6237d3fcdd0ac2f0decc7d3fa6a50b66c09\n create mode 100644 t/t1013/objects/7a/37b887a73791d12d26c0d3e39568a8fb0fa6e8\n create mode 100644 t/t1013/objects/85/df50785d62d3b05ab03d9cbf7e4a0b49449730\n create mode 100644 t/t1013/objects/8d/4e360d6c70fbd72411991c02a09c442cf7a9fa\n create mode 100644 t/t1013/objects/95/b1625de3ba8b2214d1e0d0591138aea733f64f\n create mode 100644 t/t1013/objects/9a/e9e86b7bd6cb1472d9373702d8249973da0832\n create mode 100644 t/t1013/objects/bd/15045f6ce8ff75747562173640456a394412c8\n create mode 100644 t/t1013/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391\n create mode 100644 t/t1013/objects/f8/16d5255855ac160652ee5253b06cd8ee14165a\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex d5616dc..44444ae 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -1217,14 +1217,34 @@ static int experimental_loose_object(unsigned char *map)\n \tunsigned int word;\n \n \t/*\n-\t * Is it a zlib-compressed buffer? If so, the first byte\n-\t * must be 0x78 (15-bit window size, deflated), and the\n-\t * first 16-bit word is evenly divisible by 31. If so,\n-\t * we are looking at the official format, not the experimental\n-\t * one.\n+\t * We must determine if the buffer contains the standard\n+\t * zlib-deflated stream or the experimental format based\n+\t * on the in-pack object format. Compare the header byte\n+\t * for each format:\n+\t *\n+\t * RFC1950 zlib w/ deflate : 0www1000 : 0 <= www <= 7\n+\t * Experimental pack-based : Stttssss : ttt = 1,2,3,4\n+\t *\n+\t * If bit 7 is clear and bits 0-3 equal 8, the buffer MUST be\n+\t * in standard loose-object format, UNLESS it is a Git-pack\n+\t * format object *exactly* 8 bytes in size when inflated.\n+\t *\n+\t * However, RFC1950 also specifies that the 1st 16-bit word\n+\t * must be divisible by 31 - this checksum tells us our buffer\n+\t * is in the standard format, giving a false positive only if\n+\t * the 1st word of the Git-pack format object happens to be\n+\t * divisible by 31, ie:\n+\t *      ((byte0 * 256) + byte1) % 31 = 0\n+\t *   =>        0ttt10000www1000 % 31 = 0\n+\t *\n+\t * As it happens, this case can only arise for www=3 & ttt=1\n+\t * - ie, a Commit object, which would have to be 8 bytes in\n+\t * size. As no Commit can be that small, we find that the\n+\t * combination of these two criteria (bitmask & checksum)\n+\t * can always correctly determine the buffer format.\n \t */\n \tword = (map[0] << 8) + map[1];\n-\tif (map[0] == 0x78 && !(word % 31))\n+\tif ((map[0] & 0x8F) == 0x08 && !(word % 31))\n \t\treturn 0;\n \telse\n \t\treturn 1;\ndiff --git a/t/t1013-loose-object-format.sh b/t/t1013-loose-object-format.sh\nnew file mode 100755\nindex 0000000..b5ac46d\n--- /dev/null\n+++ b/t/t1013-loose-object-format.sh\n@@ -0,0 +1,66 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2011 Roberto Tyley\n+#\n+\n+test_description='Correctly identify and parse loose object headers\n+\n+There are two file formats for loose objects - the original standard\n+format, and the experimental format introduced with Git v1.4.3, later\n+deprecated with v1.5.3. Although Git no longer writes the\n+experimental format, objects in both formats must be read, with the\n+format for a given file being determined by the header.\n+\n+Detecting file format based on header is not entirely trivial, not\n+least because the first byte of a zlib-deflated stream will vary\n+depending on how much memory was allocated for the deflation window\n+buffer when the object was written out (for example 4KB on Android,\n+rather that 32KB on a normal PC).\n+\n+The loose objects used as test vectors have been generated with the\n+following Git versions:\n+\n+standard format: Git v1.7.4.1\n+experimental format: Git v1.4.3 (legacyheaders=false)\n+standard format, deflated with 4KB window size: Agit/JGit on Android\n+'\n+\n+. ./test-lib.sh\n+\n+assert_blob_equals() {\n+\techo -n $2 > expected &&\n+\tgit cat-file -p $1 > actual &&\n+\ttest_cmp expected actual\n+}\n+\n+test_expect_success setup '\n+\tcp -R ../t1013/objects .git/\n+\tgit --version\n+'\n+\n+test_expect_success 'read standard-format loose objects' '\n+\tgit cat-file tag 8d4e360d6c70fbd72411991c02a09c442cf7a9fa &&\n+\tgit cat-file commit 6baee0540ea990d9761a3eb9ab183003a71c3696 &&\n+\tgit ls-tree 7a37b887a73791d12d26c0d3e39568a8fb0fa6e8 &&\n+\tassert_blob_equals \"257cc5642cb1a054f08cc83f2d943e56fd3ebe99\" \"foo\\n\"\n+'\n+\n+test_expect_success 'read experimental-format loose objects' '\n+\tgit cat-file tag 76e7fa9941f4d5f97f64fea65a2cba436bc79cbb &&\n+\tgit cat-file commit 7875c6237d3fcdd0ac2f0decc7d3fa6a50b66c09 &&\n+\tgit ls-tree 95b1625de3ba8b2214d1e0d0591138aea733f64f &&\n+\tassert_blob_equals \"2e65efe2a145dda7ee51d1741299f848e5bf752e\" \"a\" &&\n+\tassert_blob_equals \"9ae9e86b7bd6cb1472d9373702d8249973da0832\" \"ab\" &&\n+\tassert_blob_equals \"85df50785d62d3b05ab03d9cbf7e4a0b49449730\" \"abcd\" &&\n+\tassert_blob_equals \"1656f9233d999f61ef23ef390b9c71d75399f435\" \"abcdefgh\" &&\n+\tassert_blob_equals \"1e72a6b2c4a577ab0338860fa9fe87f761fc9bbd\" \"abcdefghi\" &&\n+\tassert_blob_equals \"70e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd\" \"abcdefghijklmnop\" &&\n+\tassert_blob_equals \"bd15045f6ce8ff75747562173640456a394412c8\" \"abcdefghijklmnopqrstuvwx\"\n+'\n+\n+test_expect_success 'read standard-format objects deflated with smaller window buffer' '\n+\tgit cat-file tag f816d5255855ac160652ee5253b06cd8ee14165a &&\n+\tgit cat-file tag 149cedb5c46929d18e0f118e9fa31927487af3b6\n+'\n+\n+test_done\ndiff --git a/t/t1013/objects/14/9cedb5c46929d18e0f118e9fa31927487af3b6 b/t/t1013/objects/14/9cedb5c46929d18e0f118e9fa31927487af3b6\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..472fd1458e03e47136416bce60d6e7c893a468ab\nGIT binary patch\nliteral 117\nzcmV-*0E+)ei51K-4#F@DKvCwL!aJ&DH^jjbLR`g3tWwmHs(9h{l<n&c-*p0_eCp+8\nz)q#teVY;BH2sX(~8m)*Hx<<sPnQCO=;NQ)l_H~^-`0>zp+xy&xqlfV?lkEVv$I`1V\nX&;Ic{P^6Jl5+pbyA%^e+FOeitJb^w>\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/16/56f9233d999f61ef23ef390b9c71d75399f435 b/t/t1013/objects/16/56f9233d999f61ef23ef390b9c71d75399f435\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..c379d74ae2b40faae9c31cb7478bc7f42a6fb13c\nGIT binary patch\nliteral 17\nYcmcDhnB(o^<>%?^eV&1VkAYbg05K>8VgLXD\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/1e/72a6b2c4a577ab0338860fa9fe87f761fc9bbd b/t/t1013/objects/1e/72a6b2c4a577ab0338860fa9fe87f761fc9bbd\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..93706305bcff060547181ee4b7d3a8583b691181\nGIT binary patch\nliteral 18\nZcmcDlnB(o^<>%?^ef|UsgJ2(X9{@cS1}Ojl\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99 b/t/t1013/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..bdcf704c9e663f3a11b3146b1b455bc2581b4761\nGIT binary patch\nliteral 19\nacmb<m^geacKgb}_<MjFGObnu-%uWDJxd#LQ\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/2e/65efe2a145dda7ee51d1741299f848e5bf752e b/t/t1013/objects/2e/65efe2a145dda7ee51d1741299f848e5bf752e\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..ad62c43e418c11254cede4dc94982ac6a30dbe9c\nGIT binary patch\nliteral 10\nRcmXr4nB&dDz>vg{1ON`X0$Bh6\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/6b/aee0540ea990d9761a3eb9ab183003a71c3696 b/t/t1013/objects/6b/aee0540ea990d9761a3eb9ab183003a71c3696\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..3d2f0337dbb64c092b4a7e9bd324a66986cfe01a\nGIT binary patch\nliteral 181\nzcmV;m080OO0i}>jY6CG41+&&EdLIz_c+?s&#*jt!#uw=6?r{d&BO_}9zP*3BL6-Fv\nzMe(?t&r^etx{p>>0V(2;GZIGZz4#y@v6HB=?^32b4sN8R*<7gV+yFCnoI*s2Ba1lV\nzFgj7@=Rk=%H>8K4H?*{$QejsHt*yZRcG4TH>l<x*;`Xpmm5FA{#V*GU_~=6l7@~(y\nj=bbbBs%`pTkNNr&2`txXKEU_mgI{mauB<nAL=six5bRpF\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/70/e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd b/t/t1013/objects/70/e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..b3f71a6ee5802b36b4576c5ebf111f30ef2017a4\nGIT binary patch\nliteral 26\nicmdnMSTV=j$IH*t*Zcg5GpEj-JbPN7fx*mytrGyBA`4~!\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/76/e7fa9941f4d5f97f64fea65a2cba436bc79cbb b/t/t1013/objects/76/e7fa9941f4d5f97f64fea65a2cba436bc79cbb\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..af4e9a7b0c035fc7c26355b85f250f3ff7d3afa1\nGIT binary patch\nliteral 155\nzcmV;M0A&Bd3wWF*%s~!<Fc3h|eNQoaV^dlvm>A>Ez2O4GbZDxSl3I-1-k{6>7C#LS\nzrUGr(He|JFof*kFg``L2m}m#I*r>r;QYTTig@ICxp@@PW__J^hk>`TbaZEYl&pl_j\nzr-5@x&~FoOaL)gfWzVZ$F}r}Xq$Jnp1u9c%tLsj8a8Q*}LiGE^!TJibhg&G{u4FBZ\nJ_yWO9IpM14O;`W`\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/78/75c6237d3fcdd0ac2f0decc7d3fa6a50b66c09 b/t/t1013/objects/78/75c6237d3fcdd0ac2f0decc7d3fa6a50b66c09\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..3dd28be5c61840c23486bc654213c493c5387d75\nGIT binary patch\nliteral 139\nzcmV;60CfM64S1ZT%u5QwFc1LHeNHiZA!PEi1rc|y+=v&LG*cUF4TP!E+lzPvmv8f=\nzF+(2`MjJA_L|w8LeMUCfgdWj##I$#AjDA$K%2XR%YvLvqZrjWo9NLdszC7JmYPrx;\nt4^^*^BcMYYt&hRN&Y&@BsLN7B_}@oeC^Ni^OmHp&FVtQ;^#LMbK`4x{Jre)`\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/7a/37b887a73791d12d26c0d3e39568a8fb0fa6e8 b/t/t1013/objects/7a/37b887a73791d12d26c0d3e39568a8fb0fa6e8\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..2b97b264c33f78fe6c8230b5bbeacd6409d9f963\nGIT binary patch\nliteral 54\nzcmV-60LlM&0V^p=O;s>9XD~D{Ff%bx2yqP#(RK6mab-}gIhvxgaY4w3o)h-EQ|!Y2\nM+U=VO05jJR92g)Lz5oCK\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/85/df50785d62d3b05ab03d9cbf7e4a0b49449730 b/t/t1013/objects/85/df50785d62d3b05ab03d9cbf7e4a0b49449730\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..6dff746876aab1acb9b42c557cdda69164d68398\nGIT binary patch\nliteral 13\nUcmXr1nB(o^<;Tdte1owY030|2-~a#s\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/8d/4e360d6c70fbd72411991c02a09c442cf7a9fa b/t/t1013/objects/8d/4e360d6c70fbd72411991c02a09c442cf7a9fa\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..cb41e92d076c191245389bedfc0184ff78511c03\nGIT binary patch\nliteral 156\nzcmV;N0Av4n0VRw<3c@fD06pgwdly5tsfhs*Z{DRJ*tBb?+D6i?(BE72I0G|63DCPu\nzj(2VaTqI_*uMJZOrVHL7S&o4s9;`8zJhs*ar(}6Cw0RhMQL;WJp|PXV?QXdY^mB;|\nzTyx|i8JgwE3mnTIwS4iM<~8VP)NR)D;{<52a+SALfUQAelxip??qHt!F~Ox5c%$~Z\nK)~G%MG&zg-a!8y2\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/95/b1625de3ba8b2214d1e0d0591138aea733f64f b/t/t1013/objects/95/b1625de3ba8b2214d1e0d0591138aea733f64f\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..7ac46b4f703aa00cd96c42971a237e3da5bbb5ca\nGIT binary patch\nliteral 252\nzcmV<Y00aN25_p_5G%zqTF;Pg(OwTCME2$`95DWXMY&&y);(O)ymfUj+uLsZkVrmFc\nzl$Kvw1Xj~}KcFHu>GFoC4YqUk*LiV!x=c5Ks>#dDO9iWuD_XYc$kOuF%oc6@EC02B\nzPy91`FH}uFREb{d`$r31?=F8Ac(Fui<`0jj`%CqpN{TZpN>Wqvz{(1qt+4Gqt@fw;\nz!1)3_-Fw^Co|5<rRaR1-npaY(3wPLFQI`0e7ynC3N|VIR99*+3U4%}+mF9z$%zF7E\nzyZYK`k)oUC=1ezKW)|P#FoG(nN-ct@c{caa>`fQ1IeT|&t}Bnaap*};@I(N)b$dQ6\nC6@X{}\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/9a/e9e86b7bd6cb1472d9373702d8249973da0832 b/t/t1013/objects/9a/e9e86b7bd6cb1472d9373702d8249973da0832\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..9d8316d4e598e32ef17b3918cf00276c8c1bffba\nGIT binary patch\nliteral 11\nScmXr2nB(ok#K5S=a0CDn4+6^o\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/bd/15045f6ce8ff75747562173640456a394412c8 b/t/t1013/objects/bd/15045f6ce8ff75747562173640456a394412c8\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..eebf23956e3b8ac736fa04e682b4214ac75c716a\nGIT binary patch\nliteral 34\nqcmdnNSTV=j$IH*t*Zcg5GpEj-JbPMSLq|(bQ&)RE14GpTE?oczGYz%?\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/t/t1013/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..134cf1937963c733d7affa6919f9835db864188a\nGIT binary patch\nliteral 9\nOcmXr0n8VBf1dIR)&;dyR\n\nliteral 0\nHcmV?d00001\n\ndiff --git a/t/t1013/objects/f8/16d5255855ac160652ee5253b06cd8ee14165a b/t/t1013/objects/f8/16d5255855ac160652ee5253b06cd8ee14165a\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..26b75aec56f8f178a9f001be3b630a4e48ceb6b9\nGIT binary patch\nliteral 116\nzcmV-)0E_=fi51Mj4uUWYfML&jirx)LyJa0F#`r3w9f$!(uovH6xc&JKzsm$f<<f?C\nzRfp1-tQ=FZG^!bj#u2Tmo**n42WG`v@ZVNJ+q%vk{CLR6_BLC0bVsL5bqBaVm!`73\nW+SeaIi6Uq0dxk3#VhDeEz9mhO%Qr3n\n\nliteral 0\nHcmV?d00001\n\n-- \n1.7.4.1\n"},{"id":"173150","messageId":"7v62m7yagb.fsf@alter.siamese.dyndns.org","threadId":"28015","inReplyTo":"1312742773-26373-1-git-send-email-roberto.tyley@gmail.com","subject":"Re: [PATCH v2] Tolerate zlib deflation with window size < 32Kb","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-08T19:23:00Z","receivedAt":"2011-08-08T19:23:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"roberto.tyley@gmail.com writes:\n\n> +. ./test-lib.sh\n> +\n> +assert_blob_equals() {\n> +\techo -n $2 > expected &&\n> +\tgit cat-file -p $1 > actual &&\n\nNeeds proper quoting with dq.\n\n> +\ttest_cmp expected actual\n> +}\n> +\n> +test_expect_success setup '\n> +\tcp -R ../t1013/objects .git/\n> +\tgit --version\n> +'\n> +\n> +test_expect_success 'read standard-format loose objects' '\n> +\tgit cat-file tag 8d4e360d6c70fbd72411991c02a09c442cf7a9fa &&\n> +\tgit cat-file commit 6baee0540ea990d9761a3eb9ab183003a71c3696 &&\n> +\tgit ls-tree 7a37b887a73791d12d26c0d3e39568a8fb0fa6e8 &&\n> +\tassert_blob_equals \"257cc5642cb1a054f08cc83f2d943e56fd3ebe99\" \"foo\\n\"\n\nIsn't it unportable to expect \"\\n\" to be kept or expanded by \"echo\"?\n\nWill squash the following in (and I have another patch on top to\nconsolidate the definition of $LF in this and other test scripts).\n\nThanks.\n\n-- >8 --\nSubject: [PATCH] fixup! Tolerate zlib deflation with window\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/t1013-loose-object-format.sh |    8 +++++---\n 1 files changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t1013-loose-object-format.sh b/t/t1013-loose-object-format.sh\nindex b5ac46d..36b4027 100755\n--- a/t/t1013-loose-object-format.sh\n+++ b/t/t1013-loose-object-format.sh\n@@ -26,10 +26,12 @@ standard format, deflated with 4KB window size: Agit/JGit on Android\n '\n \n . ./test-lib.sh\n+LF='\n+'\n \n assert_blob_equals() {\n-\techo -n $2 > expected &&\n-\tgit cat-file -p $1 > actual &&\n+\tprintf \"%s\" \"$2\" >expected &&\n+\tgit cat-file -p \"$1\" >actual &&\n \ttest_cmp expected actual\n }\n \n@@ -42,7 +44,7 @@ test_expect_success 'read standard-format loose objects' '\n \tgit cat-file tag 8d4e360d6c70fbd72411991c02a09c442cf7a9fa &&\n \tgit cat-file commit 6baee0540ea990d9761a3eb9ab183003a71c3696 &&\n \tgit ls-tree 7a37b887a73791d12d26c0d3e39568a8fb0fa6e8 &&\n-\tassert_blob_equals \"257cc5642cb1a054f08cc83f2d943e56fd3ebe99\" \"foo\\n\"\n+\tassert_blob_equals \"257cc5642cb1a054f08cc83f2d943e56fd3ebe99\" \"foo$LF\"\n '\n \n test_expect_success 'read experimental-format loose objects' '\n-- \n1.7.6.409.ge7a85\n"},{"id":"173154","messageId":"7vk4anwttc.fsf@alter.siamese.dyndns.org","threadId":"28015","inReplyTo":"1312742773-26373-1-git-send-email-roberto.tyley@gmail.com","subject":"Re: [PATCH v2] Tolerate zlib deflation with window size < 32Kb","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-08T20:07:43Z","receivedAt":"2011-08-08T20:07:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"roberto.tyley@gmail.com writes:\n\n> +test_expect_success setup '\n> +\tcp -R ../t1013/objects .git/\n> +\tgit --version\n> +'\n\nThis \"my parent directory\" reference ../t1013 does not work when you use a\nseparate test directory (e.g. to use ramdisks) with --root=/some/where/\n\nI've squashed\n\n\tcp -R \"$TEST_DIRECTORY/t1013/objects\" .git/\n\nas a fix while queuing.\n\nThanks.\n"}]}