diff options
author | Remi Collet <remi@remirepo.net> | 2023-11-10 08:35:39 +0100 |
---|---|---|
committer | Remi Collet <remi@php.net> | 2023-11-10 08:35:39 +0100 |
commit | 0a9b035bee3515e9e395e0df9b624503781068e6 (patch) | |
tree | 83a2549f3a27b7418802fdcbda3b7feda3dd7d90 | |
parent | ba8ff7f35e870a10bb0bd68b3ba0ec9ab43b8576 (diff) |
new function: rpmgetsymlink(string $path, string $name): ?string
-rw-r--r-- | package.xml | 7 | ||||
-rw-r--r-- | php_rpminfo.h | 2 | ||||
-rw-r--r-- | rpminfo.c | 69 | ||||
-rw-r--r-- | rpminfo.stub.php | 4 | ||||
-rw-r--r-- | rpminfo_arginfo.h | 15 | ||||
-rw-r--r-- | tests/014-stream.phpt | 9 |
6 files changed, 99 insertions, 7 deletions
diff --git a/package.xml b/package.xml index 1208c2e..515cb66 100644 --- a/package.xml +++ b/package.xml @@ -13,9 +13,9 @@ Documentation: https://www.php.net/rpminfo <email>remi@php.net</email> <active>yes</active> </lead> - <date>2023-10-13</date> + <date>2023-11-10</date> <version> - <release>1.0.2dev</release> + <release>1.1.0dev</release> <api>1.0.0</api> </version> <stability> @@ -24,7 +24,8 @@ Documentation: https://www.php.net/rpminfo </stability> <license uri="https://www.php.net/license/3_01.txt" filesource="LICENSE">PHP-3.01</license> <notes> -- +- check open_basedir restriction +- new function: rpmgetsymlink(string $path, string $name): ?string </notes> <contents> <dir name="/"> diff --git a/php_rpminfo.h b/php_rpminfo.h index 45cc30b..eaf7451 100644 --- a/php_rpminfo.h +++ b/php_rpminfo.h @@ -22,7 +22,7 @@ extern zend_module_entry rpminfo_module_entry; #define phpext_rpminfo_ptr &rpminfo_module_entry -#define PHP_RPMINFO_VERSION "1.0.2-dev" +#define PHP_RPMINFO_VERSION "1.1.0-dev" #ifdef PHP_WIN32 # define PHP_RPMINFO_API __declspec(dllexport) @@ -235,6 +235,9 @@ PHP_FUNCTION(rpminfo) zval_dtor(error); ZVAL_NULL(error); } + if (php_check_open_basedir(path)) { + RETURN_NULL(); + } f = Fopen(path, "r"); if (f) { @@ -688,6 +691,7 @@ static struct php_rpm_stream_data_t *php_stream_rpm_finder(const char *path, int rc = rpmReadPackageFile(ts, fdi, "rpm2cpio", &h); if (rc != RPMRC_OK && rc != RPMRC_NOKEY && rc != RPMRC_NOTTRUSTED) { zend_string_release_ex(file_basename, 0); + Fclose(fdi); return NULL; } @@ -695,6 +699,8 @@ static struct php_rpm_stream_data_t *php_stream_rpm_finder(const char *path, int snprintf(rpmio_flags, sizeof(rpmio_flags), "r.%s", compr ? compr : "gzip"); gzdi = Fdopen(fdi, rpmio_flags); if (gzdi == NULL) { + headerFree(h); + Fclose(fdi); zend_string_release_ex(file_basename, 0); return NULL; } @@ -803,7 +809,68 @@ const php_stream_wrapper php_stream_rpm_wrapper = { NULL, 0 /* is_url */ }; -#endif + +/* {{{ proto array rpmgetsymlink(string path , string name) + Retrieve soft link target of en entry */ +PHP_FUNCTION(rpmgetsymlink) +{ + char *path, *name; + const char *link; + size_t plen, nlen; + FD_t fdi; + FD_t gzdi; + int rc; + Header h; + char rpmio_flags[80]; + const char *compr; + rpmfiles files; + rpmfi fi; + rpmts ts = rpminfo_getts(); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "pp", &path, &plen, &name, &nlen) == FAILURE) { + RETURN_THROWS(); + } + + if (php_check_open_basedir(path)) { + RETURN_NULL(); + } + fdi = Fopen(path, "r.ufdio"); + if (Ferror(fdi)) { + RETURN_NULL(); + } + rc = rpmReadPackageFile(ts, fdi, "rpm2cpio", &h); + if (rc != RPMRC_OK && rc != RPMRC_NOKEY && rc != RPMRC_NOTTRUSTED) { + Fclose(fdi); + RETURN_NULL(); + } + + compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR); + snprintf(rpmio_flags, sizeof(rpmio_flags), "r.%s", compr ? compr : "gzip"); + gzdi = Fdopen(fdi, rpmio_flags); + if (gzdi == NULL) { + headerFree(h); + Fclose(fdi); + RETURN_NULL(); + } + + files = rpmfilesNew(NULL, h, 0, RPMFI_KEEPHEADER); + fi = rpmfiNewArchiveReader(gzdi, files, RPMFI_ITER_READ_ARCHIVE); + + rc = rpmfiFindFN(fi, name); + if (rc < 0 + || rpmfiSetFX(fi, rc) < 0 + || (link = rpmfiFLink(fi)) == NULL) { + RETVAL_NULL(); + } else { + RETVAL_STRING(link); + } + rpmfiFree(fi); + rpmfilesFree(files); + headerFree(h); + Fclose(gzdi); +} +/* }}} */ +#endif /* HAVE_ARCHIVE */ /* {{{ PHP_MINIT_FUNCTION diff --git a/rpminfo.stub.php b/rpminfo.stub.php index 022ccd4..7e6e32e 100644 --- a/rpminfo.stub.php +++ b/rpminfo.stub.php @@ -12,4 +12,6 @@ function rpminfo(string $path, bool $full = false, ?string &$error = null): Arra function rpmvercmp(string $evr1, string $evr2, ?string $operator = null): int|bool {} - +#ifdef HAVE_ARCHIVE +function rpmgetsymlink(string $path, string $name): string|null {} +#endif diff --git a/rpminfo_arginfo.h b/rpminfo_arginfo.h index 03fa650..aa0e1d3 100644 --- a/rpminfo_arginfo.h +++ b/rpminfo_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8636be19a4c17d1ed16247fb265a923ee7c89104 */ + * Stub hash: e65e33b4f6ebedcc7ef3030714ebf7e4c06f2778 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rpmaddtag, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, rpmtag, IS_LONG, 0) @@ -29,12 +29,22 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_rpmvercmp, 0, 2, MAY_BE_LONG|MAY ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, operator, IS_STRING, 1, "null") ZEND_END_ARG_INFO() +#if defined(HAVE_ARCHIVE) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rpmgetsymlink, 0, 2, IS_STRING, 1) + ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + ZEND_FUNCTION(rpmaddtag); ZEND_FUNCTION(rpmdbinfo); ZEND_FUNCTION(rpmdbsearch); ZEND_FUNCTION(rpminfo); ZEND_FUNCTION(rpmvercmp); +#if defined(HAVE_ARCHIVE) +ZEND_FUNCTION(rpmgetsymlink); +#endif static const zend_function_entry ext_functions[] = { @@ -43,5 +53,8 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(rpmdbsearch, arginfo_rpmdbsearch) ZEND_FE(rpminfo, arginfo_rpminfo) ZEND_FE(rpmvercmp, arginfo_rpmvercmp) +#if defined(HAVE_ARCHIVE) + ZEND_FE(rpmgetsymlink, arginfo_rpmgetsymlink) +#endif ZEND_FE_END }; diff --git a/tests/014-stream.phpt b/tests/014-stream.phpt index 95f815e..69b881e 100644 --- a/tests/014-stream.phpt +++ b/tests/014-stream.phpt @@ -43,6 +43,11 @@ var_dump(trim(file_get_contents($n))); // Existing file var_dump(trim(file_get_contents($foo))); // Hardlink with content var_dump(trim(file_get_contents($bar))); // hardlink without content var_dump(file_get_contents($x)); // Missing file + +echo "+ symlink\n"; +var_dump(rpmgetsymlink(__DIR__ . "/bidon.rpm", "missing")); +var_dump(rpmgetsymlink(__DIR__ . "/bidon.rpm", "/etc/foo.conf")); // not a symlink +var_dump(rpmgetsymlink(__DIR__ . "/bidon.rpm", "/etc/toto.conf")); // symlink ?> Done --EXPECTF-- @@ -85,4 +90,8 @@ string(7) "content" Warning: file_get_contents(%s/bidon.rpm#/usr/share/doc/bidon/MISSING): Failed to open stream: operation failed in %s on line %d bool(false) ++ symlink +NULL +string(0) "" +string(8) "foo.conf" Done |