Skip to content

Commit 72058f6

Browse files
Alexey Klimkodzentota
authored andcommitted
[SUS-128] - Add php 8.5 support to shadow
[SUS-128] - Add php 8.5 support to shadow
1 parent de0bd2a commit 72058f6

4 files changed

Lines changed: 64 additions & 26 deletions

File tree

.github/workflows/build.yml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,31 @@ on:
99
jobs:
1010
build:
1111
runs-on: ubuntu-latest
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
php-version: ['8.2', '8.3', '8.4', '8.5']
16+
17+
name: PHP ${{ matrix.php-version }}
1218

1319
steps:
1420
- uses: actions/checkout@v4
1521

16-
- name: Build and test PHP extension
22+
- name: Build and test PHP extension (PHP ${{ matrix.php-version }})
23+
run: |
24+
docker build -t php-shadow-extension-${{ matrix.php-version }} . --progress=plain \
25+
--build-arg PHP_VERSION=${{ matrix.php-version }}
26+
27+
- name: Verify extension loaded
1728
run: |
18-
docker build -t php-shadow-extension . --progress=plain
29+
docker run --rm php-shadow-extension-${{ matrix.php-version }} php -v
30+
docker run --rm php-shadow-extension-${{ matrix.php-version }} php -m | grep shadow
1931
2032
- name: Archive test results
2133
if: always()
2234
uses: actions/upload-artifact@v4
2335
with:
24-
name: test-results
36+
name: test-results-php-${{ matrix.php-version }}
2537
path: |
2638
/var/task/shadow/*.out
2739
/var/task/shadow/*.diff

Dockerfile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
FROM rockylinux:9
22

3-
# Set arguments for directory paths
3+
# Set arguments for directory paths and PHP version
4+
ARG PHP_VERSION=8.5
45
ARG PHP_BUILD_DIR=/var/task
56
ARG PHP_CONF_DIR=/etc/php.d
67
ARG PHP_EXT_DIR=/usr/lib64/php/modules
@@ -14,10 +15,10 @@ RUN dnf -y update && \
1415
bzip2 bzip2-devel libpng-devel libjpeg-devel \
1516
freetype-devel oniguruma-devel libzip-devel zlib-devel
1617

17-
# Enable Remi repository for PHP 8.4
18+
# Enable Remi repository for specified PHP version (default 8.5)
1819
RUN dnf -y install https://rpms.remirepo.net/enterprise/remi-release-9.rpm && \
1920
dnf module reset php -y && \
20-
dnf module enable php:remi-8.4 -y && \
21+
dnf module enable php:remi-${PHP_VERSION} -y && \
2122
dnf -y install php php-cli php-devel php-pear
2223

2324
# Prepare directories for building the PHP extension

shadow.c

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,6 +1432,29 @@ static void shadow_is_writable(INTERNAL_FUNCTION_PARAMETERS)
14321432
}
14331433
/* }}} */
14341434

1435+
/* Helper function to add glob results to merge hash table */
1436+
static void shadow_glob_add_to_hash(HashTable *mergedata, zval *glob_results, const char *path, int pathlen, void *dummy, int add_new)
1437+
{
1438+
zval *src_entry;
1439+
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(glob_results), src_entry) {
1440+
zend_string *mergepath_zs;
1441+
char *relpath;
1442+
if (Z_TYPE_P(src_entry) != IS_STRING) continue;
1443+
relpath = Z_STRVAL_P(src_entry) + pathlen + 1;
1444+
if (path && path[0] != '\0') {
1445+
mergepath_zs = strpprintf(MAXPATHLEN, "%s/%s", path, relpath);
1446+
} else {
1447+
mergepath_zs = zend_string_init(relpath, strlen(relpath), 0);
1448+
}
1449+
if (add_new) {
1450+
zend_hash_str_add_new_ptr(mergedata, ZSTR_VAL(mergepath_zs), ZSTR_LEN(mergepath_zs), dummy);
1451+
} else {
1452+
zend_hash_str_add_ptr(mergedata, ZSTR_VAL(mergepath_zs), ZSTR_LEN(mergepath_zs), dummy);
1453+
}
1454+
zend_string_release(mergepath_zs);
1455+
} ZEND_HASH_FOREACH_END();
1456+
}
1457+
14351458
/* {{{ proto array glob(string pattern [, int flags])
14361459
Find pathnames matching a pattern */
14371460
static void shadow_glob(INTERNAL_FUNCTION_PARAMETERS)
@@ -1441,11 +1464,11 @@ static void shadow_glob(INTERNAL_FUNCTION_PARAMETERS)
14411464
zend_long flags;
14421465
char *instname=NULL, *templname=NULL, *mask=NULL, *path=NULL;
14431466
zval instdata, templdata;
1444-
zval *src_entry;
14451467
HashTable *mergedata;
14461468
void *dummy = (void *)1;
14471469
int instlen, templen;
14481470
int skip_template=0;
1471+
zval *original_return_value = return_value; /* Save the original pointer */
14491472

