PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/phar - util.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 746 978 76.3 %
Date: 2016-08-24 Functions: 28 29 96.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   +----------------------------------------------------------------------+
       3             :   | phar php single-file executable PHP extension                        |
       4             :   | utility functions                                                    |
       5             :   +----------------------------------------------------------------------+
       6             :   | Copyright (c) 2005-2016 The PHP Group                                |
       7             :   +----------------------------------------------------------------------+
       8             :   | This source file is subject to version 3.01 of the PHP license,      |
       9             :   | that is bundled with this package in the file LICENSE, and is        |
      10             :   | available through the world-wide-web at the following url:           |
      11             :   | http://www.php.net/license/3_01.txt.                                 |
      12             :   | If you did not receive a copy of the PHP license and are unable to   |
      13             :   | obtain it through the world-wide-web, please send a note to          |
      14             :   | license@php.net so we can mail you a copy immediately.               |
      15             :   +----------------------------------------------------------------------+
      16             :   | Authors: Gregory Beaver <cellog@php.net>                             |
      17             :   |          Marcus Boerger <helly@php.net>                              |
      18             :   +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : 
      23             : #include "phar_internal.h"
      24             : #ifdef PHAR_HASH_OK
      25             : #include "ext/hash/php_hash_sha.h"
      26             : #endif
      27             : 
      28             : #ifdef PHAR_HAVE_OPENSSL
      29             : /* OpenSSL includes */
      30             : #include <openssl/evp.h>
      31             : #include <openssl/x509.h>
      32             : #include <openssl/x509v3.h>
      33             : #include <openssl/crypto.h>
      34             : #include <openssl/pem.h>
      35             : #include <openssl/err.h>
      36             : #include <openssl/conf.h>
      37             : #include <openssl/rand.h>
      38             : #include <openssl/ssl.h>
      39             : #include <openssl/pkcs12.h>
      40             : #else
      41             : static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, int key_len, char **signature, int *signature_len);
      42             : #endif
      43             : 
      44             : /* for links to relative location, prepend cwd of the entry */
      45          34 : static char *phar_get_link_location(phar_entry_info *entry) /* {{{ */
      46             : {
      47          34 :         char *p, *ret = NULL;
      48          34 :         if (!entry->link) {
      49           0 :                 return NULL;
      50             :         }
      51          34 :         if (entry->link[0] == '/') {
      52           1 :                 return estrdup(entry->link + 1);
      53             :         }
      54          33 :         p = strrchr(entry->filename, '/');
      55          33 :         if (p) {
      56           3 :                 *p = '\0';
      57           3 :                 spprintf(&ret, 0, "%s/%s", entry->filename, entry->link);
      58           3 :                 return ret;
      59             :         }
      60          30 :         return entry->link;
      61             : }
      62             : /* }}} */
      63             : 
      64        7977 : phar_entry_info *phar_get_link_source(phar_entry_info *entry) /* {{{ */
      65             : {
      66             :         phar_entry_info *link_entry;
      67             :         char *link;
      68             : 
      69        7977 :         if (!entry->link) {
      70        7943 :                 return entry;
      71             :         }
      72             : 
      73          34 :         link = phar_get_link_location(entry);
      74          74 :         if (NULL != (link_entry = zend_hash_str_find_ptr(&(entry->phar->manifest), entry->link, strlen(entry->link))) ||
      75           6 :                 NULL != (link_entry = zend_hash_str_find_ptr(&(entry->phar->manifest), link, strlen(link)))) {
      76          31 :                 if (link != entry->link) {
      77           4 :                         efree(link);
      78             :                 }
      79          31 :                 return phar_get_link_source(link_entry);
      80             :         } else {
      81           3 :                 if (link != entry->link) {
      82           0 :                         efree(link);
      83             :                 }
      84           3 :                 return NULL;
      85             :         }
      86             : }
      87             : /* }}} */
      88             : 
      89             : /* retrieve a phar_entry_info's current file pointer for reading contents */
      90       59811 : php_stream *phar_get_efp(phar_entry_info *entry, int follow_links) /* {{{ */
      91             : {
      92       59811 :         if (follow_links && entry->link) {
      93           4 :                 phar_entry_info *link_entry = phar_get_link_source(entry);
      94             : 
      95           4 :                 if (link_entry && link_entry != entry) {
      96           3 :                         return phar_get_efp(link_entry, 1);
      97             :                 }
      98             :         }
      99             : 
     100       59808 :         if (phar_get_fp_type(entry) == PHAR_FP) {
     101       16048 :                 if (!phar_get_entrypfp(entry)) {
     102             :                         /* re-open just in time for cases where our refcount reached 0 on the phar archive */
     103          22 :                         phar_open_archive_fp(entry->phar);
     104             :                 }
     105       16048 :                 return phar_get_entrypfp(entry);
     106       43760 :         } else if (phar_get_fp_type(entry) == PHAR_UFP) {
     107       15638 :                 return phar_get_entrypufp(entry);
     108       28122 :         } else if (entry->fp_type == PHAR_MOD) {
     109       28111 :                 return entry->fp;
     110             :         } else {
     111             :                 /* temporary manifest entry */
     112          11 :                 if (!entry->fp) {
     113           0 :                         entry->fp = php_stream_open_wrapper(entry->tmp, "rb", STREAM_MUST_SEEK|0, NULL);
     114             :                 }
     115          11 :                 return entry->fp;
     116             :         }
     117             : }
     118             : /* }}} */
     119             : 
     120       23832 : int phar_seek_efp(phar_entry_info *entry, zend_off_t offset, int whence, zend_off_t position, int follow_links) /* {{{ */
     121             : {
     122       23832 :         php_stream *fp = phar_get_efp(entry, follow_links);
     123             :         zend_off_t temp, eoffset;
     124             : 
     125       23832 :         if (!fp) {
     126           1 :                 return -1;
     127             :         }
     128             : 
     129       23831 :         if (follow_links) {
     130             :                 phar_entry_info *t;
     131        7718 :                 t = phar_get_link_source(entry);
     132        7718 :                 if (t) {
     133        7718 :                         entry = t;
     134             :                 }
     135             :         }
     136             : 
     137       23831 :         if (entry->is_dir) {
     138          18 :                 return 0;
     139             :         }
     140             : 
     141       23813 :         eoffset = phar_get_fp_offset(entry);
     142             : 
     143       23813 :         switch (whence) {
     144             :                 case SEEK_END:
     145           0 :                         temp = eoffset + entry->uncompressed_filesize + offset;
     146           0 :                         break;
     147             :                 case SEEK_CUR:
     148           0 :                         temp = eoffset + position + offset;
     149           0 :                         break;
     150             :                 case SEEK_SET:
     151       23813 :                         temp = eoffset + offset;
     152       23813 :                         break;
     153             :                 default:
     154           0 :                         temp = 0;
     155             :         }
     156             : 
     157       23813 :         if (temp > eoffset + (zend_off_t) entry->uncompressed_filesize) {
     158           0 :                 return -1;
     159             :         }
     160             : 
     161       23813 :         if (temp < eoffset) {
     162           0 :                 return -1;
     163             :         }
     164             : 
     165       23813 :         return php_stream_seek(fp, temp, SEEK_SET);
     166             : }
     167             : /* }}} */
     168             : 
     169             : /* mount an absolute path or uri to a path internal to the phar archive */
     170          23 : int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, char *path, int path_len) /* {{{ */
     171             : {
     172          23 :         phar_entry_info entry = {0};
     173             :         php_stream_statbuf ssb;
     174             :         int is_phar;
     175             :         const char *err;
     176             : 
     177          23 :         if (phar_path_check(&path, &path_len, &err) > pcr_is_ok) {
     178           0 :                 return FAILURE;
     179             :         }
     180             : 
     181          23 :         if (path_len >= (int)sizeof(".phar")-1 && !memcmp(path, ".phar", sizeof(".phar")-1)) {
     182             :                 /* no creating magic phar files by mounting them */
     183           1 :                 return FAILURE;
     184             :         }
     185             : 
     186          22 :         is_phar = (filename_len > 7 && !memcmp(filename, "phar://", 7));
     187             : 
     188          22 :         entry.phar = phar;
     189          22 :         entry.filename = estrndup(path, path_len);
     190             : #ifdef PHP_WIN32
     191             :         phar_unixify_path_separators(entry.filename, path_len);
     192             : #endif
     193          22 :         entry.filename_len = path_len;
     194          22 :         if (is_phar) {
     195           4 :                 entry.tmp = estrndup(filename, filename_len);
     196             :         } else {
     197          18 :                 entry.tmp = expand_filepath(filename, NULL);
     198          18 :                 if (!entry.tmp) {
     199           0 :                         entry.tmp = estrndup(filename, filename_len);
     200             :                 }
     201             :         }
     202          22 :         filename = entry.tmp;
     203             : 
     204             :         /* only check openbasedir for files, not for phar streams */
     205          22 :         if (!is_phar && php_check_open_basedir(filename)) {
     206           0 :                 efree(entry.tmp);
     207           0 :                 efree(entry.filename);
     208           0 :                 return FAILURE;
     209             :         }
     210             : 
     211          22 :         entry.is_mounted = 1;
     212          22 :         entry.is_crc_checked = 1;
     213          22 :         entry.fp_type = PHAR_TMP;
     214             : 
     215          22 :         if (SUCCESS != php_stream_stat_path(filename, &ssb)) {
     216           3 :                 efree(entry.tmp);
     217           3 :                 efree(entry.filename);
     218           3 :                 return FAILURE;
     219             :         }
     220             : 
     221          19 :         if (ssb.sb.st_mode & S_IFDIR) {
     222           5 :                 entry.is_dir = 1;
     223          10 :                 if (NULL == zend_hash_str_add_ptr(&phar->mounted_dirs, entry.filename, path_len, entry.filename)) {
     224             :                         /* directory already mounted */
     225           1 :                         efree(entry.tmp);
     226           1 :                         efree(entry.filename);
     227           1 :                         return FAILURE;
     228             :                 }
     229             :         } else {
     230          14 :                 entry.is_dir = 0;
     231          14 :                 entry.uncompressed_filesize = entry.compressed_filesize = ssb.sb.st_size;
     232             :         }
     233             : 
     234          18 :         entry.flags = ssb.sb.st_mode;
     235             : 
     236          36 :         if (NULL != zend_hash_str_add_mem(&phar->manifest, entry.filename, path_len, (void*)&entry, sizeof(phar_entry_info))) {
     237          15 :                 return SUCCESS;
     238             :         }
     239             : 
     240           3 :         efree(entry.tmp);
     241           3 :         efree(entry.filename);
     242           3 :         return FAILURE;
     243             : }
     244             : /* }}} */
     245             : 
     246       17233 : zend_string *phar_find_in_include_path(char *filename, int filename_len, phar_archive_data **pphar) /* {{{ */
     247             : {
     248             :         zend_string *ret;
     249             :         char *path, *fname, *arch, *entry, *test;
     250             :         int arch_len, entry_len, fname_len;
     251             :         phar_archive_data *phar;
     252             : 
     253       17233 :         if (pphar) {
     254           0 :                 *pphar = NULL;
     255             :         } else {
     256       17233 :                 pphar = &phar;
     257             :         }
     258             : 
     259       17233 :         if (!zend_is_executing() || !PHAR_G(cwd)) {
     260       17211 :                 return phar_save_resolve_path(filename, filename_len);
     261             :         }
     262             : 
     263          22 :         fname = (char*)zend_get_executed_filename();
     264          22 :         fname_len = strlen(fname);
     265             : 
     266          22 :         if (PHAR_G(last_phar) && !memcmp(fname, "phar://", 7) && fname_len - 7 >= PHAR_G(last_phar_name_len) && !memcmp(fname + 7, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len))) {
     267           1 :                 arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len));
     268           1 :                 arch_len = PHAR_G(last_phar_name_len);
     269           1 :                 phar = PHAR_G(last_phar);
     270           1 :                 goto splitted;
     271             :         }
     272             : 
     273          21 :         if (fname_len < 7 || memcmp(fname, "phar://", 7) || SUCCESS != phar_split_fname(fname, strlen(fname), &arch, &arch_len, &entry, &entry_len, 1, 0)) {
     274          14 :                 return phar_save_resolve_path(filename, filename_len);
     275             :         }
     276             : 
     277           7 :         efree(entry);
     278             : 
     279           7 :         if (*filename == '.') {
     280             :                 int try_len;
     281             : 
     282           4 :                 if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL)) {
     283           0 :                         efree(arch);
     284           0 :                         return phar_save_resolve_path(filename, filename_len);
     285             :                 }
     286             : splitted:
     287           5 :                 if (pphar) {
     288           5 :                         *pphar = phar;
     289             :                 }
     290             : 
     291           5 :                 try_len = filename_len;
     292           5 :                 test = phar_fix_filepath(estrndup(filename, filename_len), &try_len, 1);
     293             : 
     294           5 :                 if (*test == '/') {
     295           2 :                         if (zend_hash_str_exists(&(phar->manifest), test + 1, try_len - 1)) {
     296           2 :                                 ret = strpprintf(0, "phar://%s%s", arch, test);
     297           2 :                                 efree(arch);
     298           2 :                                 efree(test);
     299           2 :                                 return ret;
     300             :                         }
     301             :                 } else {
     302           3 :                         if (zend_hash_str_exists(&(phar->manifest), test, try_len)) {
     303           2 :                                 ret = strpprintf(0, "phar://%s/%s", arch, test);
     304           2 :                                 efree(arch);
     305           2 :                                 efree(test);
     306           2 :                                 return ret;
     307             :                         }
     308             :                 }
     309           1 :                 efree(test);
     310             :         }
     311             : 
     312           4 :         spprintf(&path, MAXPATHLEN, "phar://%s/%s%c%s", arch, PHAR_G(cwd), DEFAULT_DIR_SEPARATOR, PG(include_path));
     313           4 :         efree(arch);
     314           4 :         ret = php_resolve_path(filename, filename_len, path);
     315           4 :         efree(path);
     316             : 
     317           4 :         if (ret && ZSTR_LEN(ret) > 8 && !strncmp(ZSTR_VAL(ret), "phar://", 7)) {
     318             :                 /* found phar:// */
     319           2 :                 if (SUCCESS != phar_split_fname(ZSTR_VAL(ret), ZSTR_LEN(ret), &arch, &arch_len, &entry, &entry_len, 1, 0)) {
     320           0 :                         return ret;
     321             :                 }
     322             : 
     323           4 :                 *pphar = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), arch, arch_len);
     324             : 
     325           2 :                 if (!*pphar && PHAR_G(manifest_cached)) {
     326           0 :                         *pphar = zend_hash_str_find_ptr(&cached_phars, arch, arch_len);
     327             :                 }
     328             : 
     329           2 :                 efree(arch);
     330           2 :                 efree(entry);
     331             :         }
     332             : 
     333           4 :         return ret;
     334             : }
     335             : /* }}} */
     336             : 
     337             : /**
     338             :  * Retrieve a copy of the file information on a single file within a phar, or null.
     339             :  * This also transfers the open file pointer, if any, to the entry.
     340             :  *
     341             :  * If the file does not already exist, this will fail.  Pre-existing files can be
     342             :  * appended, truncated, or read.  For read, if the entry is marked unmodified, it is
     343             :  * assumed that the file pointer, if present, is opened for reading
     344             :  */
     345        8214 : int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, const char *mode, char allow_dir, char **error, int security) /* {{{ */
     346             : {
     347             :         phar_archive_data *phar;
     348             :         phar_entry_info *entry;
     349        8214 :         int for_write  = mode[0] != 'r' || mode[1] == '+';
     350        8214 :         int for_append = mode[0] == 'a';
     351        8214 :         int for_create = mode[0] != 'r';
     352        8214 :         int for_trunc  = mode[0] == 'w';
     353             : 
     354        8214 :         if (!ret) {
     355           0 :                 return FAILURE;
     356             :         }
     357             : 
     358        8214 :         *ret = NULL;
     359             : 
     360        8214 :         if (error) {
     361        8214 :                 *error = NULL;
     362             :         }
     363             : 
     364        8214 :         if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error)) {
     365           0 :                 return FAILURE;
     366             :         }
     367             : 
     368        8214 :         if (for_write && PHAR_G(readonly) && !phar->is_data) {
     369           0 :                 if (error) {
     370           0 :                         spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, disabled by ini setting", path, fname);
     371             :                 }
     372           0 :                 return FAILURE;
     373             :         }
     374             : 
     375        8214 :         if (!path_len) {
     376           4 :                 if (error) {
     377           4 :                         spprintf(error, 4096, "phar error: file \"\" in phar \"%s\" cannot be empty", fname);
     378             :                 }
     379           4 :                 return FAILURE;
     380             :         }
     381             : really_get_entry:
     382        8211 :         if (allow_dir) {
     383          18 :                 if ((entry = phar_get_entry_info_dir(phar, path, path_len, allow_dir, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security)) == NULL) {
     384          16 :                         if (for_create && (!PHAR_G(readonly) || phar->is_data)) {
     385          16 :                                 return SUCCESS;
     386             :                         }
     387           0 :                         return FAILURE;
     388             :                 }
     389             :         } else {
     390        8193 :                 if ((entry = phar_get_entry_info(phar, path, path_len, for_create && !PHAR_G(readonly) && !phar->is_data ? NULL : error, security)) == NULL) {
     391        3540 :                         if (for_create && (!PHAR_G(readonly) || phar->is_data)) {
     392        3516 :                                 return SUCCESS;
     393             :                         }
     394          24 :                         return FAILURE;
     395             :                 }
     396             :         }
     397             : 
     398        4655 :         if (for_write && phar->is_persistent) {
     399           1 :                 if (FAILURE == phar_copy_on_write(&phar)) {
     400           0 :                         if (error) {
     401           0 :                                 spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, could not make cached phar writeable", path, fname);
     402             :                         }
     403           0 :                         return FAILURE;
     404             :                 } else {
     405           1 :                         goto really_get_entry;
     406             :                 }
     407             :         }
     408             : 
     409        4654 :         if (entry->is_modified && !for_write) {
     410           0 :                 if (error) {
     411           0 :                         spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for reading, writable file pointers are open", path, fname);
     412             :                 }
     413           0 :                 return FAILURE;
     414             :         }
     415             : 
     416        4654 :         if (entry->fp_refcount && for_write) {
     417           1 :                 if (error) {
     418           1 :                         spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be opened for writing, readable file pointers are open", path, fname);
     419             :                 }
     420           1 :                 return FAILURE;
     421             :         }
     422             : 
     423        4653 :         if (entry->is_deleted) {
     424           0 :                 if (!for_create) {
     425           0 :                         return FAILURE;
     426             :                 }
     427           0 :                 entry->is_deleted = 0;
     428             :         }
     429             : 
     430        4653 :         if (entry->is_dir) {
     431           2 :                 *ret = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
     432           2 :                 (*ret)->position = 0;
     433           2 :                 (*ret)->fp = NULL;
     434           2 :                 (*ret)->phar = phar;
     435           2 :                 (*ret)->for_write = for_write;
     436           2 :                 (*ret)->internal_file = entry;
     437           2 :                 (*ret)->is_zip = entry->is_zip;
     438           2 :                 (*ret)->is_tar = entry->is_tar;
     439             : 
     440           2 :                 if (!phar->is_persistent) {
     441           2 :                         ++(entry->phar->refcount);
     442           2 :                         ++(entry->fp_refcount);
     443             :                 }
     444             : 
     445           2 :                 return SUCCESS;
     446             :         }
     447             : 
     448        4651 :         if (entry->fp_type == PHAR_MOD) {
     449           0 :                 if (for_trunc) {
     450           0 :                         if (FAILURE == phar_create_writeable_entry(phar, entry, error)) {
     451           0 :                                 return FAILURE;
     452             :                         }
     453           0 :                 } else if (for_append) {
     454           0 :                         phar_seek_efp(entry, 0, SEEK_END, 0, 0);
     455             :                 }
     456             :         } else {
     457        4651 :                 if (for_write) {
     458        4124 :                         if (entry->link) {
     459           1 :                                 efree(entry->link);
     460           1 :                                 entry->link = NULL;
     461           1 :                                 entry->tar_type = (entry->is_tar ? TAR_FILE : '\0');
     462             :                         }
     463             : 
     464        4124 :                         if (for_trunc) {
     465        4123 :                                 if (FAILURE == phar_create_writeable_entry(phar, entry, error)) {
     466           0 :                                         return FAILURE;
     467             :                                 }
     468             :                         } else {
     469           1 :                                 if (FAILURE == phar_separate_entry_fp(entry, error)) {
     470           0 :                                         return FAILURE;
     471             :                                 }
     472             :                         }
     473             :                 } else {
     474         527 :                         if (FAILURE == phar_open_entry_fp(entry, error, 1)) {
     475           4 :                                 return FAILURE;
     476             :                         }
     477             :                 }
     478             :         }
     479             : 
     480        4647 :         *ret = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
     481        4647 :         (*ret)->position = 0;
     482        4647 :         (*ret)->phar = phar;
     483        4647 :         (*ret)->for_write = for_write;
     484        4647 :         (*ret)->internal_file = entry;
     485        4647 :         (*ret)->is_zip = entry->is_zip;
     486        4647 :         (*ret)->is_tar = entry->is_tar;
     487        4647 :         (*ret)->fp = phar_get_efp(entry, 1);
     488        4647 :         if (entry->link) {
     489           4 :                 phar_entry_info *link = phar_get_link_source(entry);
     490           4 :                 if(!link) {
     491           1 :                         efree(*ret);
     492           1 :                         return FAILURE;
     493             :                 }
     494           3 :                 (*ret)->zero = phar_get_fp_offset(link);
     495             :         } else {
     496        4643 :                 (*ret)->zero = phar_get_fp_offset(entry);
     497             :         }
     498             : 
     499        4646 :         if (!phar->is_persistent) {
     500        4646 :                 ++(entry->fp_refcount);
     501        4646 :                 ++(entry->phar->refcount);
     502             :         }
     503             : 
     504        4646 :         return SUCCESS;
     505             : }
     506             : /* }}} */
     507             : 
     508             : /**
     509             :  * Create a new dummy file slot within a writeable phar for a newly created file
     510             :  */
     511        7663 : phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char *path, int path_len, const char *mode, char allow_dir, char **error, int security) /* {{{ */
     512             : {
     513             :         phar_archive_data *phar;
     514             :         phar_entry_info *entry, etemp;
     515             :         phar_entry_data *ret;
     516             :         const char *pcr_error;
     517             :         char is_dir;
     518             : 
     519             : #ifdef PHP_WIN32
     520             :         phar_unixify_path_separators(path, path_len);
     521             : #endif
     522             : 
     523        7663 :         is_dir = (path_len && path[path_len - 1] == '/') ? 1 : 0;
     524             : 
     525        7663 :         if (FAILURE == phar_get_archive(&phar, fname, fname_len, NULL, 0, error)) {
     526           0 :                 return NULL;
     527             :         }
     528             : 
     529        7663 :         if (FAILURE == phar_get_entry_data(&ret, fname, fname_len, path, path_len, mode, allow_dir, error, security)) {
     530           5 :                 return NULL;
     531        7658 :         } else if (ret) {
     532        4126 :                 return ret;
     533             :         }
     534             : 
     535        3532 :         if (phar_path_check(&path, &path_len, &pcr_error) > pcr_is_ok) {
     536           7 :                 if (error) {
     537           7 :                         spprintf(error, 0, "phar error: invalid path \"%s\" contains %s", path, pcr_error);
     538             :                 }
     539           7 :                 return NULL;
     540             :         }
     541             : 
     542        3525 :         if (phar->is_persistent && FAILURE == phar_copy_on_write(&phar)) {
     543           0 :                 if (error) {
     544           0 :                         spprintf(error, 4096, "phar error: file \"%s\" in phar \"%s\" cannot be created, could not make cached phar writeable", path, fname);
     545             :                 }
     546           0 :                 return NULL;
     547             :         }
     548             : 
     549             :         /* create a new phar data holder */
     550        3525 :         ret = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
     551             : 
     552             :         /* create an entry, this is a new file */
     553        3525 :         memset(&etemp, 0, sizeof(phar_entry_info));
     554        3525 :         etemp.filename_len = path_len;
     555        3525 :         etemp.fp_type = PHAR_MOD;
     556        3525 :         etemp.fp = php_stream_fopen_tmpfile();
     557             : 
     558        3525 :         if (!etemp.fp) {
     559           0 :                 if (error) {
     560           0 :                         spprintf(error, 0, "phar error: unable to create temporary file");
     561             :                 }
     562           0 :                 efree(ret);
     563           0 :                 return NULL;
     564             :         }
     565             : 
     566        3525 :         etemp.fp_refcount = 1;
     567             : 
     568        3525 :         if (allow_dir == 2) {
     569          16 :                 etemp.is_dir = 1;
     570          16 :                 etemp.flags = etemp.old_flags = PHAR_ENT_PERM_DEF_DIR;
     571             :         } else {
     572        3509 :                 etemp.flags = etemp.old_flags = PHAR_ENT_PERM_DEF_FILE;
     573             :         }
     574        3525 :         if (is_dir) {
     575           2 :                 etemp.filename_len--; /* strip trailing / */
     576           2 :                 path_len--;
     577             :         }
     578             : 
     579        3525 :         phar_add_virtual_dirs(phar, path, path_len);
     580        3525 :         etemp.is_modified = 1;
     581        3525 :         etemp.timestamp = time(0);
     582        3525 :         etemp.is_crc_checked = 1;
     583        3525 :         etemp.phar = phar;
     584        3525 :         etemp.filename = estrndup(path, path_len);
     585        3525 :         etemp.is_zip = phar->is_zip;
     586             : 
     587        3525 :         if (phar->is_tar) {
     588         100 :                 etemp.is_tar = phar->is_tar;
     589         100 :                 etemp.tar_type = etemp.is_dir ? TAR_DIR : TAR_FILE;
     590             :         }
     591             : 
     592        7050 :         if (NULL == (entry = zend_hash_str_add_mem(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info)))) {
     593           0 :                 php_stream_close(etemp.fp);
     594           0 :                 if (error) {
     595           0 :                         spprintf(error, 0, "phar error: unable to add new entry \"%s\" to phar \"%s\"", etemp.filename, phar->fname);
     596             :                 }
     597           0 :                 efree(ret);
     598           0 :                 efree(etemp.filename);
     599           0 :                 return NULL;
     600             :         }
     601             : 
     602        3525 :         if (!entry) {
     603           0 :                 php_stream_close(etemp.fp);
     604           0 :                 efree(etemp.filename);
     605           0 :                 efree(ret);
     606           0 :                 return NULL;
     607             :         }
     608             : 
     609        3525 :         ++(phar->refcount);
     610        3525 :         ret->phar = phar;
     611        3525 :         ret->fp = entry->fp;
     612        3525 :         ret->position = ret->zero = 0;
     613        3525 :         ret->for_write = 1;
     614        3525 :         ret->is_zip = entry->is_zip;
     615        3525 :         ret->is_tar = entry->is_tar;
     616        3525 :         ret->internal_file = entry;
     617             : 
     618        3525 :         return ret;
     619             : }
     620             : /* }}} */
     621             : 
     622             : /* initialize a phar_archive_data's read-only fp for existing phar data */
     623         346 : int phar_open_archive_fp(phar_archive_data *phar) /* {{{ */
     624             : {
     625         346 :         if (phar_get_pharfp(phar)) {
     626         177 :                 return SUCCESS;
     627             :         }
     628             : 
     629         169 :         if (php_check_open_basedir(phar->fname)) {
     630           0 :                 return FAILURE;
     631             :         }
     632             : 
     633         169 :         phar_set_pharfp(phar, php_stream_open_wrapper(phar->fname, "rb", IGNORE_URL|STREAM_MUST_SEEK|0, NULL));
     634             : 
     635         169 :         if (!phar_get_pharfp(phar)) {
     636           4 :                 return FAILURE;
     637             :         }
     638             : 
     639         165 :         return SUCCESS;
     640             : }
     641             : /* }}} */
     642             : 
     643             : /* copy file data from an existing to a new phar_entry_info that is not in the manifest */
     644           6 : int phar_copy_entry_fp(phar_entry_info *source, phar_entry_info *dest, char **error) /* {{{ */
     645             : {
     646             :         phar_entry_info *link;
     647             : 
     648           6 :         if (FAILURE == phar_open_entry_fp(source, error, 1)) {
     649           0 :                 return FAILURE;
     650             :         }
     651             : 
     652           6 :         if (dest->link) {
     653           0 :                 efree(dest->link);
     654           0 :                 dest->link = NULL;
     655           0 :                 dest->tar_type = (dest->is_tar ? TAR_FILE : '\0');
     656             :         }
     657             : 
     658           6 :         dest->fp_type = PHAR_MOD;
     659           6 :         dest->offset = 0;
     660           6 :         dest->is_modified = 1;
     661           6 :         dest->fp = php_stream_fopen_tmpfile();
     662           6 :         if (dest->fp == NULL) {
     663           0 :                 spprintf(error, 0, "phar error: unable to create temporary file");
     664           0 :                 return EOF;
     665             :         }
     666           6 :         phar_seek_efp(source, 0, SEEK_SET, 0, 1);
     667           6 :         link = phar_get_link_source(source);
     668             : 
     669           6 :         if (!link) {
     670           0 :                 link = source;
     671             :         }
     672             : 
     673           6 :         if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), dest->fp, link->uncompressed_filesize, NULL)) {
     674           0 :                 php_stream_close(dest->fp);
     675           0 :                 dest->fp_type = PHAR_FP;
     676           0 :                 if (error) {
     677           0 :                         spprintf(error, 4096, "phar error: unable to copy contents of file \"%s\" to \"%s\" in phar archive \"%s\"", source->filename, dest->filename, source->phar->fname);
     678             :                 }
     679           0 :                 return FAILURE;
     680             :         }
     681             : 
     682           6 :         return SUCCESS;
     683             : }
     684             : /* }}} */
     685             : 
     686             : /* open and decompress a compressed phar entry
     687             :  */
     688        2437 : int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links) /* {{{ */
     689             : {
     690             :         php_stream_filter *filter;
     691        2437 :         phar_archive_data *phar = entry->phar;
     692             :         char *filtername;
     693             :         zend_off_t loc;
     694             :         php_stream *ufp;
     695             :         phar_entry_data dummy;
     696             : 
     697        2437 :         if (follow_links && entry->link) {
     698           4 :                 phar_entry_info *link_entry = phar_get_link_source(entry);
     699           4 :                 if (link_entry && link_entry != entry) {
     700           3 :                         return phar_open_entry_fp(link_entry, error, 1);
     701             :                 }
     702             :         }
     703             : 
     704        2434 :         if (entry->is_modified) {
     705        1363 :                 return SUCCESS;
     706             :         }
     707             : 
     708        1071 :         if (entry->fp_type == PHAR_TMP) {
     709           9 :                 if (!entry->fp) {
     710           8 :                         entry->fp = php_stream_open_wrapper(entry->tmp, "rb", STREAM_MUST_SEEK|0, NULL);
     711             :                 }
     712           9 :                 return SUCCESS;
     713             :         }
     714             : 
     715        1062 :         if (entry->fp_type != PHAR_FP) {
     716             :                 /* either newly created or already modified */
     717           2 :                 return SUCCESS;
     718             :         }
     719             : 
     720        1060 :         if (!phar_get_pharfp(phar)) {
     721         147 :                 if (FAILURE == phar_open_archive_fp(phar)) {
     722           1 :                         spprintf(error, 4096, "phar error: Cannot open phar archive \"%s\" for reading", phar->fname);
     723           1 :                         return FAILURE;
     724             :                 }
     725             :         }
     726             : 
     727        1059 :         if ((entry->old_flags && !(entry->old_flags & PHAR_ENT_COMPRESSION_MASK)) || !(entry->flags & PHAR_ENT_COMPRESSION_MASK)) {
     728        1018 :                 dummy.internal_file = entry;
     729        1018 :                 dummy.phar = phar;
     730        1018 :                 dummy.zero = entry->offset;
     731        1018 :                 dummy.fp = phar_get_pharfp(phar);
     732        1018 :                 if (FAILURE == phar_postprocess_file(&dummy, entry->crc32, error, 1)) {
     733           0 :                         return FAILURE;
     734             :                 }
     735        1018 :                 return SUCCESS;
     736             :         }
     737             : 
     738          41 :         if (!phar_get_entrypufp(entry)) {
     739          24 :                 phar_set_entrypufp(entry, php_stream_fopen_tmpfile());
     740          24 :                 if (!phar_get_entrypufp(entry)) {
     741           0 :                         spprintf(error, 4096, "phar error: Cannot open temporary file for decompressing phar archive \"%s\" file \"%s\"", phar->fname, entry->filename);
     742           0 :                         return FAILURE;
     743             :                 }
     744             :         }
     745             : 
     746          41 :         dummy.internal_file = entry;
     747          41 :         dummy.phar = phar;
     748          41 :         dummy.zero = entry->offset;
     749          41 :         dummy.fp = phar_get_pharfp(phar);
     750          41 :         if (FAILURE == phar_postprocess_file(&dummy, entry->crc32, error, 1)) {
     751           0 :                 return FAILURE;
     752             :         }
     753             : 
     754          41 :         ufp = phar_get_entrypufp(entry);
     755             : 
     756          41 :         if ((filtername = phar_decompress_filter(entry, 0)) != NULL) {
     757          41 :                 filter = php_stream_filter_create(filtername, NULL, 0);
     758             :         } else {
     759           0 :                 filter = NULL;
     760             :         }
     761             : 
     762          41 :         if (!filter) {
     763           0 :                 spprintf(error, 4096, "phar error: unable to read phar \"%s\" (cannot create %s filter while decompressing file \"%s\")", phar->fname, phar_decompress_filter(entry, 1), entry->filename);
     764           0 :                 return FAILURE;
     765             :         }
     766             : 
     767             :         /* now we can safely use proper decompression */
     768             :         /* save the new offset location within ufp */
     769          41 :         php_stream_seek(ufp, 0, SEEK_END);
     770          41 :         loc = php_stream_tell(ufp);
     771          41 :         php_stream_filter_append(&ufp->writefilters, filter);
     772          41 :         php_stream_seek(phar_get_entrypfp(entry), phar_get_fp_offset(entry), SEEK_SET);
     773             : 
     774          41 :         if (entry->uncompressed_filesize) {
     775          40 :                 if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_entrypfp(entry), ufp, entry->compressed_filesize, NULL)) {
     776           0 :                         spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, entry->filename);
     777           0 :                         php_stream_filter_remove(filter, 1);
     778           0 :                         return FAILURE;
     779             :                 }
     780             :         }
     781             : 
     782          41 :         php_stream_filter_flush(filter, 1);
     783          41 :         php_stream_flush(ufp);
     784          41 :         php_stream_filter_remove(filter, 1);
     785             : 
     786          41 :         if (php_stream_tell(ufp) - loc != (zend_off_t) entry->uncompressed_filesize) {
     787           4 :                 spprintf(error, 4096, "phar error: internal corruption of phar \"%s\" (actual filesize mismatch on file \"%s\")", phar->fname, entry->filename);
     788           4 :                 return FAILURE;
     789             :         }
     790             : 
     791          37 :         entry->old_flags = entry->flags;
     792             : 
     793             :         /* this is now the new location of the file contents within this fp */
     794          37 :         phar_set_fp_type(entry, PHAR_UFP, loc);
     795          37 :         dummy.zero = entry->offset;
     796          37 :         dummy.fp = ufp;
     797          37 :         if (FAILURE == phar_postprocess_file(&dummy, entry->crc32, error, 0)) {
     798           0 :                 return FAILURE;
     799             :         }
     800          37 :         return SUCCESS;
     801             : }
     802             : /* }}} */
     803             : 
     804        4123 : int phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */
     805             : {
     806        4123 :         if (entry->fp_type == PHAR_MOD) {
     807             :                 /* already newly created, truncate */
     808           0 :                 php_stream_truncate_set_size(entry->fp, 0);
     809             : 
     810           0 :                 entry->old_flags = entry->flags;
     811           0 :                 entry->is_modified = 1;
     812           0 :                 phar->is_modified = 1;
     813             :                 /* reset file size */
     814           0 :                 entry->uncompressed_filesize = 0;
     815           0 :                 entry->compressed_filesize = 0;
     816           0 :                 entry->crc32 = 0;
     817           0 :                 entry->flags = PHAR_ENT_PERM_DEF_FILE;
     818           0 :                 entry->fp_type = PHAR_MOD;
     819           0 :                 entry->offset = 0;
     820           0 :                 return SUCCESS;
     821             :         }
     822             : 
     823        4123 :         if (error) {
     824        4123 :                 *error = NULL;
     825             :         }
     826             : 
     827             :         /* open a new temp file for writing */
     828        4123 :         if (entry->link) {
     829           0 :                 efree(entry->link);
     830           0 :                 entry->link = NULL;
     831           0 :                 entry->tar_type = (entry->is_tar ? TAR_FILE : '\0');
     832             :         }
     833             : 
     834        4123 :         entry->fp = php_stream_fopen_tmpfile();
     835             : 
     836        4123 :         if (!entry->fp) {
     837           0 :                 if (error) {
     838           0 :                         spprintf(error, 0, "phar error: unable to create temporary file");
     839             :                 }
     840           0 :                 return FAILURE;
     841             :         }
     842             : 
     843        4123 :         entry->old_flags = entry->flags;
     844        4123 :         entry->is_modified = 1;
     845        4123 :         phar->is_modified = 1;
     846             :         /* reset file size */
     847        4123 :         entry->uncompressed_filesize = 0;
     848        4123 :         entry->compressed_filesize = 0;
     849        4123 :         entry->crc32 = 0;
     850        4123 :         entry->flags = PHAR_ENT_PERM_DEF_FILE;
     851        4123 :         entry->fp_type = PHAR_MOD;
     852        4123 :         entry->offset = 0;
     853        4123 :         return SUCCESS;
     854             : }
     855             : /* }}} */
     856             : 
     857           1 : int phar_separate_entry_fp(phar_entry_info *entry, char **error) /* {{{ */
     858             : {
     859             :         php_stream *fp;
     860             :         phar_entry_info *link;
     861             : 
     862           1 :         if (FAILURE == phar_open_entry_fp(entry, error, 1)) {
     863           0 :                 return FAILURE;
     864             :         }
     865             : 
     866           1 :         if (entry->fp_type == PHAR_MOD) {
     867           0 :                 return SUCCESS;
     868             :         }
     869             : 
     870           1 :         fp = php_stream_fopen_tmpfile();
     871           1 :         if (fp == NULL) {
     872           0 :                 spprintf(error, 0, "phar error: unable to create temporary file");
     873           0 :                 return FAILURE;
     874             :         }
     875           1 :         phar_seek_efp(entry, 0, SEEK_SET, 0, 1);
     876           1 :         link = phar_get_link_source(entry);
     877             : 
     878           1 :         if (!link) {
     879           0 :                 link = entry;
     880             :         }
     881             : 
     882           1 :         if (SUCCESS != php_stream_copy_to_stream_ex(phar_get_efp(link, 0), fp, link->uncompressed_filesize, NULL)) {
     883           0 :                 if (error) {
     884           0 :                         spprintf(error, 4096, "phar error: cannot separate entry file \"%s\" contents in phar archive \"%s\" for write access", entry->filename, entry->phar->fname);
     885             :                 }
     886           0 :                 return FAILURE;
     887             :         }
     888             : 
     889           1 :         if (entry->link) {
     890           0 :                 efree(entry->link);
     891           0 :                 entry->link = NULL;
     892           0 :                 entry->tar_type = (entry->is_tar ? TAR_FILE : '\0');
     893             :         }
     894             : 
     895           1 :         entry->offset = 0;
     896           1 :         entry->fp = fp;
     897           1 :         entry->fp_type = PHAR_MOD;
     898           1 :         entry->is_modified = 1;
     899           1 :         return SUCCESS;
     900             : }
     901             : /* }}} */
     902             : 
     903             : /**
     904             :  * helper function to open an internal file's fp just-in-time
     905             :  */
     906           1 : phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, char **error) /* {{{ */
     907             : {
     908           1 :         if (error) {
     909           1 :                 *error = NULL;
     910             :         }
     911             :         /* seek to start of internal file and read it */
     912           1 :         if (FAILURE == phar_open_entry_fp(entry, error, 1)) {
     913           1 :                 return NULL;
     914             :         }
     915           0 :         if (-1 == phar_seek_efp(entry, 0, SEEK_SET, 0, 1)) {
     916           0 :                 spprintf(error, 4096, "phar error: cannot seek to start of file \"%s\" in phar \"%s\"", entry->filename, phar->fname);
     917           0 :                 return NULL;
     918             :         }
     919           0 :         return entry;
     920             : }
     921             : /* }}} */
     922             : 
     923           0 : PHP_PHAR_API int phar_resolve_alias(char *alias, int alias_len, char **filename, int *filename_len) /* {{{ */ {
     924             :         phar_archive_data *fd_ptr;
     925           0 :         if (PHAR_G(phar_alias_map.u.flags)
     926           0 :                         && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) {
     927           0 :                 *filename = fd_ptr->fname;
     928           0 :                 *filename_len = fd_ptr->fname_len;
     929           0 :                 return SUCCESS;
     930             :         }
     931           0 :         return FAILURE;
     932             : }
     933             : /* }}} */
     934             : 
     935          16 : int phar_free_alias(phar_archive_data *phar, char *alias, int alias_len) /* {{{ */
     936             : {
     937          16 :         if (phar->refcount || phar->is_persistent) {
     938          13 :                 return FAILURE;
     939             :         }
     940             : 
     941             :         /* this archive has no open references, so emit an E_STRICT and remove it */
     942           3 :         if (zend_hash_str_del(&(PHAR_G(phar_fname_map)), phar->fname, phar->fname_len) != SUCCESS) {
     943           0 :                 return FAILURE;
     944             :         }
     945             : 
     946             :         /* invalidate phar cache */
     947           3 :         PHAR_G(last_phar) = NULL;
     948           3 :         PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
     949             : 
     950           3 :         return SUCCESS;
     951             : }
     952             : /* }}} */
     953             : 
     954             : /**
     955             :  * Looks up a phar archive in the filename map, connecting it to the alias
     956             :  * (if any) or returns null
     957             :  */
     958       20032 : int phar_get_archive(phar_archive_data **archive, char *fname, int fname_len, char *alias, int alias_len, char **error) /* {{{ */
     959             : {
     960             :         phar_archive_data *fd, *fd_ptr;
     961             :         char *my_realpath, *save;
     962             :         int save_len;
     963             : 
     964       20032 :         phar_request_initialize();
     965             : 
     966       20032 :         if (error) {
     967       19447 :                 *error = NULL;
     968             :         }
     969             : 
     970       20032 :         *archive = NULL;
     971             : 
     972       20032 :         if (PHAR_G(last_phar) && fname_len == PHAR_G(last_phar_name_len) && !memcmp(fname, PHAR_G(last_phar_name), fname_len)) {
     973       18300 :                 *archive = PHAR_G(last_phar);
     974       18300 :                 if (alias && alias_len) {
     975             : 
     976         175 :                         if (!PHAR_G(last_phar)->is_temporary_alias && (alias_len != PHAR_G(last_phar)->alias_len || memcmp(PHAR_G(last_phar)->alias, alias, alias_len))) {
     977           3 :                                 if (error) {
     978           3 :                                         spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, PHAR_G(last_phar)->fname, fname);
     979             :                                 }
     980           3 :                                 *archive = NULL;
     981           3 :                                 return FAILURE;
     982             :                         }
     983             : 
     984         344 :                         if (PHAR_G(last_phar)->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len))) {
     985         135 :                                 zend_hash_str_del(&(PHAR_G(phar_alias_map)), PHAR_G(last_phar)->alias, PHAR_G(last_phar)->alias_len);
     986             :                         }
     987             : 
     988         172 :                         zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, *archive);
     989         172 :                         PHAR_G(last_alias) = alias;
     990         172 :                         PHAR_G(last_alias_len) = alias_len;
     991             :                 }
     992             : 
     993       18297 :                 return SUCCESS;
     994             :         }
     995             : 
     996        1732 :         if (alias && alias_len && PHAR_G(last_phar) && alias_len == PHAR_G(last_alias_len) && !memcmp(alias, PHAR_G(last_alias), alias_len)) {
     997           3 :                 fd = PHAR_G(last_phar);
     998           3 :                 fd_ptr = fd;
     999           3 :                 goto alias_success;
    1000             :         }
    1001             : 
    1002        1729 :         if (alias && alias_len) {
    1003         256 :                 if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len))) {
    1004             : alias_success:
    1005          21 :                         if (fname && (fname_len != fd_ptr->fname_len || strncmp(fname, fd_ptr->fname, fname_len))) {
    1006           5 :                                 if (error) {
    1007           5 :                                         spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname);
    1008             :                                 }
    1009           5 :                                 if (SUCCESS == phar_free_alias(fd_ptr, alias, alias_len)) {
    1010           0 :                                         if (error) {
    1011           0 :                                                 efree(*error);
    1012           0 :                                                 *error = NULL;
    1013             :                                         }
    1014             :                                 }
    1015           5 :                                 return FAILURE;
    1016             :                         }
    1017             : 
    1018          16 :                         *archive = fd_ptr;
    1019          16 :                         fd = fd_ptr;
    1020          16 :                         PHAR_G(last_phar) = fd;
    1021          16 :                         PHAR_G(last_phar_name) = fd->fname;
    1022          16 :                         PHAR_G(last_phar_name_len) = fd->fname_len;
    1023          16 :                         PHAR_G(last_alias) = alias;
    1024          16 :                         PHAR_G(last_alias_len) = alias_len;
    1025             : 
    1026          16 :                         return SUCCESS;
    1027             :                 }
    1028             : 
    1029         110 :                 if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, alias, alias_len))) {
    1030           0 :                         goto alias_success;
    1031             :                 }
    1032             :         }
    1033             : 
    1034        1711 :         my_realpath = NULL;
    1035        1711 :         save = fname;
    1036        1711 :         save_len = fname_len;
    1037             : 
    1038        1711 :         if (fname && fname_len) {
    1039        3422 :                 if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len))) {
    1040         787 :                         *archive = fd_ptr;
    1041         787 :                         fd = fd_ptr;
    1042             : 
    1043         787 :                         if (alias && alias_len) {
    1044          44 :                                 if (!fd->is_temporary_alias && (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len))) {
    1045           0 :                                         if (error) {
    1046           0 :                                                 spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname);
    1047             :                                         }
    1048           0 :                                         return FAILURE;
    1049             :                                 }
    1050             : 
    1051          88 :                                 if (fd->alias_len && NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len))) {
    1052           1 :                                         zend_hash_str_del(&(PHAR_G(phar_alias_map)), fd->alias, fd->alias_len);
    1053             :                                 }
    1054             : 
    1055          44 :                                 zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd);
    1056             :                         }
    1057             : 
    1058         787 :                         PHAR_G(last_phar) = fd;
    1059         787 :                         PHAR_G(last_phar_name) = fd->fname;
    1060         787 :                         PHAR_G(last_phar_name_len) = fd->fname_len;
    1061         787 :                         PHAR_G(last_alias) = fd->alias;
    1062         787 :                         PHAR_G(last_alias_len) = fd->alias_len;
    1063             : 
    1064         787 :                         return SUCCESS;
    1065             :                 }
    1066             : 
    1067        1049 :                 if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) {
    1068           3 :                         *archive = fd_ptr;
    1069           3 :                         fd = fd_ptr;
    1070             : 
    1071             :                         /* this could be problematic - alias should never be different from manifest alias
    1072             :                            for cached phars */
    1073           3 :                         if (!fd->is_temporary_alias && alias && alias_len) {
    1074           0 :                                 if (alias_len != fd->alias_len || memcmp(fd->alias, alias, alias_len)) {
    1075           0 :                                         if (error) {
    1076           0 :                                                 spprintf(error, 0, "alias \"%s\" is already used for archive \"%s\" cannot be overloaded with \"%s\"", alias, fd_ptr->fname, fname);
    1077             :                                         }
    1078           0 :                                         return FAILURE;
    1079             :                                 }
    1080             :                         }
    1081             : 
    1082           3 :                         PHAR_G(last_phar) = fd;
    1083           3 :                         PHAR_G(last_phar_name) = fd->fname;
    1084           3 :                         PHAR_G(last_phar_name_len) = fd->fname_len;
    1085           3 :                         PHAR_G(last_alias) = fd->alias;
    1086           3 :                         PHAR_G(last_alias_len) = fd->alias_len;
    1087             : 
    1088           3 :                         return SUCCESS;
    1089             :                 }
    1090             : 
    1091        1842 :                 if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_alias_map)), save, save_len))) {
    1092         130 :                         fd = *archive = fd_ptr;
    1093             : 
    1094         130 :                         PHAR_G(last_phar) = fd;
    1095         130 :                         PHAR_G(last_phar_name) = fd->fname;
    1096         130 :                         PHAR_G(last_phar_name_len) = fd->fname_len;
    1097         130 :                         PHAR_G(last_alias) = fd->alias;
    1098         130 :                         PHAR_G(last_alias_len) = fd->alias_len;
    1099             : 
    1100         130 :                         return SUCCESS;
    1101             :                 }
    1102             : 
    1103         913 :                 if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_alias, save, save_len))) {
    1104           0 :                         fd = *archive = fd_ptr;
    1105             : 
    1106           0 :                         PHAR_G(last_phar) = fd;
    1107           0 :                         PHAR_G(last_phar_name) = fd->fname;
    1108           0 :                         PHAR_G(last_phar_name_len) = fd->fname_len;
    1109           0 :                         PHAR_G(last_alias) = fd->alias;
    1110           0 :                         PHAR_G(last_alias_len) = fd->alias_len;
    1111             : 
    1112           0 :                         return SUCCESS;
    1113             :                 }
    1114             : 
    1115             :                 /* not found, try converting \ to / */
    1116         791 :                 my_realpath = expand_filepath(fname, my_realpath);
    1117             : 
    1118         791 :                 if (my_realpath) {
    1119         791 :                         fname_len = strlen(my_realpath);
    1120         791 :                         fname = my_realpath;
    1121             :                 } else {
    1122           0 :                         return FAILURE;
    1123             :                 }
    1124             : #ifdef PHP_WIN32
    1125             :                 phar_unixify_path_separators(fname, fname_len);
    1126             : #endif
    1127             : 
    1128        1582 :                 if (NULL != (fd_ptr = zend_hash_str_find_ptr(&(PHAR_G(phar_fname_map)), fname, fname_len))) {
    1129             : realpath_success:
    1130          15 :                         *archive = fd_ptr;
    1131          15 :                         fd = fd_ptr;
    1132             : 
    1133          15 :                         if (alias && alias_len) {
    1134           0 :                                 zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), alias, alias_len, fd);
    1135             :                         }
    1136             : 
    1137          15 :                         efree(my_realpath);
    1138             : 
    1139          15 :                         PHAR_G(last_phar) = fd;
    1140          15 :                         PHAR_G(last_phar_name) = fd->fname;
    1141          15 :                         PHAR_G(last_phar_name_len) = fd->fname_len;
    1142          15 :                         PHAR_G(last_alias) = fd->alias;
    1143          15 :                         PHAR_G(last_alias_len) = fd->alias_len;
    1144             : 
    1145          15 :                         return SUCCESS;
    1146             :                 }
    1147             : 
    1148         898 :                 if (PHAR_G(manifest_cached) && NULL != (fd_ptr = zend_hash_str_find_ptr(&cached_phars, fname, fname_len))) {
    1149           0 :                         goto realpath_success;
    1150             :                 }
    1151             : 
    1152         776 :                 efree(my_realpath);
    1153             :         }
    1154             : 
    1155         776 :         return FAILURE;
    1156             : }
    1157             : /* }}} */
    1158             : 
    1159             : /**
    1160             :  * Determine which stream compression filter (if any) we need to read this file
    1161             :  */
    1162          49 : char * phar_compress_filter(phar_entry_info * entry, int return_unknown) /* {{{ */
    1163             : {
    1164          49 :         switch (entry->flags & PHAR_ENT_COMPRESSION_MASK) {
    1165             :         case PHAR_ENT_COMPRESSED_GZ:
    1166          33 :                 return "zlib.deflate";
    1167             :         case PHAR_ENT_COMPRESSED_BZ2:
    1168          16 :                 return "bzip2.compress";
    1169             :         default:
    1170           0 :                 return return_unknown ? "unknown" : NULL;
    1171             :         }
    1172             : }
    1173             : /* }}} */
    1174             : 
    1175             : /**
    1176             :  * Determine which stream decompression filter (if any) we need to read this file
    1177             :  */
    1178          41 : char * phar_decompress_filter(phar_entry_info * entry, int return_unknown) /* {{{ */
    1179             : {
    1180             :         uint32_t flags;
    1181             : 
    1182          41 :         if (entry->is_modified) {
    1183           0 :                 flags = entry->old_flags;
    1184             :         } else {
    1185          41 :                 flags = entry->flags;
    1186             :         }
    1187             : 
    1188          41 :         switch (flags & PHAR_ENT_COMPRESSION_MASK) {
    1189             :                 case PHAR_ENT_COMPRESSED_GZ:
    1190          28 :                         return "zlib.inflate";
    1191             :                 case PHAR_ENT_COMPRESSED_BZ2:
    1192          13 :                         return "bzip2.decompress";
    1193             :                 default:
    1194           0 :                         return return_unknown ? "unknown" : NULL;
    1195             :         }
    1196             : }
    1197             : /* }}} */
    1198             : 
    1199             : /**
    1200             :  * retrieve information on a file contained within a phar, or null if it ain't there
    1201             :  */
    1202        8280 : phar_entry_info *phar_get_entry_info(phar_archive_data *phar, char *path, int path_len, char **error, int security) /* {{{ */
    1203             : {
    1204        8280 :         return phar_get_entry_info_dir(phar, path, path_len, 0, error, security);
    1205             : }
    1206             : /* }}} */
    1207             : /**
    1208             :  * retrieve information on a file or directory contained within a phar, or null if none found
    1209             :  * allow_dir is 0 for none, 1 for both empty directories in the phar and temp directories, and 2 for only
    1210             :  * valid pre-existing empty directory entries
    1211             :  */
    1212        9065 : phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, int path_len, char dir, char **error, int security) /* {{{ */
    1213             : {
    1214             :         const char *pcr_error;
    1215             :         phar_entry_info *entry;
    1216             :         int is_dir;
    1217             : 
    1218             : #ifdef PHP_WIN32
    1219             :         phar_unixify_path_separators(path, path_len);
    1220             : #endif
    1221             : 
    1222        9065 :         is_dir = (path_len && (path[path_len - 1] == '/')) ? 1 : 0;
    1223             : 
    1224        9065 :         if (error) {
    1225        1333 :                 *error = NULL;
    1226             :         }
    1227             : 
    1228        9065 :         if (security && path_len >= (int)sizeof(".phar")-1 && !memcmp(path, ".phar", sizeof(".phar")-1)) {
    1229           1 :                 if (error) {
    1230           0 :                         spprintf(error, 4096, "phar error: cannot directly access magic \".phar\" directory or files within it");
    1231             :                 }
    1232           1 :                 return NULL;
    1233             :         }
    1234             : 
    1235        9064 :         if (!path_len && !dir) {
    1236           2 :                 if (error) {
    1237           2 :                         spprintf(error, 4096, "phar error: invalid path \"%s\" must not be empty", path);
    1238             :                 }
    1239           2 :                 return NULL;
    1240             :         }
    1241             : 
    1242        9062 :         if (phar_path_check(&path, &path_len, &pcr_error) > pcr_is_ok) {
    1243           7 :                 if (error) {
    1244           0 :                         spprintf(error, 4096, "phar error: invalid path \"%s\" contains %s", path, pcr_error);
    1245             :                 }
    1246           7 :                 return NULL;
    1247             :         }
    1248             : 
    1249        9055 :         if (!phar->manifest.u.flags) {
    1250           0 :                 return NULL;
    1251             :         }
    1252             : 
    1253        9055 :         if (is_dir) {
    1254           5 :                 if (!path_len || path_len == 1) {
    1255           0 :                         return NULL;
    1256             :                 }
    1257           5 :                 path_len--;
    1258             :         }
    1259             : 
    1260       18110 :         if (NULL != (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) {
    1261        5454 :                 if (entry->is_deleted) {
    1262             :                         /* entry is deleted, but has not been flushed to disk yet */
    1263           0 :                         return NULL;
    1264             :                 }
    1265        5454 :                 if (entry->is_dir && !dir) {
    1266           1 :                         if (error) {
    1267           1 :                                 spprintf(error, 4096, "phar error: path \"%s\" is a directory", path);
    1268             :                         }
    1269           1 :                         return NULL;
    1270             :                 }
    1271        5453 :                 if (!entry->is_dir && dir == 2) {
    1272             :                         /* user requested a directory, we must return one */
    1273           3 :                         if (error) {
    1274           3 :                                 spprintf(error, 4096, "phar error: path \"%s\" exists and is a not a directory", path);
    1275             :                         }
    1276           3 :                         return NULL;
    1277             :                 }
    1278        5450 :                 return entry;
    1279             :         }
    1280             : 
    1281        3601 :         if (dir) {
    1282          53 :                 if (zend_hash_str_exists(&phar->virtual_dirs, path, path_len)) {
    1283             :                         /* a file or directory exists in a sub-directory of this path */
    1284          20 :                         entry = (phar_entry_info *) ecalloc(1, sizeof(phar_entry_info));
    1285             :                         /* this next line tells PharFileInfo->__destruct() to efree the filename */
    1286          20 :                         entry->is_temp_dir = entry->is_dir = 1;
    1287          20 :                         entry->filename = (char *) estrndup(path, path_len + 1);
    1288          20 :                         entry->filename_len = path_len;
    1289          20 :                         entry->phar = phar;
    1290          20 :                         return entry;
    1291             :                 }
    1292             :         }
    1293             : 
    1294        3581 :         if (phar->mounted_dirs.u.flags && zend_hash_num_elements(&phar->mounted_dirs)) {
    1295             :                 zend_string *str_key;
    1296             : 
    1297           6 :                 ZEND_HASH_FOREACH_STR_KEY(&phar->mounted_dirs, str_key) {
    1298           3 :                         if ((int)ZSTR_LEN(str_key) >= path_len || strncmp(ZSTR_VAL(str_key), path, ZSTR_LEN(str_key))) {
    1299           0 :                                 continue;
    1300             :                         } else {
    1301             :                                 char *test;
    1302             :                                 int test_len;
    1303             :                                 php_stream_statbuf ssb;
    1304             : 
    1305           6 :                                 if (NULL == (entry = zend_hash_find_ptr(&phar->manifest, str_key))) {
    1306           0 :                                         if (error) {
    1307           0 :                                                 spprintf(error, 4096, "phar internal error: mounted path \"%s\" could not be retrieved from manifest", ZSTR_VAL(str_key));
    1308             :                                         }
    1309           0 :                                         return NULL;
    1310             :                                 }
    1311             : 
    1312           3 :                                 if (!entry->tmp || !entry->is_mounted) {
    1313           0 :                                         if (error) {
    1314           0 :                                                 spprintf(error, 4096, "phar internal error: mounted path \"%s\" is not properly initialized as a mounted path", ZSTR_VAL(str_key));
    1315             :                                         }
    1316           0 :                                         return NULL;
    1317             :                                 }
    1318             : 
    1319           3 :                                 test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, path + ZSTR_LEN(str_key));
    1320             : 
    1321           3 :                                 if (SUCCESS != php_stream_stat_path(test, &ssb)) {
    1322           0 :                                         efree(test);
    1323           0 :                                         return NULL;
    1324             :                                 }
    1325             : 
    1326           3 :                                 if (ssb.sb.st_mode & S_IFDIR && !dir) {
    1327           1 :                                         efree(test);
    1328           1 :                                         if (error) {
    1329           1 :                                                 spprintf(error, 4096, "phar error: path \"%s\" is a directory", path);
    1330             :                                         }
    1331           1 :                                         return NULL;
    1332             :                                 }
    1333             : 
    1334           2 :                                 if ((ssb.sb.st_mode & S_IFDIR) == 0 && dir) {
    1335           0 :                                         efree(test);
    1336             :                                         /* user requested a directory, we must return one */
    1337           0 :                                         if (error) {
    1338           0 :                                                 spprintf(error, 4096, "phar error: path \"%s\" exists and is a not a directory", path);
    1339             :                                         }
    1340           0 :                                         return NULL;
    1341             :                                 }
    1342             : 
    1343             :                                 /* mount the file just in time */
    1344           2 :                                 if (SUCCESS != phar_mount_entry(phar, test, test_len, path, path_len)) {
    1345           0 :                                         efree(test);
    1346           0 :                                         if (error) {
    1347           0 :                                                 spprintf(error, 4096, "phar error: path \"%s\" exists as file \"%s\" and could not be mounted", path, test);
    1348             :                                         }
    1349           0 :                                         return NULL;
    1350             :                                 }
    1351             : 
    1352           2 :                                 efree(test);
    1353             : 
    1354           4 :                                 if (NULL == (entry = zend_hash_str_find_ptr(&phar->manifest, path, path_len))) {
    1355           0 :                                         if (error) {
    1356           0 :                                                 spprintf(error, 4096, "phar error: path \"%s\" exists as file \"%s\" and could not be retrieved after being mounted", path, test);
    1357             :                                         }
    1358           0 :                                         return NULL;
    1359             :                                 }
    1360           2 :                                 return entry;
    1361             :                         }
    1362             :                 } ZEND_HASH_FOREACH_END();
    1363             :         }
    1364             : 
    1365        3578 :         return NULL;
    1366             : }
    1367             : /* }}} */
    1368             : 
    1369             : static const char hexChars[] = "0123456789ABCDEF";
    1370             : 
    1371        5113 : static int phar_hex_str(const char *digest, size_t digest_len, char **signature) /* {{{ */
    1372             : {
    1373        5113 :         int pos = -1;
    1374        5113 :         size_t len = 0;
    1375             : 
    1376        5113 :         *signature = (char*)safe_pemalloc(digest_len, 2, 1, PHAR_G(persist));
    1377             : 
    1378      108401 :         for (; len < digest_len; ++len) {
    1379      103288 :                 (*signature)[++pos] = hexChars[((const unsigned char *)digest)[len] >> 4];
    1380      103288 :                 (*signature)[++pos] = hexChars[((const unsigned char *)digest)[len] & 0x0F];
    1381             :         }
    1382        5113 :         (*signature)[++pos] = '\0';
    1383        5113 :         return pos;
    1384             : }
    1385             : /* }}} */
    1386             : 
    1387             : #ifndef PHAR_HAVE_OPENSSL
    1388             : static int phar_call_openssl_signverify(int is_sign, php_stream *fp, zend_off_t end, char *key, int key_len, char **signature, int *signature_len) /* {{{ */
    1389             : {
    1390             :         zend_fcall_info fci;
    1391             :         zend_fcall_info_cache fcc;
    1392             :         zval retval, zp[3], openssl;
    1393             :         zend_string *str;
    1394             : 
    1395             :         ZVAL_STRINGL(&openssl, is_sign ? "openssl_sign" : "openssl_verify", is_sign ? sizeof("openssl_sign")-1 : sizeof("openssl_verify")-1);
    1396             :         ZVAL_STRINGL(&zp[1], *signature, *signature_len);
    1397             :         ZVAL_STRINGL(&zp[2], key, key_len);
    1398             :         php_stream_rewind(fp);
    1399             :         str = php_stream_copy_to_mem(fp, (size_t) end, 0);
    1400             :         if (str) {
    1401             :                 ZVAL_STR(&zp[0], str);
    1402             :         } else {
    1403             :                 ZVAL_EMPTY_STRING(&zp[0]);
    1404             :         }
    1405             : 
    1406             :         if ((size_t)end != Z_STRLEN(zp[0])) {
    1407             :                 zval_dtor(&zp[0]);
    1408             :                 zval_dtor(&zp[1]);
    1409             :                 zval_dtor(&zp[2]);
    1410             :                 zval_dtor(&openssl);
    1411             :                 return FAILURE;
    1412             :         }
    1413             : 
    1414             :         if (FAILURE == zend_fcall_info_init(&openssl, 0, &fci, &fcc, NULL, NULL)) {
    1415             :                 zval_dtor(&zp[0]);
    1416             :                 zval_dtor(&zp[1]);
    1417             :                 zval_dtor(&zp[2]);
    1418             :                 zval_dtor(&openssl);
    1419             :                 return FAILURE;
    1420             :         }
    1421             : 
    1422             :         fci.param_count = 3;
    1423             :         fci.params = zp;
    1424             :         Z_ADDREF(zp[0]);
    1425             :         if (is_sign) {
    1426             :                 ZVAL_NEW_REF(&zp[1], &zp[1]);
    1427             :         } else {
    1428             :                 Z_ADDREF(zp[1]);
    1429             :         }
    1430             :         Z_ADDREF(zp[2]);
    1431             : 
    1432             :         fci.retval = &retval;
    1433             : 
    1434             :         if (FAILURE == zend_call_function(&fci, &fcc)) {
    1435             :                 zval_dtor(&zp[0]);
    1436             :                 zval_dtor(&zp[1]);
    1437             :                 zval_dtor(&zp[2]);
    1438             :                 zval_dtor(&openssl);
    1439             :                 return FAILURE;
    1440             :         }
    1441             : 
    1442             :         zval_dtor(&openssl);
    1443             :         Z_DELREF(zp[0]);
    1444             : 
    1445             :         if (is_sign) {
    1446             :                 ZVAL_UNREF(&zp[1]);
    1447             :         } else {
    1448             :                 Z_DELREF(zp[1]);
    1449             :         }
    1450             :         Z_DELREF(zp[2]);
    1451             : 
    1452             :         zval_dtor(&zp[0]);
    1453             :         zval_dtor(&zp[2]);
    1454             : 
    1455             :         switch (Z_TYPE(retval)) {
    1456             :                 default:
    1457             :                 case IS_LONG:
    1458             :                         zval_dtor(&zp[1]);
    1459             :                         if (1 == Z_LVAL(retval)) {
    1460             :                                 return SUCCESS;
    1461             :                         }
    1462             :                         return FAILURE;
    1463             :                 case IS_TRUE:
    1464             :                         *signature = estrndup(Z_STRVAL(zp[1]), Z_STRLEN(zp[1]));
    1465             :                         *signature_len = Z_STRLEN(zp[1]);
    1466             :                         zval_dtor(&zp[1]);
    1467             :                         return SUCCESS;
    1468             :                 case IS_FALSE:
    1469             :                         zval_dtor(&zp[1]);
    1470             :                         return FAILURE;
    1471             :         }
    1472             : }
    1473             : /* }}} */
    1474             : #endif /* #ifndef PHAR_HAVE_OPENSSL */
    1475             : 
    1476         236 : int phar_verify_signature(php_stream *fp, size_t end_of_phar, uint32_t sig_type, char *sig, int sig_len, char *fname, char **signature, int *signature_len, char **error) /* {{{ */
    1477             : {
    1478             :         int read_size, len;
    1479             :         zend_off_t read_len;
    1480             :         unsigned char buf[1024];
    1481             : 
    1482         236 :         php_stream_rewind(fp);
    1483             : 
    1484         236 :         switch (sig_type) {
    1485             :                 case PHAR_SIG_OPENSSL: {
    1486             : #ifdef PHAR_HAVE_OPENSSL
    1487             :                         BIO *in;
    1488             :                         EVP_PKEY *key;
    1489           3 :                         EVP_MD *mdtype = (EVP_MD *) EVP_sha1();
    1490             :                         EVP_MD_CTX *md_ctx;
    1491             : #else
    1492             :                         int tempsig;
    1493             : #endif
    1494           3 :                         zend_string *pubkey = NULL;
    1495             :                         char *pfile;
    1496             :                         php_stream *pfp;
    1497             : #ifndef PHAR_HAVE_OPENSSL
    1498             :                         if (!zend_hash_str_exists(&module_registry, "openssl", sizeof("openssl")-1)) {
    1499             :                                 if (error) {
    1500             :                                         spprintf(error, 0, "openssl not loaded");
    1501             :                                 }
    1502             :                                 return FAILURE;
    1503             :                         }
    1504             : #endif
    1505             :                         /* use __FILE__ . '.pubkey' for public key file */
    1506           3 :                         spprintf(&pfile, 0, "%s.pubkey", fname);
    1507           3 :                         pfp = php_stream_open_wrapper(pfile, "rb", 0, NULL);
    1508           3 :                         efree(pfile);
    1509             : 
    1510           3 :                         if (!pfp || !(pubkey = php_stream_copy_to_mem(pfp, PHP_STREAM_COPY_ALL, 0)) || !ZSTR_LEN(pubkey)) {
    1511           0 :                                 if (pfp) {
    1512           0 :                                         php_stream_close(pfp);
    1513             :                                 }
    1514           0 :                                 if (error) {
    1515           0 :                                         spprintf(error, 0, "openssl public key could not be read");
    1516             :                                 }
    1517           0 :                                 return FAILURE;
    1518             :                         }
    1519             : 
    1520           3 :                         php_stream_close(pfp);
    1521             : #ifndef PHAR_HAVE_OPENSSL
    1522             :                         tempsig = sig_len;
    1523             : 
    1524             :                         if (FAILURE == phar_call_openssl_signverify(0, fp, end_of_phar, pubkey ? ZSTR_VAL(pubkey) : NULL, pubkey ? ZSTR_LEN(pubkey) : 0, &sig, &tempsig)) {
    1525             :                                 if (pubkey) {
    1526             :                                         zend_string_release(pubkey);
    1527             :                                 }
    1528             : 
    1529             :                                 if (error) {
    1530             :                                         spprintf(error, 0, "openssl signature could not be verified");
    1531             :                                 }
    1532             : 
    1533             :                                 return FAILURE;
    1534             :                         }
    1535             : 
    1536             :                         if (pubkey) {
    1537             :                                 zend_string_release(pubkey);
    1538             :                         }
    1539             : 
    1540             :                         sig_len = tempsig;
    1541             : #else
    1542           3 :                         in = BIO_new_mem_buf(pubkey ? ZSTR_VAL(pubkey) : NULL, pubkey ? ZSTR_LEN(pubkey) : 0);
    1543             : 
    1544           3 :                         if (NULL == in) {
    1545             :                                 zend_string_release(pubkey);
    1546           0 :                                 if (error) {
    1547           0 :                                         spprintf(error, 0, "openssl signature could not be processed");
    1548             :                                 }
    1549           0 :                                 return FAILURE;
    1550             :                         }
    1551             : 
    1552           3 :                         key = PEM_read_bio_PUBKEY(in, NULL,NULL, NULL);
    1553           3 :                         BIO_free(in);
    1554             :                         zend_string_release(pubkey);
    1555             : 
    1556           3 :                         if (NULL == key) {
    1557           0 :                                 if (error) {
    1558           0 :                                         spprintf(error, 0, "openssl signature could not be processed");
    1559             :                                 }
    1560           0 :                                 return FAILURE;
    1561             :                         }
    1562             : 
    1563           3 :                         md_ctx = EVP_MD_CTX_create();
    1564           3 :                         EVP_VerifyInit(md_ctx, mdtype);
    1565           3 :                         read_len = end_of_phar;
    1566             : 
    1567           3 :                         if ((size_t)read_len > sizeof(buf)) {
    1568           2 :                                 read_size = sizeof(buf);
    1569             :                         } else {
    1570           1 :                                 read_size = (int)read_len;
    1571             :                         }
    1572             : 
    1573           3 :                         php_stream_seek(fp, 0, SEEK_SET);
    1574             : 
    1575          22 :                         while (read_size && (len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
    1576          16 :                                 EVP_VerifyUpdate (md_ctx, buf, len);
    1577          16 :                                 read_len -= (zend_off_t)len;
    1578             : 
    1579          16 :                                 if (read_len < read_size) {
    1580           5 :                                         read_size = (int)read_len;
    1581             :                                 }
    1582             :                         }
    1583             : 
    1584           3 :                         if (EVP_VerifyFinal(md_ctx, (unsigned char *)sig, sig_len, key) != 1) {
    1585             :                                 /* 1: signature verified, 0: signature does not match, -1: failed signature operation */
    1586           0 :                                 EVP_MD_CTX_destroy(md_ctx);
    1587             : 
    1588           0 :                                 if (error) {
    1589           0 :                                         spprintf(error, 0, "broken openssl signature");
    1590             :                                 }
    1591             : 
    1592           0 :                                 return FAILURE;
    1593             :                         }
    1594             : 
    1595           3 :                         EVP_MD_CTX_destroy(md_ctx);
    1596             : #endif
    1597             : 
    1598           3 :                         *signature_len = phar_hex_str((const char*)sig, sig_len, signature);
    1599             :                 }
    1600           3 :                 break;
    1601             : #ifdef PHAR_HASH_OK
    1602             :                 case PHAR_SIG_SHA512: {
    1603             :                         unsigned char digest[64];
    1604             :                         PHP_SHA512_CTX context;
    1605             : 
    1606           2 :                         PHP_SHA512Init(&context);
    1607           2 :                         read_len = end_of_phar;
    1608             : 
    1609           2 :                         if ((size_t)read_len > sizeof(buf)) {
    1610           0 :                                 read_size = sizeof(buf);
    1611             :                         } else {
    1612           2 :                                 read_size = (int)read_len;
    1613             :                         }
    1614             : 
    1615           6 :                         while ((len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
    1616           2 :                                 PHP_SHA512Update(&context, buf, len);
    1617           2 :                                 read_len -= (zend_off_t)len;
    1618           2 :                                 if (read_len < read_size) {
    1619           2 :                                         read_size = (int)read_len;
    1620             :                                 }
    1621             :                         }
    1622             : 
    1623           2 :                         PHP_SHA512Final(digest, &context);
    1624             : 
    1625           2 :                         if (memcmp(digest, sig, sizeof(digest))) {
    1626           0 :                                 if (error) {
    1627           0 :                                         spprintf(error, 0, "broken signature");
    1628             :                                 }
    1629           0 :                                 return FAILURE;
    1630             :                         }
    1631             : 
    1632           2 :                         *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature);
    1633           2 :                         break;
    1634             :                 }
    1635             :                 case PHAR_SIG_SHA256: {
    1636             :                         unsigned char digest[32];
    1637             :                         PHP_SHA256_CTX context;
    1638             : 
    1639           2 :                         PHP_SHA256Init(&context);
    1640           2 :                         read_len = end_of_phar;
    1641             : 
    1642           2 :                         if ((size_t)read_len > sizeof(buf)) {
    1643           0 :                                 read_size = sizeof(buf);
    1644             :                         } else {
    1645           2 :                                 read_size = (int)read_len;
    1646             :                         }
    1647             : 
    1648           6 :                         while ((len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
    1649           2 :                                 PHP_SHA256Update(&context, buf, len);
    1650           2 :                                 read_len -= (zend_off_t)len;
    1651           2 :                                 if (read_len < read_size) {
    1652           2 :                                         read_size = (int)read_len;
    1653             :                                 }
    1654             :                         }
    1655             : 
    1656           2 :                         PHP_SHA256Final(digest, &context);
    1657             : 
    1658           2 :                         if (memcmp(digest, sig, sizeof(digest))) {
    1659           0 :                                 if (error) {
    1660           0 :                                         spprintf(error, 0, "broken signature");
    1661             :                                 }
    1662           0 :                                 return FAILURE;
    1663             :                         }
    1664             : 
    1665           2 :                         *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature);
    1666           2 :                         break;
    1667             :                 }
    1668             : #else
    1669             :                 case PHAR_SIG_SHA512:
    1670             :                 case PHAR_SIG_SHA256:
    1671             :                         if (error) {
    1672             :                                 spprintf(error, 0, "unsupported signature");
    1673             :                         }
    1674             :                         return FAILURE;
    1675             : #endif
    1676             :                 case PHAR_SIG_SHA1: {
    1677             :                         unsigned char digest[20];
    1678             :                         PHP_SHA1_CTX  context;
    1679             : 
    1680         227 :                         PHP_SHA1Init(&context);
    1681         227 :                         read_len = end_of_phar;
    1682             : 
    1683         227 :                         if ((size_t)read_len > sizeof(buf)) {
    1684          99 :                                 read_size = sizeof(buf);
    1685             :                         } else {
    1686         128 :                                 read_size = (int)read_len;
    1687             :                         }
    1688             : 
    1689        1681 :                         while ((len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
    1690        1227 :                                 PHP_SHA1Update(&context, buf, len);
    1691        1227 :                                 read_len -= (zend_off_t)len;
    1692        1227 :                                 if (read_len < read_size) {
    1693         292 :                                         read_size = (int)read_len;
    1694             :                                 }
    1695             :                         }
    1696             : 
    1697         227 :                         PHP_SHA1Final(digest, &context);
    1698             : 
    1699         227 :                         if (memcmp(digest, sig, sizeof(digest))) {
    1700           0 :                                 if (error) {
    1701           0 :                                         spprintf(error, 0, "broken signature");
    1702             :                                 }
    1703           0 :                                 return FAILURE;
    1704             :                         }
    1705             : 
    1706         227 :                         *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature);
    1707         227 :                         break;
    1708             :                 }
    1709             :                 case PHAR_SIG_MD5: {
    1710             :                         unsigned char digest[16];
    1711             :                         PHP_MD5_CTX   context;
    1712             : 
    1713           2 :                         PHP_MD5Init(&context);
    1714           2 :                         read_len = end_of_phar;
    1715             : 
    1716           2 :                         if ((size_t)read_len > sizeof(buf)) {
    1717           0 :                                 read_size = sizeof(buf);
    1718             :                         } else {
    1719           2 :                                 read_size = (int)read_len;
    1720             :                         }
    1721             : 
    1722           6 :                         while ((len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
    1723           2 :                                 PHP_MD5Update(&context, buf, len);
    1724           2 :                                 read_len -= (zend_off_t)len;
    1725           2 :                                 if (read_len < read_size) {
    1726           2 :                                         read_size = (int)read_len;
    1727             :                                 }
    1728             :                         }
    1729             : 
    1730           2 :                         PHP_MD5Final(digest, &context);
    1731             : 
    1732           2 :                         if (memcmp(digest, sig, sizeof(digest))) {
    1733           0 :                                 if (error) {
    1734           0 :                                         spprintf(error, 0, "broken signature");
    1735             :                                 }
    1736           0 :                                 return FAILURE;
    1737             :                         }
    1738             : 
    1739           2 :                         *signature_len = phar_hex_str((const char*)digest, sizeof(digest), signature);
    1740           2 :                         break;
    1741             :                 }
    1742             :                 default:
    1743           0 :                         if (error) {
    1744           0 :                                 spprintf(error, 0, "broken or unsupported signature");
    1745             :                         }
    1746           0 :                         return FAILURE;
    1747             :         }
    1748         236 :         return SUCCESS;
    1749             : }
    1750             : /* }}} */
    1751             : 
    1752        4877 : int phar_create_signature(phar_archive_data *phar, php_stream *fp, char **signature, int *signature_length, char **error) /* {{{ */
    1753             : {
    1754             :         unsigned char buf[1024];
    1755             :         int sig_len;
    1756             : 
    1757        4877 :         php_stream_rewind(fp);
    1758             : 
    1759        4877 :         if (phar->signature) {
    1760         272 :                 efree(phar->signature);
    1761         272 :                 phar->signature = NULL;
    1762             :         }
    1763             : 
    1764        4877 :         switch(phar->sig_flags) {
    1765             : #ifdef PHAR_HASH_OK
    1766             :                 case PHAR_SIG_SHA512: {
    1767             :                         unsigned char digest[64];
    1768             :                         PHP_SHA512_CTX context;
    1769             : 
    1770           3 :                         PHP_SHA512Init(&context);
    1771             : 
    1772          16 :                         while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
    1773          10 :                                 PHP_SHA512Update(&context, buf, sig_len);
    1774             :                         }
    1775             : 
    1776           3 :                         PHP_SHA512Final(digest, &context);
    1777           3 :                         *signature = estrndup((char *) digest, 64);
    1778           3 :                         *signature_length = 64;
    1779           3 :                         break;
    1780             :                 }
    1781             :                 case PHAR_SIG_SHA256: {
    1782             :                         unsigned char digest[32];
    1783             :                         PHP_SHA256_CTX  context;
    1784             : 
    1785           3 :                         PHP_SHA256Init(&context);
    1786             : 
    1787          16 :                         while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
    1788          10 :                                 PHP_SHA256Update(&context, buf, sig_len);
    1789             :                         }
    1790             : 
    1791           3 :                         PHP_SHA256Final(digest, &context);
    1792           3 :                         *signature = estrndup((char *) digest, 32);
    1793           3 :                         *signature_length = 32;
    1794           3 :                         break;
    1795             :                 }
    1796             : #else
    1797             :                 case PHAR_SIG_SHA512:
    1798             :                 case PHAR_SIG_SHA256:
    1799             :                         if (error) {
    1800             :                                 spprintf(error, 0, "unable to write to phar \"%s\" with requested hash type", phar->fname);
    1801             :                         }
    1802             : 
    1803             :                         return FAILURE;
    1804             : #endif
    1805             :                 case PHAR_SIG_OPENSSL: {
    1806             :                         int siglen;
    1807             :                         unsigned char *sigbuf;
    1808             : #ifdef PHAR_HAVE_OPENSSL
    1809             :                         BIO *in;
    1810             :                         EVP_PKEY *key;
    1811             :                         EVP_MD_CTX *md_ctx;
    1812             : 
    1813           3 :                         in = BIO_new_mem_buf(PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len));
    1814             : 
    1815           3 :                         if (in == NULL) {
    1816           0 :                                 if (error) {
    1817           0 :                                         spprintf(error, 0, "unable to write to phar \"%s\" with requested openssl signature", phar->fname);
    1818             :                                 }
    1819           0 :                                 return FAILURE;
    1820             :                         }
    1821             : 
    1822           3 :                         key = PEM_read_bio_PrivateKey(in, NULL,NULL, "");
    1823           3 :                         BIO_free(in);
    1824             : 
    1825           3 :                         if (!key) {
    1826           0 :                                 if (error) {
    1827           0 :                                         spprintf(error, 0, "unable to process private key");
    1828             :                                 }
    1829           0 :                                 return FAILURE;
    1830             :                         }
    1831             : 
    1832           3 :                         md_ctx = EVP_MD_CTX_create();
    1833             : 
    1834           3 :                         siglen = EVP_PKEY_size(key);
    1835           3 :                         sigbuf = emalloc(siglen + 1);
    1836             : 
    1837           3 :                         if (!EVP_SignInit(md_ctx, EVP_sha1())) {
    1838           0 :                                 efree(sigbuf);
    1839           0 :                                 if (error) {
    1840           0 :                                         spprintf(error, 0, "unable to initialize openssl signature for phar \"%s\"", phar->fname);
    1841             :                                 }
    1842           0 :                                 return FAILURE;
    1843             :                         }
    1844             : 
    1845          16 :                         while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
    1846          10 :                                 if (!EVP_SignUpdate(md_ctx, buf, sig_len)) {
    1847           0 :                                         efree(sigbuf);
    1848           0 :                                         if (error) {
    1849           0 :                                                 spprintf(error, 0, "unable to update the openssl signature for phar \"%s\"", phar->fname);
    1850             :                                         }
    1851           0 :                                         return FAILURE;
    1852             :                                 }
    1853             :                         }
    1854             : 
    1855           3 :                         if (!EVP_SignFinal (md_ctx, sigbuf,(unsigned int *)&siglen, key)) {
    1856           0 :                                 efree(sigbuf);
    1857           0 :                                 if (error) {
    1858           0 :                                         spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname);
    1859             :                                 }
    1860           0 :                                 return FAILURE;
    1861             :                         }
    1862             : 
    1863           3 :                         sigbuf[siglen] = '\0';
    1864           3 :                         EVP_MD_CTX_destroy(md_ctx);
    1865             : #else
    1866             :                         sigbuf = NULL;
    1867             :                         siglen = 0;
    1868             :                         php_stream_seek(fp, 0, SEEK_END);
    1869             : 
    1870             :                         if (FAILURE == phar_call_openssl_signverify(1, fp, php_stream_tell(fp), PHAR_G(openssl_privatekey), PHAR_G(openssl_privatekey_len), (char **)&sigbuf, &siglen)) {
    1871             :                                 if (error) {
    1872             :                                         spprintf(error, 0, "unable to write phar \"%s\" with requested openssl signature", phar->fname);
    1873             :                                 }
    1874             :                                 return FAILURE;
    1875             :                         }
    1876             : #endif
    1877           3 :                         *signature = (char *) sigbuf;
    1878           3 :                         *signature_length = siglen;
    1879             :                 }
    1880           3 :                 break;
    1881             :                 default:
    1882         170 :                         phar->sig_flags = PHAR_SIG_SHA1;
    1883             :                 case PHAR_SIG_SHA1: {
    1884             :                         unsigned char digest[20];
    1885             :                         PHP_SHA1_CTX  context;
    1886             : 
    1887        4863 :                         PHP_SHA1Init(&context);
    1888             : 
    1889       42602 :                         while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
    1890       32876 :                                 PHP_SHA1Update(&context, buf, sig_len);
    1891             :                         }
    1892             : 
    1893        4863 :                         PHP_SHA1Final(digest, &context);
    1894        4863 :                         *signature = estrndup((char *) digest, 20);
    1895        4863 :                         *signature_length = 20;
    1896        4863 :                         break;
    1897             :                 }
    1898             :                 case PHAR_SIG_MD5: {
    1899             :                         unsigned char digest[16];
    1900             :                         PHP_MD5_CTX   context;
    1901             : 
    1902           5 :                         PHP_MD5Init(&context);
    1903             : 
    1904          22 :                         while ((sig_len = php_stream_read(fp, (char*)buf, sizeof(buf))) > 0) {
    1905          12 :                                 PHP_MD5Update(&context, buf, sig_len);
    1906             :                         }
    1907             : 
    1908           5 :                         PHP_MD5Final(digest, &context);
    1909           5 :                         *signature = estrndup((char *) digest, 16);
    1910           5 :                         *signature_length = 16;
    1911             :                         break;
    1912             :                 }
    1913             :         }
    1914             : 
    1915        4877 :         phar->sig_len = phar_hex_str((const char *)*signature, *signature_length, &phar->signature);
    1916        4877 :         return SUCCESS;
    1917             : }
    1918             : /* }}} */
    1919             : 
    1920       21229 : void phar_add_virtual_dirs(phar_archive_data *phar, char *filename, int filename_len) /* {{{ */
    1921             : {
    1922             :         const char *s;
    1923             : 
    1924      120177 :         while ((s = zend_memrchr(filename, '/', filename_len))) {
    1925       35318 :                 filename_len = s - filename;
    1926       35318 :                 if (!filename_len || NULL == zend_hash_str_add_empty_element(&phar->virtual_dirs, filename, filename_len)) {
    1927             :                         break;
    1928             :                 }
    1929             :         }
    1930       21229 : }
    1931             : /* }}} */
    1932             : 
    1933           4 : static int phar_update_cached_entry(zval *data, void *argument) /* {{{ */
    1934             : {
    1935           4 :         phar_entry_info *entry = (phar_entry_info *)Z_PTR_P(data);
    1936             : 
    1937           4 :         entry->phar = (phar_archive_data *)argument;
    1938             : 
    1939           4 :         if (entry->link) {
    1940           0 :                 entry->link = estrdup(entry->link);
    1941             :         }
    1942             : 
    1943           4 :         if (entry->tmp) {
    1944           0 :                 entry->tmp = estrdup(entry->tmp);
    1945             :         }
    1946             : 
    1947           4 :         entry->metadata_str.s = NULL;
    1948           4 :         entry->filename = estrndup(entry->filename, entry->filename_len);
    1949           4 :         entry->is_persistent = 0;
    1950             : 
    1951           8 :         if (Z_TYPE(entry->metadata) != IS_UNDEF) {
    1952           3 :                 if (entry->metadata_len) {
    1953           3 :                         char *buf = estrndup((char *) Z_PTR(entry->metadata), entry->metadata_len);
    1954             :                         /* assume success, we would have failed before */
    1955           3 :                         phar_parse_metadata((char **) &buf, &entry->metadata, entry->metadata_len);
    1956           3 :                         efree(buf);
    1957             :                 } else {
    1958           0 :                         zval_copy_ctor(&entry->metadata);
    1959           0 :                         entry->metadata_str.s = NULL;
    1960             :                 }
    1961             :         }
    1962           4 :         return ZEND_HASH_APPLY_KEEP;
    1963             : }
    1964             : /* }}} */
    1965             : 
    1966           4 : static void phar_manifest_copy_ctor(zval *zv) /* {{{ */
    1967             : {
    1968           4 :         phar_entry_info *info = emalloc(sizeof(phar_entry_info));
    1969           4 :         memcpy(info, Z_PTR_P(zv), sizeof(phar_entry_info));
    1970           4 :         Z_PTR_P(zv) = info;
    1971           4 : }
    1972             : /* }}} */
    1973             : 
    1974           3 : static void phar_copy_cached_phar(phar_archive_data **pphar) /* {{{ */
    1975             : {
    1976             :         phar_archive_data *phar;
    1977             :         HashTable newmanifest;
    1978             :         char *fname;
    1979             :         phar_archive_object *objphar;
    1980             : 
    1981           3 :         phar = (phar_archive_data *) emalloc(sizeof(phar_archive_data));
    1982           3 :         *phar = **pphar;
    1983           3 :         phar->is_persistent = 0;
    1984           3 :         fname = phar->fname;
    1985           3 :         phar->fname = estrndup(phar->fname, phar->fname_len);
    1986           3 :         phar->ext = phar->fname + (phar->ext - fname);
    1987             : 
    1988           3 :         if (phar->alias) {
    1989           3 :                 phar->alias = estrndup(phar->alias, phar->alias_len);
    1990             :         }
    1991             : 
    1992           3 :         if (phar->signature) {
    1993           3 :                 phar->signature = estrdup(phar->signature);
    1994             :         }
    1995             : 
    1996           6 :         if (Z_TYPE(phar->metadata) != IS_UNDEF) {
    1997             :                 /* assume success, we would have failed before */
    1998           3 :                 if (phar->metadata_len) {
    1999           3 :                         char *buf = estrndup((char *) Z_PTR(phar->metadata), phar->metadata_len);
    2000           3 :                         phar_parse_metadata(&buf, &phar->metadata, phar->metadata_len);
    2001           3 :                         efree(buf);
    2002             :                 } else {
    2003           0 :                         zval_copy_ctor(&phar->metadata);
    2004             :                 }
    2005             :         }
    2006             : 
    2007           3 :         zend_hash_init(&newmanifest, sizeof(phar_entry_info),
    2008             :                 zend_get_hash_value, destroy_phar_manifest_entry, 0);
    2009           3 :         zend_hash_copy(&newmanifest, &(*pphar)->manifest, phar_manifest_copy_ctor);
    2010           3 :         zend_hash_apply_with_argument(&newmanifest, phar_update_cached_entry, (void *)phar);
    2011           3 :         phar->manifest = newmanifest;
    2012           3 :         zend_hash_init(&phar->mounted_dirs, sizeof(char *),
    2013             :                 zend_get_hash_value, NULL, 0);
    2014           3 :         zend_hash_init(&phar->virtual_dirs, sizeof(char *),
    2015             :                 zend_get_hash_value, NULL, 0);
    2016           3 :         zend_hash_copy(&phar->virtual_dirs, &(*pphar)->virtual_dirs, NULL);
    2017           3 :         *pphar = phar;
    2018             : 
    2019             :         /* now, scan the list of persistent Phar objects referencing this phar and update the pointers */
    2020           7 :         ZEND_HASH_FOREACH_PTR(&PHAR_G(phar_persist_map), objphar) {
    2021           2 :                 if (objphar->archive->fname_len == phar->fname_len && !memcmp(objphar->archive->fname, phar->fname, phar->fname_len)) {
    2022           2 :                         objphar->archive = phar;
    2023             :                 }
    2024             :         } ZEND_HASH_FOREACH_END();
    2025           3 : }
    2026             : /* }}} */
    2027             : 
    2028           3 : int phar_copy_on_write(phar_archive_data **pphar) /* {{{ */
    2029             : {
    2030             :         zval zv, *pzv;
    2031             :         phar_archive_data *newpphar;
    2032             : 
    2033           3 :         ZVAL_PTR(&zv, *pphar);
    2034           3 :         if (NULL == (pzv = zend_hash_str_add(&(PHAR_G(phar_fname_map)), (*pphar)->fname, (*pphar)->fname_len, &zv))) {
    2035           0 :                 return FAILURE;
    2036             :         }
    2037             : 
    2038           3 :         phar_copy_cached_phar((phar_archive_data **)&Z_PTR_P(pzv));
    2039           3 :         newpphar = Z_PTR_P(pzv);
    2040             :         /* invalidate phar cache */
    2041           3 :         PHAR_G(last_phar) = NULL;
    2042           3 :         PHAR_G(last_phar_name) = PHAR_G(last_alias) = NULL;
    2043             : 
    2044           6 :         if (newpphar->alias_len && NULL == zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), newpphar->alias, newpphar->alias_len, newpphar)) {
    2045           0 :                 zend_hash_str_del(&(PHAR_G(phar_fname_map)), (*pphar)->fname, (*pphar)->fname_len);
    2046           0 :                 return FAILURE;
    2047             :         }
    2048             : 
    2049           3 :         *pphar = newpphar;
    2050           3 :         return SUCCESS;
    2051             : }
    2052             : /* }}} */
    2053             : 
    2054             : /*
    2055             :  * Local variables:
    2056             :  * tab-width: 4
    2057             :  * c-basic-offset: 4
    2058             :  * End:
    2059             :  * vim600: noet sw=4 ts=4 fdm=marker
    2060             :  * vim<600: noet sw=4 ts=4
    2061             :  */

Generated by: LCOV version 1.10

Generated at Wed, 24 Aug 2016 12:20:28 +0000 (4 days ago)

Copyright © 2005-2016 The PHP Group
All rights reserved.