]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.4' into PHP-8.0
authorChristoph M. Becker <cmbecker69@gmx.de>
Tue, 5 Jan 2021 22:43:20 +0000 (23:43 +0100)
committerChristoph M. Becker <cmbecker69@gmx.de>
Tue, 5 Jan 2021 22:46:05 +0000 (23:46 +0100)
* PHP-7.4:
  Fix #77565: Incorrect locator detection in ZIP-based phars

1  2 
NEWS
ext/phar/tests/bug69441.phpt
ext/phar/tests/zip/corrupt_003.phpt
ext/phar/zip.c

diff --cc NEWS
index 569241ef5549f2ee8077b4baf9d285b173bfb20b,6a12fe4a8816bb8ee31fb5f087ad63751bfb6aa7..f40480ca88d02f1ec345a369960de7e32f8a43b5
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -32,17 -20,14 +32,19 @@@ PH
    . Fixed bug #77935 (Crash in mysqlnd_fetch_stmt_row_cursor when calling an SP
      with a cursor). (Nikita)
  
 +- PDO_Firebird:
 +  . Fixed bug #80521 (Parameters with underscores no longer recognized). (cmb,
 +    Simonov Denis)
 +
  - Phar:
 -07 Jan 2021, PHP 7.4.14
 +  . Fixed bug #76929 (zip-based phar does not respect phar.require_hash).
 +    (david at bamsoftware, cmb)
+   . Fixed bug #77565 (Incorrect locator detection in ZIP-based phars). (cmb)
 +
 +07 Jan 2021, PHP 8.0.1
  
  - Core:
 -  . Fixed bug #74558 (Can't rebind closure returned by Closure::fromCallable()).
 -    (cmb)
    . Fixed bug #80345 (PHPIZE configuration has outdated PHP_RELEASE_VERSION).
      (cmb)
    . Fixed bug #72964 (White space not unfolded for CC/Bcc headers). (cmb)
index 43565b81d9fd59eddbbf0f4cf43188639aa4e6f6,7150af0f341aa5ff079bce1073e614da2931ba9d..b1b6a5de3de902f0683bc02e505ea3309499d00f
@@@ -8,11 -8,13 +8,11 @@@ $fname = __DIR__ . '/bug69441.phar'
  try {
  $r = new Phar($fname, 0);
  } catch(UnexpectedValueException $e) {
 -      echo $e;
 +    echo $e;
  }
  ?>
 -
 -==DONE==
  --EXPECTF--
- UnexpectedValueException: phar error: corrupted central directory entry, no magic signature in zip-based phar "%sbug69441.phar" in %sbug69441.php:%d
+ UnexpectedValueException: phar error: end of central directory not found in zip-based phar "%sbug69441.phar" in %sbug69441.php:%d
  Stack trace:
  #0 %s%ebug69441.php(%d): Phar->__construct('%s', 0)
  #1 {main}
