PHP Bug #79714

From: Date: Fri, 26 Jun 2020 11:20:17 +0000
Subject: PHP Bug #79714
Groups: php.internals 
Request: Send a blank email to internals+get-110733@lists.php.net to get a copy of this message
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

« previous php.internals (#110733) next »