]> granicus.if.org Git - php/commitdiff
MFB: fix several errors found by valgrind
authorGreg Beaver <cellog@php.net>
Sun, 26 Oct 2008 05:49:24 +0000 (05:49 +0000)
committerGreg Beaver <cellog@php.net>
Sun, 26 Oct 2008 05:49:24 +0000 (05:49 +0000)
1 - entry metadata not properly processed or retrieved from cached phars
2 - copy on write was using a void return value instead of int, a dangerous oversight in phar_update_cached_entry
3 - metadata creation in entries for cached phars was causing an invalid read

ext/phar/phar.c
ext/phar/phar_object.c
ext/phar/util.c

index 31efbcab338eba8e6d010f394b91ae0820a616fa..0db27db34eb6cf3cb65b872f306deeb77b6e6641 100644 (file)
@@ -1035,6 +1035,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
        /* check whether we have meta data, zero check works regardless of byte order */
        if (mydata->is_persistent) {
                PHAR_GET_32(buffer, mydata->metadata_len);
+               if (!mydata->metadata_len) buffer -= 4;
                if (phar_parse_metadata(&buffer, &mydata->metadata, mydata->metadata_len TSRMLS_CC) == FAILURE) {
                        MAPPHAR_FAIL("unable to read phar metadata in .phar file \"%s\"");
                }
@@ -1114,7 +1115,9 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
                }
 
                if (entry.is_persistent) {
-                       if (phar_parse_metadata(&buffer, &entry.metadata, 0 TSRMLS_CC) == FAILURE) {
+                       PHAR_GET_32(buffer, entry.metadata_len);
+                       if (!entry.metadata_len) buffer -= 4;
+                       if (phar_parse_metadata(&buffer, &entry.metadata, entry.metadata_len TSRMLS_CC) == FAILURE) {
                                pefree(entry.filename, entry.is_persistent);
                                MAPPHAR_FAIL("unable to read file metadata in .phar file \"%s\"");
                        }
index e2261b95354236ca79d8d4336e33f51ee766c08d..d3bc4de87244dfbff361fee55676d5466696d280 100755 (executable)
@@ -4583,6 +4583,15 @@ PHP_METHOD(PharFileInfo, getMetadata)
        PHAR_ENTRY_OBJECT();
 
        if (entry_obj->ent.entry->metadata) {
+               if (entry_obj->ent.entry->is_persistent) {
+                       zval *ret;
+                       char *buf = estrndup((char *) entry_obj->ent.entry->metadata, entry_obj->ent.entry->metadata_len);
+                       /* assume success, we would have failed before */
+                       phar_parse_metadata(&buf, &ret, entry_obj->ent.entry->metadata_len TSRMLS_CC);
+                       efree(buf);
+                       RETURN_ZVAL(ret, 0, 1);
+                       return;
+               }
                RETURN_ZVAL(entry_obj->ent.entry->metadata, 1, 0);
        }
 }
index c6d734981c8e44ffc41c107667cfebe00307c88c..5c57e72e41825962fd17d55556f95f64aa51cb17 100644 (file)
@@ -2198,7 +2198,7 @@ void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, int filename
 }
 /* }}} */
 
-static void phar_update_cached_entry(void *data, void *argument) /* {{{ */
+static int phar_update_cached_entry(void *data, void *argument) /* {{{ */
 {
        phar_entry_info *entry = (phar_entry_info *)data;
        TSRMLS_FETCH();
@@ -2221,7 +2221,7 @@ static void phar_update_cached_entry(void *data, void *argument) /* {{{ */
                if (entry->metadata_len) {
                        char *buf = estrndup((char *) entry->metadata, entry->metadata_len);
                        /* assume success, we would have failed before */
-                       phar_parse_metadata((char **) &entry->metadata, &entry->metadata, entry->metadata_len TSRMLS_CC);
+                       phar_parse_metadata((char **) &buf, &entry->metadata, entry->metadata_len TSRMLS_CC);
                        efree(buf);
                } else {
                        zval *t;
@@ -2239,6 +2239,7 @@ static void phar_update_cached_entry(void *data, void *argument) /* {{{ */
                        entry->metadata_str.len = 0;
                }
        }
+       return ZEND_HASH_APPLY_KEEP;
 }
 /* }}} */