index 6c2aebb9289bb405d8c805857b6e0e07d5bba7ec,9f5bcceeec55288044ad20572f2fccbc1bd56fbc..60c17210a3138887f4deeb0c684fc8dd163c25c2
@@@ -5,10 -5,12 +5,10 @@@ Phar: corrupted zip (truncated file com
  --FILE--
  <?php
  try {
 -      new PharData(__DIR__ . '/files/filecomment.zip');
 +    new PharData(__DIR__ . '/files/filecomment.zip');
  } catch (Exception $e) {
 -      echo $e->getMessage() . "\n";
 +    echo $e->getMessage() . "\n";
  }
  ?>
 -===DONE===
  --EXPECTF--
- phar error: corrupt zip archive, zip file comment truncated in zip-based phar "%sfilecomment.zip"
+ phar error: end of central directory not found in zip-based phar "%sfilecomment.zip"
 -===DONE===
diff --cc ext/phar/zip.c
index f3aef85cd9a43129d2274bed39b2a5d877091bd6,c52e87647d11a5266d50a1636828728720dc36f3..eb683a886cd3e44300017df2a0df7f0ee02ea60d
@@@ -205,50 -228,55 +228,48 @@@ int phar_parse_zipfile(php_stream *fp, 
                return FAILURE;
        }
  
-       while ((p=(char *) memchr(p + 1, 'P', (size_t) (size - (p + 1 - buf)))) != NULL) {
-               if ((p - buf) + sizeof(locator) <= (size_t)size && !memcmp(p + 1, "K\5\6", 3)) {
-                       memcpy((void *)&locator, (void *) p, sizeof(locator));
-                       if (PHAR_GET_16(locator.centraldisk) != 0 || PHAR_GET_16(locator.disknumber) != 0) {
-                               /* split archives not handled */
-                               php_stream_close(fp);
-                               if (error) {
-                                       spprintf(error, 4096, "phar error: split archives spanning multiple zips cannot be processed in zip-based phar \"%s\"", fname);
-                               }
-                               return FAILURE;
+       if ((p = phar_find_eocd(buf, size)) != NULL) {
+               memcpy((void *)&locator, (void *) p, sizeof(locator));
+               if (PHAR_GET_16(locator.centraldisk) != 0 || PHAR_GET_16(locator.disknumber) != 0) {
+                       /* split archives not handled */
+                       php_stream_close(fp);
+                       if (error) {
+                               spprintf(error, 4096, "phar error: split archives spanning multiple zips cannot be processed in zip-based phar \"%s\"", fname);
                        }
+                       return FAILURE;
+               }
  
-                       if (PHAR_GET_16(locator.counthere) != PHAR_GET_16(locator.count)) {
-                               if (error) {
-                                       spprintf(error, 4096, "phar error: corrupt zip archive, conflicting file count in end of central directory record in zip-based phar \"%s\"", fname);
-                               }
-                               php_stream_close(fp);
-                               return FAILURE;
+               if (PHAR_GET_16(locator.counthere) != PHAR_GET_16(locator.count)) {
+                       if (error) {
+                               spprintf(error, 4096, "phar error: corrupt zip archive, conflicting file count in end of central directory record in zip-based phar \"%s\"", fname);
                        }
+                       php_stream_close(fp);
+                       return FAILURE;
+               }
  
-                       mydata = pecalloc(1, sizeof(phar_archive_data), PHAR_G(persist));
-                       mydata->is_persistent = PHAR_G(persist);
+               mydata = pecalloc(1, sizeof(phar_archive_data), PHAR_G(persist));
+               mydata->is_persistent = PHAR_G(persist);
  
-                       /* read in archive comment, if any */
-                       if (PHAR_GET_16(locator.comment_len)) {
+               /* read in archive comment, if any */
+               if (PHAR_GET_16(locator.comment_len)) {
  
-                               metadata = p + sizeof(locator);
+                       metadata = p + sizeof(locator);
  
-                               if (PHAR_GET_16(locator.comment_len) != size - (metadata - buf)) {
-                                       if (error) {
-                                               spprintf(error, 4096, "phar error: corrupt zip archive, zip file comment truncated in zip-based phar \"%s\"", fname);
-                                       }
-                                       php_stream_close(fp);
-                                       pefree(mydata, mydata->is_persistent);
-                                       return FAILURE;
+                       if (PHAR_GET_16(locator.comment_len) != size - (metadata - buf)) {
+                               if (error) {
+                                       spprintf(error, 4096, "phar error: corrupt zip archive, zip file comment truncated in zip-based phar \"%s\"", fname);
                                }
-                               phar_parse_metadata_lazy(metadata, &mydata->metadata_tracker, PHAR_GET_16(locator.comment_len), mydata->is_persistent);
-                       } else {
-                               ZVAL_UNDEF(&mydata->metadata_tracker.val);
+                               php_stream_close(fp);
+                               pefree(mydata, mydata->is_persistent);
+                               return FAILURE;
                        }
  
-                       goto foundit;
 -                      mydata->metadata_len = PHAR_GET_16(locator.comment_len);
 -
 -                      if (phar_parse_metadata(&metadata, &mydata->metadata, PHAR_GET_16(locator.comment_len)) == FAILURE) {
 -                              mydata->metadata_len = 0;
 -                              /* if not valid serialized data, it is a regular string */
 -
 -                              ZVAL_NEW_STR(&mydata->metadata, zend_string_init(metadata, PHAR_GET_16(locator.comment_len), mydata->is_persistent));
 -                      }
++                      phar_parse_metadata_lazy(metadata, &mydata->metadata_tracker, PHAR_GET_16(locator.comment_len), mydata->is_persistent);
+               } else {
 -                      ZVAL_UNDEF(&mydata->metadata);
++                      ZVAL_UNDEF(&mydata->metadata_tracker.val);
                }
+               goto foundit;
        }
  
        php_stream_close(fp);