summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--package.xml7
-rw-r--r--php_rpminfo.h2
-rw-r--r--rpminfo.c69
-rw-r--r--rpminfo.stub.php4
-rw-r--r--rpminfo_arginfo.h15
-rw-r--r--tests/014-stream.phpt9
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)
diff --git a/rpminfo.c b/rpminfo.c
index ab2ebf1..13d4293 100644
--- a/rpminfo.c
+++ b/rpminfo.c
@@ -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