14501473
if(!SHADOW_ENABLED()) {
14511474
orig_glob(INTERNAL_FUNCTION_PARAM_PASSTHRU);
@@ -1531,13 +1554,7 @@ static void shadow_glob(INTERNAL_FUNCTION_PARAMETERS)
15311554
/* call with template */
15321555
if(shadow_call_replace_name(0, templname, orig_glob, INTERNAL_FUNCTION_PARAM_PASSTHRU) == SUCCESS && Z_TYPE_P(return_value) == IS_ARRAY) {
15331556
/* cut off instname and put path part there */
1534-
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(return_value), src_entry) {
1535-
char *mergepath;
1536-
if (Z_TYPE_P(src_entry) != IS_STRING) continue; /* weird, glob shouldn't do that to us */
1537-
spprintf(&mergepath, MAXPATHLEN, "%s/%s", path, Z_STRVAL_P(src_entry)+templen+1);
1538-
zend_hash_str_add_new_ptr(mergedata, mergepath, strlen(mergepath), dummy);
1539-
efree(mergepath);
1540-
} ZEND_HASH_FOREACH_END();
1557+
shadow_glob_add_to_hash(mergedata, return_value, path, templen, dummy, 1);
15411558
} else {
15421559
/* ignore problems here - other one may pick it up */
15431560
array_init(return_value);
@@ -1553,22 +1570,27 @@ static void shadow_glob(INTERNAL_FUNCTION_PARAMETERS)
15531570
/* call with instance */
15541571
if(shadow_call_replace_name(0, instname, orig_glob, INTERNAL_FUNCTION_PARAM_PASSTHRU) == SUCCESS && Z_TYPE_P(return_value) == IS_ARRAY) {
15551572
/* merge data */
1556-
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(return_value), src_entry) {
1557-
char *mergepath;
1558-
if (Z_TYPE_P(src_entry) != IS_STRING) continue; /* weird, glob shouldn't do that to us */
1559-
spprintf(&mergepath, MAXPATHLEN, "%s/%s", path, Z_STRVAL_P(src_entry)+instlen+1);
1560-
zend_hash_str_add_ptr(mergedata, mergepath, strlen(mergepath), dummy);
1561-
efree(mergepath);
1562-
} ZEND_HASH_FOREACH_END();
1573+
shadow_glob_add_to_hash(mergedata, return_value, path, instlen, dummy, 0);
15631574
}
15641575
zval_dtor(return_value);
15651576
return_value = &templdata;
15661577
/* convert mergedata to return */
1567-
zend_hash_clean(Z_ARRVAL_P(return_value));
1568-
zend_string *filename_zs;
1569-
ZEND_HASH_FOREACH_STR_KEY(mergedata, filename_zs) {
1570-
add_next_index_str(return_value, zend_string_copy(filename_zs));
1571-
} ZEND_HASH_FOREACH_END();
1578+
if (Z_TYPE_P(return_value) == IS_ARRAY && Z_ARR_P(return_value) != &zend_empty_array) {
1579+
zend_hash_clean(Z_ARRVAL_P(return_value));
1580+
} else {
1581+
array_init(return_value);
1582+
}
1583+
zend_string *name = NULL;
1584+
zend_ulong num;
1585+
zend_hash_internal_pointer_reset(mergedata);
1586+
while (zend_hash_get_current_key(mergedata, &name, &num) == HASH_KEY_IS_STRING) {
1587+
if (name && ZSTR_VAL(name) && ZSTR_LEN(name)) {
1588+
add_next_index_str(return_value, zend_string_copy(name));
1589+
}
1590+
zend_hash_move_forward(mergedata);
1591+
}
1592+
/* CRITICAL: Copy templdata back to the ORIGINAL return_value pointer */
1593+
ZVAL_COPY_VALUE(original_return_value, &templdata);
15721594
/* cleanup */
15731595
zend_hash_clean(mergedata);
15741596
zend_hash_destroy(mergedata);

tests/stream_wrapper_reenable.phpt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ stream_wrapper_restore('file');
1515
shadow($template, $instance, array("cache", "custom", "custom/some/long/directory/name"), true) || die("failed to setup shadow");
1616

1717
echo file_get_contents("$instance/txt/override.txt");
18+
19+
// Restore the file immediately for subsequent test runs
20+
file_put_contents("$instance/txt/override.txt", "Instance data\n");
1821
?>
1922
--EXPECT--
2023
Instance data

0 commit comments

Comments
 (0)