AMG: This page exists as a temporary repository for a file that the SourceForge bug tracker won't let me attach. Will some SF administrator please file a way to get the file into the bug tracker, then delete this page? Thanks. The bug URL is: [L1 ]
Here's the patch:
diff -ur tcl8.6b3~/generic/tclBinary.c tcl8.6b3/generic/tclBinary.c
--- tcl8.6b3~/generic/tclBinary.c 2012-09-17 07:25:44.000000000 -0500
+++ tcl8.6b3/generic/tclBinary.c 2012-10-16 19:04:02.000000000 -0500
@@ -2658,7 +2658,7 @@
Tcl_Obj *const objv[])
{
Tcl_Obj *resultObj = NULL;
- unsigned char *data, *datastart, *dataend, c;
+ unsigned char *data, *datastart, *dataend, c = '\0';
unsigned char *begin = NULL;
unsigned char *cursor = NULL;
int strict = 0;
@@ -2691,43 +2691,82 @@
while (data < dataend) {
unsigned long value = 0;
- for (i=0 ; i<4 ; i++) {
+ /*
+ * Decode the current block. Each base64 block consists of four input
+ * characters A-Z, a-z, 0-9, +, or /. Each character supplies six bits
+ * of output data, so each block's output is 24 bits (three bytes) in
+ * length. The final block can be shorter by one or two bytes, denoted
+ * by the input ending with one or two ='s, respectively.
+ */
+ for (i = 0; i < 4; i++) {
+ /*
+ * Get the next input character. At end of input, pad with at most
+ * two ='s. If more than two ='s would be needed, instead discard
+ * the block read thus far.
+ */
if (data < dataend) {
c = *data++;
+ } else if (i > 1) {
+ c = '=';
+ } else {
+ cut += 3;
+ break;
+ }
- if (c >= 'A' && c <= 'Z') {
- value = (value << 6) | ((c - 'A') & 0x3f);
- } else if (c >= 'a' && c <= 'z') {
- value = (value << 6) | ((c - 'a' + 26) & 0x3f);
- } else if (c >= '0' && c <= '9') {
- value = (value << 6) | ((c - '0' + 52) & 0x3f);
- } else if (c == '+') {
- value = (value << 6) | 0x3e;
- } else if (c == '/') {
- value = (value << 6) | 0x3f;
- } else if (c == '=') {
+ /*
+ * Load the character into the block value. Handle ='s specially
+ * because they're only valid as the last character or two of the
+ * final block of input. Unless strict mode is enabled, skip any
+ * input whitespace characters.
+ */
+ if (cut) {
+ if (c == '=' && i > 1) {
value <<= 6;
- if (cut < 2) {
- cut++;
- }
- } else {
- if (strict || !isspace(c)) {
- goto bad64;
- }
+ cut++;
+ } else if (!strict && isspace(c)) {
i--;
- continue;
+ } else {
+ goto bad64;
}
- } else {
+ } else if (c >= 'A' && c <= 'Z') {
+ value = (value << 6) | ((c - 'A') & 0x3f);
+ } else if (c >= 'a' && c <= 'z') {
+ value = (value << 6) | ((c - 'a' + 26) & 0x3f);
+ } else if (c >= '0' && c <= '9') {
+ value = (value << 6) | ((c - '0' + 52) & 0x3f);
+ } else if (c == '+') {
+ value = (value << 6) | 0x3e;
+ } else if (c == '/') {
+ value = (value << 6) | 0x3f;
+ } else if (c == '=') {
value <<= 6;
cut++;
+ } else if (strict || !isspace(c)) {
+ goto bad64;
+ } else {
+ i--;
}
}
*cursor++ = UCHAR((value >> 16) & 0xff);
*cursor++ = UCHAR((value >> 8) & 0xff);
*cursor++ = UCHAR(value & 0xff);
- }
- if (cut > size) {
- cut = size;
+
+ /*
+ * Since = is only valid within the final block, if it was encountered
+ * but there are still more input characters, confirm that strict mode
+ * is off and all subsequent characters are whitespace.
+ */
+ if (cut && data < dataend) {
+ if (strict) {
+ goto bad64;
+ } else {
+ for (; data < dataend; data++) {
+ if (!isspace(*data)) {
+ goto bad64;
+ }
+ }
+ }
+ }
}
Tcl_SetByteArrayLength(resultObj, cursor - begin - cut);
Tcl_SetObjResult(interp, resultObj);
diff -ur tcl8.6b3~/tests/binary.test tcl8.6b3/tests/binary.test
--- tcl8.6b3~/tests/binary.test 2012-06-26 08:59:02.000000000 -0500
+++ tcl8.6b3/tests/binary.test 2012-10-16 18:43:50.000000000 -0500
@@ -2642,6 +2642,27 @@
test binary-73.24 {binary decode base64} -body {
string length [binary decode base64 " "]
} -result 0
+test binary-73.25 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 WA==\n]]] $r
+} -result {1 X}
+test binary-73.26 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 WFk=\n]]] $r
+} -result {2 XY}
+test binary-73.27 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 WFla\n]]] $r
+} -result {3 XYZ}
+test binary-73.28 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 -strict WA==\n]]] $r
+} -returnCodes error -match glob -result {invalid base64 character *}
+test binary-73.29 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 -strict WFk=\n]]] $r
+} -returnCodes error -match glob -result {invalid base64 character *}
+test binary-73.30 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 -strict WFla\n]]] $r
+} -returnCodes error -match glob -result {invalid base64 character *}
+test binary-73.31 {binary decode base64} -body {
+ list [string length [set r [binary decode base64 WA==WFla]]] $r
+} -returnCodes error -match glob -result {invalid base64 character *}
test binary-74.1 {binary encode uuencode} -body {
binary encode uuencodeHopefully the Wiki won't destroy all the tabs... *sigh*
Yup, it ate my tabs. Oh well, you can still read it.
Here's the intended file, formatted in base64 of course. :^)
begin-base64 644 tcl8.6b3-base64decode.patch ZGlmZiAtdXIgdGNsOC42YjN+L2dlbmVyaWMvdGNsQmluYXJ5LmMgdGNsOC42 YjMvZ2VuZXJpYy90Y2xCaW5hcnkuYwotLS0gdGNsOC42YjN+L2dlbmVyaWMv dGNsQmluYXJ5LmMJMjAxMi0wOS0xNyAwNzoyNTo0NC4wMDAwMDAwMDAgLTA1 MDAKKysrIHRjbDguNmIzL2dlbmVyaWMvdGNsQmluYXJ5LmMJMjAxMi0xMC0x NiAxOTowNDowMi4wMDAwMDAwMDAgLTA1MDAKQEAgLTI2NTgsNyArMjY1OCw3 IEBACiAgICAgVGNsX09iaiAqY29uc3Qgb2JqdltdKQogewogICAgIFRjbF9P YmogKnJlc3VsdE9iaiA9IE5VTEw7Ci0gICAgdW5zaWduZWQgY2hhciAqZGF0 YSwgKmRhdGFzdGFydCwgKmRhdGFlbmQsIGM7CisgICAgdW5zaWduZWQgY2hh ciAqZGF0YSwgKmRhdGFzdGFydCwgKmRhdGFlbmQsIGMgPSAnXDAnOwogICAg IHVuc2lnbmVkIGNoYXIgKmJlZ2luID0gTlVMTDsKICAgICB1bnNpZ25lZCBj aGFyICpjdXJzb3IgPSBOVUxMOwogICAgIGludCBzdHJpY3QgPSAwOwpAQCAt MjY5MSw0MyArMjY5MSw4MiBAQAogICAgIHdoaWxlIChkYXRhIDwgZGF0YWVu ZCkgewogCXVuc2lnbmVkIGxvbmcgdmFsdWUgPSAwOwogCi0JZm9yIChpPTAg OyBpPDQgOyBpKyspIHsKKwkvKgorCSAqIERlY29kZSB0aGUgY3VycmVudCBi bG9jay4gRWFjaCBiYXNlNjQgYmxvY2sgY29uc2lzdHMgb2YgZm91ciBpbnB1 dAorCSAqIGNoYXJhY3RlcnMgQS1aLCBhLXosIDAtOSwgKywgb3IgLy4gRWFj aCBjaGFyYWN0ZXIgc3VwcGxpZXMgc2l4IGJpdHMKKwkgKiBvZiBvdXRwdXQg ZGF0YSwgc28gZWFjaCBibG9jaydzIG91dHB1dCBpcyAyNCBiaXRzICh0aHJl ZSBieXRlcykgaW4KKwkgKiBsZW5ndGguIFRoZSBmaW5hbCBibG9jayBjYW4g YmUgc2hvcnRlciBieSBvbmUgb3IgdHdvIGJ5dGVzLCBkZW5vdGVkCisJICog YnkgdGhlIGlucHV0IGVuZGluZyB3aXRoIG9uZSBvciB0d28gPSdzLCByZXNw ZWN0aXZlbHkuCisJICovCisJZm9yIChpID0gMDsgaSA8IDQ7IGkrKykgewor CSAgICAvKgorCSAgICAgKiBHZXQgdGhlIG5leHQgaW5wdXQgY2hhcmFjdGVy LiBBdCBlbmQgb2YgaW5wdXQsIHBhZCB3aXRoIGF0IG1vc3QKKwkgICAgICog dHdvID0ncy4gSWYgbW9yZSB0aGFuIHR3byA9J3Mgd291bGQgYmUgbmVlZGVk LCBpbnN0ZWFkIGRpc2NhcmQKKwkgICAgICogdGhlIGJsb2NrIHJlYWQgdGh1 cyBmYXIuCisJICAgICAqLwogCSAgICBpZiAoZGF0YSA8IGRhdGFlbmQpIHsK IAkJYyA9ICpkYXRhKys7CisJICAgIH0gZWxzZSBpZiAoaSA+IDEpIHsKKwkJ YyA9ICc9JzsKKwkgICAgfSBlbHNlIHsKKwkJY3V0ICs9IDM7CisJCWJyZWFr OworCSAgICB9CiAKLQkJaWYgKGMgPj0gJ0EnICYmIGMgPD0gJ1onKSB7Ci0J CSAgICB2YWx1ZSA9ICh2YWx1ZSA8PCA2KSB8ICgoYyAtICdBJykgJiAweDNm KTsKLQkJfSBlbHNlIGlmIChjID49ICdhJyAmJiBjIDw9ICd6JykgewotCQkg ICAgdmFsdWUgPSAodmFsdWUgPDwgNikgfCAoKGMgLSAnYScgKyAyNikgJiAw eDNmKTsKLQkJfSBlbHNlIGlmIChjID49ICcwJyAmJiBjIDw9ICc5Jykgewot CQkgICAgdmFsdWUgPSAodmFsdWUgPDwgNikgfCAoKGMgLSAnMCcgKyA1Mikg JiAweDNmKTsKLQkJfSBlbHNlIGlmIChjID09ICcrJykgewotCQkgICAgdmFs dWUgPSAodmFsdWUgPDwgNikgfCAweDNlOwotCQl9IGVsc2UgaWYgKGMgPT0g Jy8nKSB7Ci0JCSAgICB2YWx1ZSA9ICh2YWx1ZSA8PCA2KSB8IDB4M2Y7Ci0J CX0gZWxzZSBpZiAoYyA9PSAnPScpIHsKKwkgICAgLyoKKwkgICAgICogTG9h ZCB0aGUgY2hhcmFjdGVyIGludG8gdGhlIGJsb2NrIHZhbHVlLiBIYW5kbGUg PSdzIHNwZWNpYWxseQorCSAgICAgKiBiZWNhdXNlIHRoZXkncmUgb25seSB2 YWxpZCBhcyB0aGUgbGFzdCBjaGFyYWN0ZXIgb3IgdHdvIG9mIHRoZQorCSAg ICAgKiBmaW5hbCBibG9jayBvZiBpbnB1dC4gVW5sZXNzIHN0cmljdCBtb2Rl IGlzIGVuYWJsZWQsIHNraXAgYW55CisJICAgICAqIGlucHV0IHdoaXRlc3Bh Y2UgY2hhcmFjdGVycy4KKwkgICAgICovCisJICAgIGlmIChjdXQpIHsKKwkJ aWYgKGMgPT0gJz0nICYmIGkgPiAxKSB7CiAJCSAgICB2YWx1ZSA8PD0gNjsK LQkJICAgIGlmIChjdXQgPCAyKSB7Ci0JCQljdXQrKzsKLQkJICAgIH0KLQkJ fSBlbHNlIHsKLQkJICAgIGlmIChzdHJpY3QgfHwgIWlzc3BhY2UoYykpIHsK LQkJCWdvdG8gYmFkNjQ7Ci0JCSAgICB9CisJCSAgICBjdXQrKzsKKwkJfSBl bHNlIGlmICghc3RyaWN0ICYmIGlzc3BhY2UoYykpIHsKIAkJICAgIGktLTsK LQkJICAgIGNvbnRpbnVlOworCQl9IGVsc2UgeworCQkgICAgZ290byBiYWQ2 NDsKIAkJfQotCSAgICB9IGVsc2UgeworCSAgICB9IGVsc2UgaWYgKGMgPj0g J0EnICYmIGMgPD0gJ1onKSB7CisJCXZhbHVlID0gKHZhbHVlIDw8IDYpIHwg KChjIC0gJ0EnKSAmIDB4M2YpOworCSAgICB9IGVsc2UgaWYgKGMgPj0gJ2En ICYmIGMgPD0gJ3onKSB7CisJCXZhbHVlID0gKHZhbHVlIDw8IDYpIHwgKChj IC0gJ2EnICsgMjYpICYgMHgzZik7CisJICAgIH0gZWxzZSBpZiAoYyA+PSAn MCcgJiYgYyA8PSAnOScpIHsKKwkJdmFsdWUgPSAodmFsdWUgPDwgNikgfCAo KGMgLSAnMCcgKyA1MikgJiAweDNmKTsKKwkgICAgfSBlbHNlIGlmIChjID09 ICcrJykgeworCQl2YWx1ZSA9ICh2YWx1ZSA8PCA2KSB8IDB4M2U7CisJICAg IH0gZWxzZSBpZiAoYyA9PSAnLycpIHsKKwkJdmFsdWUgPSAodmFsdWUgPDwg NikgfCAweDNmOworCSAgICB9IGVsc2UgaWYgKGMgPT0gJz0nKSB7CiAJCXZh bHVlIDw8PSA2OwogCQljdXQrKzsKKwkgICAgfSBlbHNlIGlmIChzdHJpY3Qg fHwgIWlzc3BhY2UoYykpIHsKKwkJZ290byBiYWQ2NDsKKwkgICAgfSBlbHNl IHsKKwkJaS0tOwogCSAgICB9CiAJfQogCSpjdXJzb3IrKyA9IFVDSEFSKCh2 YWx1ZSA+PiAxNikgJiAweGZmKTsKIAkqY3Vyc29yKysgPSBVQ0hBUigodmFs dWUgPj4gOCkgJiAweGZmKTsKIAkqY3Vyc29yKysgPSBVQ0hBUih2YWx1ZSAm IDB4ZmYpOwotICAgIH0KLSAgICBpZiAoY3V0ID4gc2l6ZSkgewotCWN1dCA9 IHNpemU7CisKKwkvKgorCSAqIFNpbmNlID0gaXMgb25seSB2YWxpZCB3aXRo aW4gdGhlIGZpbmFsIGJsb2NrLCBpZiBpdCB3YXMgZW5jb3VudGVyZWQKKwkg KiBidXQgdGhlcmUgYXJlIHN0aWxsIG1vcmUgaW5wdXQgY2hhcmFjdGVycywg Y29uZmlybSB0aGF0IHN0cmljdCBtb2RlCisJICogaXMgb2ZmIGFuZCBhbGwg c3Vic2VxdWVudCBjaGFyYWN0ZXJzIGFyZSB3aGl0ZXNwYWNlLgorCSAqLwor CWlmIChjdXQgJiYgZGF0YSA8IGRhdGFlbmQpIHsKKwkgICAgaWYgKHN0cmlj dCkgeworCQlnb3RvIGJhZDY0OworCSAgICB9IGVsc2UgeworCQlmb3IgKDsg ZGF0YSA8IGRhdGFlbmQ7IGRhdGErKykgeworCQkgICAgaWYgKCFpc3NwYWNl KCpkYXRhKSkgeworCQkJZ290byBiYWQ2NDsKKwkJICAgIH0KKwkJfQorCSAg ICB9CisJfQogICAgIH0KICAgICBUY2xfU2V0Qnl0ZUFycmF5TGVuZ3RoKHJl c3VsdE9iaiwgY3Vyc29yIC0gYmVnaW4gLSBjdXQpOwogICAgIFRjbF9TZXRP YmpSZXN1bHQoaW50ZXJwLCByZXN1bHRPYmopOwpkaWZmIC11ciB0Y2w4LjZi M34vdGVzdHMvYmluYXJ5LnRlc3QgdGNsOC42YjMvdGVzdHMvYmluYXJ5LnRl c3QKLS0tIHRjbDguNmIzfi90ZXN0cy9iaW5hcnkudGVzdAkyMDEyLTA2LTI2 IDA4OjU5OjAyLjAwMDAwMDAwMCAtMDUwMAorKysgdGNsOC42YjMvdGVzdHMv YmluYXJ5LnRlc3QJMjAxMi0xMC0xNiAxODo0Mzo1MC4wMDAwMDAwMDAgLTA1 MDAKQEAgLTI2NDIsNiArMjY0MiwyNyBAQAogdGVzdCBiaW5hcnktNzMuMjQg e2JpbmFyeSBkZWNvZGUgYmFzZTY0fSAtYm9keSB7CiAgICAgc3RyaW5nIGxl bmd0aCBbYmluYXJ5IGRlY29kZSBiYXNlNjQgIiAiXQogfSAtcmVzdWx0IDAK K3Rlc3QgYmluYXJ5LTczLjI1IHtiaW5hcnkgZGVjb2RlIGJhc2U2NH0gLWJv ZHkgeworICAgIGxpc3QgW3N0cmluZyBsZW5ndGggW3NldCByIFtiaW5hcnkg ZGVjb2RlIGJhc2U2NCBXQT09XG5dXV0gJHIKK30gLXJlc3VsdCB7MSBYfQor dGVzdCBiaW5hcnktNzMuMjYge2JpbmFyeSBkZWNvZGUgYmFzZTY0fSAtYm9k eSB7CisgICAgbGlzdCBbc3RyaW5nIGxlbmd0aCBbc2V0IHIgW2JpbmFyeSBk ZWNvZGUgYmFzZTY0IFdGaz1cbl1dXSAkcgorfSAtcmVzdWx0IHsyIFhZfQor dGVzdCBiaW5hcnktNzMuMjcge2JpbmFyeSBkZWNvZGUgYmFzZTY0fSAtYm9k eSB7CisgICAgbGlzdCBbc3RyaW5nIGxlbmd0aCBbc2V0IHIgW2JpbmFyeSBk ZWNvZGUgYmFzZTY0IFdGbGFcbl1dXSAkcgorfSAtcmVzdWx0IHszIFhZWn0K K3Rlc3QgYmluYXJ5LTczLjI4IHtiaW5hcnkgZGVjb2RlIGJhc2U2NH0gLWJv ZHkgeworICAgIGxpc3QgW3N0cmluZyBsZW5ndGggW3NldCByIFtiaW5hcnkg ZGVjb2RlIGJhc2U2NCAtc3RyaWN0IFdBPT1cbl1dXSAkcgorfSAtcmV0dXJu Q29kZXMgZXJyb3IgLW1hdGNoIGdsb2IgLXJlc3VsdCB7aW52YWxpZCBiYXNl NjQgY2hhcmFjdGVyICp9Cit0ZXN0IGJpbmFyeS03My4yOSB7YmluYXJ5IGRl Y29kZSBiYXNlNjR9IC1ib2R5IHsKKyAgICBsaXN0IFtzdHJpbmcgbGVuZ3Ro IFtzZXQgciBbYmluYXJ5IGRlY29kZSBiYXNlNjQgLXN0cmljdCBXRms9XG5d XV0gJHIKK30gLXJldHVybkNvZGVzIGVycm9yIC1tYXRjaCBnbG9iIC1yZXN1 bHQge2ludmFsaWQgYmFzZTY0IGNoYXJhY3RlciAqfQordGVzdCBiaW5hcnkt NzMuMzAge2JpbmFyeSBkZWNvZGUgYmFzZTY0fSAtYm9keSB7CisgICAgbGlz dCBbc3RyaW5nIGxlbmd0aCBbc2V0IHIgW2JpbmFyeSBkZWNvZGUgYmFzZTY0 IC1zdHJpY3QgV0ZsYVxuXV1dICRyCit9IC1yZXR1cm5Db2RlcyBlcnJvciAt bWF0Y2ggZ2xvYiAtcmVzdWx0IHtpbnZhbGlkIGJhc2U2NCBjaGFyYWN0ZXIg Kn0KK3Rlc3QgYmluYXJ5LTczLjMxIHtiaW5hcnkgZGVjb2RlIGJhc2U2NH0g LWJvZHkgeworICAgIGxpc3QgW3N0cmluZyBsZW5ndGggW3NldCByIFtiaW5h cnkgZGVjb2RlIGJhc2U2NCBXQT09V0ZsYV1dXSAkcgorfSAtcmV0dXJuQ29k ZXMgZXJyb3IgLW1hdGNoIGdsb2IgLXJlc3VsdCB7aW52YWxpZCBiYXNlNjQg Y2hhcmFjdGVyICp9CiAKIHRlc3QgYmluYXJ5LTc0LjEge2JpbmFyeSBlbmNv ZGUgdXVlbmNvZGV9IC1ib2R5IHsKICAgICBiaW5hcnkgZW5jb2RlIHV1ZW5j b2RlCg== ====