]> granicus.if.org Git - php/commitdiff
base64_decode: fix bug #72264 ('VV= =' shouldn't fail in strict mode)
authorLauri Kenttä <lauri.kentta@gmail.com>
Wed, 25 May 2016 19:06:42 +0000 (22:06 +0300)
committerNikita Popov <nikic@php.net>
Wed, 6 Jul 2016 23:27:23 +0000 (01:27 +0200)
ext/standard/base64.c
ext/standard/tests/strings/bug72264.phpt [new file with mode: 0644]

index dc3e52071b159299385fec185f4d8ace4101d4f3..d625dc0752a87fc225d7bc926b4208777a8cf6f8 100644 (file)
@@ -136,7 +136,7 @@ PHPAPI zend_string *php_base64_decode(const unsigned char *str, size_t length) /
 PHPAPI zend_string *php_base64_decode_ex(const unsigned char *str, size_t length, zend_bool strict) /* {{{ */
 {
        const unsigned char *current = str;
-       int ch, i = 0, j = 0;
+       int ch, i = 0, j = 0, padding = 0;
        zend_string *result;
 
        result = zend_string_alloc(length, 0);
@@ -155,26 +155,26 @@ PHPAPI zend_string *php_base64_decode_ex(const unsigned char *str, size_t length
                                zend_string_free(result);
                                return NULL;
                        }
-                       if (length > 0 && *current != '=' && strict) {
-                               while (length > 0 && isspace(*current)) {
-                                       current++;
-                                       length--;
-                               }
-                               if (length == 0 || *current == '\0') {
-                                       continue;
-                               }
-                               zend_string_free(result);
-                               return NULL;
-                       }
+                       padding++;
                        continue;
                }
 
                ch = base64_reverse_table[ch];
-               if ((!strict && ch < 0) || ch == -1) { /* a space or some other separator character, we simply skip over */
-                       continue;
-               } else if (ch == -2) {
-                       zend_string_free(result);
-                       return NULL;
+               if (!strict) {
+                       /* skip unknown characters and whitespace */
+                       if (ch < 0) {
+                               continue;
+                       }
+               } else {
+                       /* skip whitespace */
+                       if (ch == -1) {
+                               continue;
+                       }
+                       /* fail on bad characters or if any data follows padding */
+                       if (ch == -2 || padding) {
+                               zend_string_free(result);
+                               return NULL;
+                       }
                }
 
                switch(i % 4) {
diff --git a/ext/standard/tests/strings/bug72264.phpt b/ext/standard/tests/strings/bug72264.phpt
new file mode 100644 (file)
index 0000000..67dc0e9
--- /dev/null
@@ -0,0 +1,7 @@
+--TEST--
+Bug #72264 (base64_decode $strict fails with whitespace between padding)
+--FILE--
+<?php
+var_dump(base64_decode("VV= =", true));
+--EXPECT--
+string(1) "U"