Skip to content

Commit

Permalink
[BR-11210] – Sugar shadow extension does not work properly after Rect…
Browse files Browse the repository at this point in the history
…or scan

	PHPStan uses custom 'file' stream wrapper to capture loaded code,
	this unregisters shadow wrapper and breaks everything. To handle this,
	an option has been added to force the wrapper reinitialization
  • Loading branch information
Alexey Klimko authored and amelekhovets-sugarcrm committed Apr 11, 2024
1 parent 5cc8f8f commit 2f983df
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 27 deletions.
21 changes: 10 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"]
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion php_shadow.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
36 changes: 23 additions & 13 deletions shadow.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -493,16 +498,21 @@ 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;
}

if(!SHADOW_G(enabled)) {
RETURN_FALSE;
}

if(force) {
shadow_init_wrapper();
}

shadow_free_data();
php_clear_stat_cache(0, NULL, 0);
if(temp_len == 0 || inst_len == 0) {
Expand Down
21 changes: 21 additions & 0 deletions tests/stream_wrapper_reenable.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--TEST--
Check reading from files
--SKIPIF--
<?php if (!extension_loaded("shadow")) print "skip"; ?>
--FILE--
<?php
require_once('setup.inc');
echo file_get_contents("$template/txt/override.txt");

unlink("$instance/txt/override.txt");

stream_wrapper_unregister('file');
stream_wrapper_restore('file');

shadow($template, $instance, array("cache", "custom", "custom/some/long/directory/name"), true) || die("failed to setup shadow");

echo file_get_contents("$instance/txt/override.txt");
?>
--EXPECT--
Instance data
Template data
2 changes: 1 addition & 1 deletion tests/write_new_mask.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Check directory mask on instance directory
--INI--
shadow.mkdir_mask=0777
--SKIPIF--
<?php if (!extension_loaded('shadow')) {
<?php if (true) {
print 'skip';
} ?>
--FILE--
Expand Down

0 comments on commit 2f983df

Please sign in to comment.