From 2f983df15e943b2c21c87ba2eead3f5dfc726148 Mon Sep 17 00:00:00 2001 From: Alexey Klimko Date: Fri, 2 Feb 2024 17:30:10 -0500 Subject: [PATCH] =?UTF-8?q?[BR-11210]=20=E2=80=93=20Sugar=20shadow=20exten?= =?UTF-8?q?sion=20does=20not=20work=20properly=20after=20Rector=20scan=20?= =?UTF-8?q?=09PHPStan=20uses=20custom=20'file'=20stream=20wrapper=20to=20c?= =?UTF-8?q?apture=20loaded=20code,=20=09this=20unregisters=20shadow=20wrap?= =?UTF-8?q?per=20and=20breaks=20everything.=20To=20handle=20this,=20=09an?= =?UTF-8?q?=20option=20has=20been=20added=20to=20force=20the=20wrapper=20r?= =?UTF-8?q?einitialization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 21 +++++++++-------- README.md | 4 +++- php_shadow.h | 2 +- shadow.c | 36 +++++++++++++++++++----------- tests/stream_wrapper_reenable.phpt | 21 +++++++++++++++++ tests/write_new_mask.phpt | 2 +- 6 files changed, 59 insertions(+), 27 deletions(-) create mode 100644 tests/stream_wrapper_reenable.phpt diff --git a/Dockerfile b/Dockerfile index 5eabd35..ded61eb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,18 +4,16 @@ ARG PHP_BUILD_DIR=/var/task ARG PHP_CONF_DIR=/etc/php.d ARG PHP_EXT_DIR=/usr/lib64/php/modules +RUN yum install -y amazon-linux-extras +RUN amazon-linux-extras enable php8.2 +RUN amazon-linux-extras install -y php8.2 RUN yum clean all && \ yum -y upgrade && \ - yum -y install ilibzip-dev libonig-dev putils \ - yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \ - https://rpms.remirepo.net/enterprise/remi-release-7.rpm \ - re2c \ - yum-utils && \ - yum-config-manager --disable remi-safe + yum -y install ilibzip-dev libonig-dev putils gcc make \ + yum -y re2c \ + yum-utils -RUN yum-config-manager --enable remi-php82 && \ - yum-config-manager --setopt=remi-php82.priority=10 --save && \ - yum -y install php-cli php-common php-devel && \ +RUN yum -y install php-cli php-common php-devel && \ yum clean all #Extension install @@ -38,7 +36,8 @@ RUN cd shadow && \ ./configure && \ make && \ make install && \ - make test && \ echo "extension=${PHP_EXT_DIR}/shadow.so" > ${PHP_CONF_DIR}/shadow.ini +RUN cd shadow && \ + php run-tests.php --show-diff . -ENTRYPOINT ["php", "-m"] +ENTRYPOINT ["tail", "-f", "/dev/null"] diff --git a/README.md b/README.md index c8ff17a..0af1efa 100644 --- a/README.md +++ b/README.md @@ -35,13 +35,15 @@ Shadow function Shadow has one main function: ```c -void shadow(string template, string instance[, array instance_only]) +void shadow(string template, string instance[, array instance_only, bool force = false]) ``` - template is the template directory - instance is instance directory - instance\_only is an array of directories or filenames (relative to instance directory) that are instance-only +- force stream wrapper initialization (normally performed at request + initialization, but in some cases should be done separately) Other functions: diff --git a/php_shadow.h b/php_shadow.h index 3633cc9..6b67906 100644 --- a/php_shadow.h +++ b/php_shadow.h @@ -69,7 +69,7 @@ ZEND_END_MODULE_GLOBALS(shadow) #define SHADOW_G(v) (shadow_globals.v) #endif -#define SHADOW_VERSION "1.1.1" +#define SHADOW_VERSION "1.2.0" ZEND_EXTERN_MODULE_GLOBALS(shadow) diff --git a/shadow.c b/shadow.c index 09a8ba0..3ad3d8a 100644 --- a/shadow.c +++ b/shadow.c @@ -48,6 +48,7 @@ php_stream_wrapper shadow_wrapper = { static ssize_t shadow_dirstream_read(php_stream *stream, char *buf, size_t count); static int shadow_dirstream_close(php_stream *stream, int close_handle); static int shadow_dirstream_rewind(php_stream *stream, off_t offset, int whence, off_t *newoffs); +static void shadow_init_wrapper(); static php_stream_ops shadow_dirstream_ops = { NULL, @@ -423,22 +424,26 @@ PHP_MSHUTDOWN_FUNCTION(shadow) */ PHP_RINIT_FUNCTION(shadow) { - if(SHADOW_G(enabled)) { - zend_string *protocol; - protocol = zend_string_init("file", strlen("file"), 0); - php_unregister_url_stream_wrapper_volatile(protocol); - php_register_url_stream_wrapper_volatile(protocol, &shadow_wrapper); - zend_string_release_ex(protocol, 0); - } - SHADOW_G(template) = NULL; - SHADOW_G(instance) = NULL; - SHADOW_G(curdir) = NULL; - SHADOW_G(segment_id) = 0; - SHADOW_G(shadow_override_copy) = NULL; + shadow_init_wrapper(); return SUCCESS; } /* }}} */ +static void shadow_init_wrapper() { + if(SHADOW_G(enabled)) { + zend_string *protocol; + protocol = zend_string_init("file", strlen("file"), 0); + php_unregister_url_stream_wrapper_volatile(protocol); + php_register_url_stream_wrapper_volatile(protocol, &shadow_wrapper); + zend_string_release_ex(protocol, 0); + } + SHADOW_G(template) = NULL; + SHADOW_G(instance) = NULL; + SHADOW_G(curdir) = NULL; + SHADOW_G(segment_id) = 0; + SHADOW_G(shadow_override_copy) = NULL; +} + static void shadow_free_data() { if(SHADOW_G(template)) { @@ -493,9 +498,10 @@ PHP_FUNCTION(shadow) char *temp = NULL; char *inst = NULL; size_t temp_len, inst_len; + zend_bool force = 0; // New parameter HashTable *instance_only = NULL; /* paths relative to template root */ - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|h", &temp, &temp_len, &inst, &inst_len, &instance_only) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|hb", &temp, &temp_len, &inst, &inst_len, &instance_only, &force) == FAILURE) { return; } @@ -503,6 +509,10 @@ PHP_FUNCTION(shadow) RETURN_FALSE; } + if(force) { + shadow_init_wrapper(); + } + shadow_free_data(); php_clear_stat_cache(0, NULL, 0); if(temp_len == 0 || inst_len == 0) { diff --git a/tests/stream_wrapper_reenable.phpt b/tests/stream_wrapper_reenable.phpt new file mode 100644 index 0000000..5be8d14 --- /dev/null +++ b/tests/stream_wrapper_reenable.phpt @@ -0,0 +1,21 @@ +--TEST-- +Check reading from files +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Instance data +Template data diff --git a/tests/write_new_mask.phpt b/tests/write_new_mask.phpt index 2d5fa4a..0b58094 100644 --- a/tests/write_new_mask.phpt +++ b/tests/write_new_mask.phpt @@ -3,7 +3,7 @@ Check directory mask on instance directory --INI-- shadow.mkdir_mask=0777 --SKIPIF-- - --FILE--