PHP Bug #79714

php.internals

Henrik Skov

6 years ago
Hi list ! I am still trying to solve bug 79714 (See: https://bugs.php.net/bug.php?id=79714) I am no expert at C and/or the PHP Core at all so I need a little advice from you guys. Seeing lines 3238-3314 in /ext/phar/phar.c (from php-src repo): static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type) /* {{{ */ {     zend_op_array *res;     char *name = NULL;     int failed;     phar_archive_data *phar;     if (!file_handle || !file_handle->filename) {         return phar_orig_compile_file(file_handle, type);     }     if (strstr(file_handle->filename, ".phar") && !strstr(file_handle->filename, "://")) {         if (SUCCESS == phar_open_from_filename((char*)file_handle->filename, strlen(file_handle->filename), NULL, 0, 0, &phar, NULL)) {             if (phar->is_zip || phar->is_tar) {                 zend_file_handle f = *file_handle;                 /* zip or tar-based phar */                 spprintf(&name, 4096, "phar://%s/%s", file_handle->filename, ".phar/stub.php");                 if (SUCCESS == phar_orig_zend_open((const char *)name, &f)) {                     efree(name);                     name = NULL;                     f.filename = file_handle->filename;                     if (f.opened_path) {                         efree(f.opened_path);                     }                     f.opened_path = file_handle->opened_path;                     f.free_filename = file_handle->free_filename;                     switch (file_handle->type) {                         case ZEND_HANDLE_STREAM:                             if (file_handle->handle.stream.closer && file_handle->handle.stream.handle) { file_handle->handle.stream.closer(file_handle->handle.stream.handle);                             }                             file_handle->handle.stream.handle = NULL;                             break;                         default:                             break;                     }                     *file_handle = f;                 }             } else if (phar->flags & PHAR_FILE_COMPRESSION_MASK) {                 zend_file_handle_dtor(file_handle);                 /* compressed phar */                 file_handle->type = ZEND_HANDLE_STREAM;                 /* we do our own reading directly from the phar, don't change the next line */                 file_handle->handle.stream.handle  = phar;                 file_handle->handle.stream.reader  = phar_zend_stream_reader;                 file_handle->handle.stream.closer  = NULL;                 file_handle->handle.stream.fsizer  = phar_zend_stream_fsizer;                 file_handle->handle.stream.isatty  = 0;                 phar->is_persistent ? php_stream_rewind(PHAR_G(cached_fp)[phar->phar_pos].fp) :                     php_stream_rewind(phar->fp);             }         }     }     zend_try {         failed = 0;         CG(zend_lineno) = 0;         res = phar_orig_compile_file(file_handle, type);     } zend_catch {         failed = 1;         res = NULL;     } zend_end_try();     if (name) {         efree(name);     }     if (failed) {         zend_bailout();     }     return res; } I *think* that what maybe would fix this bug is if line 3299 (res = phar_orig_compile_file(file_handle, type);) was - if BCGEN extension is loaded - is affected so that phar_orig_compile_file was changed to point to another function. Let's imagine that phar_orig_compile_file pointed to bcgen_phar_compile_file() which was then implemented by BCGEN: ZendAccelerator.h (of BCGEN): (Link: https://github.com/vjardin/bcgen/blob/a863b8d596cebb698a491f7475903f5aa3664719/ZendAccelerator.h) zend_op_array *bcgen_phar_compile_file(zend_file_handle *file_handle, int type); ZendAccelerator.c (of BCGEN): (Link: https://github.com/vjardin/bcgen/blob/a863b8d596cebb698a491f7475903f5aa3664719/ZendAccelerator.c) zend_op_array *bcgen_phar_compile_file(zend_file_handle *file_handle, int type) {     if (!file_handle->filename || !ZCG(enabled) || !accel_startup_ok) {             /* The Accelerator is disabled, act as if without BCGEN */         return zend_compile(file_handle, type);     } else {         /* Use the zend_compile replacement of BCGEN for this file */         return persistent_load_file(file_handle, type);     } } Now, for my question: How can I make sure that phar_orig_compile_file() points to bcgen_phar_compile_file() when line 3299 of /ext/phar/phar.c is hit *WITHOUT* changing line 3299 if - and only if BCGEN module is present ? Would a #define do it ? (something like: #define phar_orig_compile_file bcgen_phar_compile_file in ZendAccelerator.h (of BCGEN) (Link: https://github.com/vjardin/bcgen/blob/a863b8d596cebb698a491f7475903f5aa3664719/ZendAccelerator.h) NOTE: /ext/phar/phar.c already has this on line 3230: zend_op_array *(*phar_orig_compile_file)(zend_file_handle *file_handle, int type); which would conflict with my - proposed - define/solution or ? Please advice ! If it is inappropriate to ask for coding advice on this list, I do apologize for this mail ! Thank you in advance ! Best regards, Henrik Skov Secuno A/S