diff --git a/.gitignore b/.gitignore index 0dafcdb..577b9de 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ clog /smbclient-1.0.4.tgz /smbclient-1.0.5.tgz /smbclient-1.0.6.tgz +/smbclient-1.1.0.tgz diff --git a/php-smbclient.spec b/php-smbclient.spec index b7cc356..0bd71f2 100644 --- a/php-smbclient.spec +++ b/php-smbclient.spec @@ -17,28 +17,28 @@ %global with_zts 0%{?__ztsphp:1} %global ini_name 40-%{pecl_name}.ini # Test suite requires a Samba server and configuration file -%global with_tests 0%{?_with_tests:1} +%bcond_with tests Name: php-smbclient -Version: 1.0.6 -Release: 9%{?dist} +Version: 1.1.0 +Release: 1%{?dist} Summary: PHP wrapper for libsmbclient License: BSD-2-Clause URL: https://github.com/eduardok/libsmbclient-php Source0: https://pecl.php.net/get/%{pecl_name}-%{version}%{?prever}.tgz -%if %{with_tests} +%if %{with tests} Source2: %{pecl_name}-phpunit.xml %endif -Patch0: %{pecl_name}-stub.patch +Patch0: %{pecl_name}-bug98.patch BuildRequires: make BuildRequires: gcc BuildRequires: php-devel BuildRequires: php-pear BuildRequires: libsmbclient-devel > 3.6 -%if %{with_tests} +%if %{with tests} BuildRequires: php-composer(phpunit/phpunit) BuildRequires: samba %endif @@ -73,7 +73,7 @@ sed -e 's/role="test"/role="src"/' \ -i package.xml cd NTS -%patch0 -p1 +%patch -P0 -p1 -b .pr100 # Check extension version ver=$(sed -n '/define PHP_SMBCLIENT_VERSION/{s/.* "//;s/".*$//;p}' php_smbclient.h) @@ -141,7 +141,7 @@ done --modules | grep %{pecl_name} %endif -%if %{with_tests} +%if %{with tests} : Upstream test suite for NTS extension cd NTS cp %{SOURCE2} phpunit.xml @@ -167,6 +167,12 @@ cp %{SOURCE2} phpunit.xml %changelog +* Tue Apr 4 2023 Remi Collet - 1.1.0-1 +- update to 1.1.0 +- drop patch merged upstream +- add workaround for regression in libsmbclient 4.16.9/4.17.5 + from https://github.com/eduardok/libsmbclient-php/pull/100 + * Fri Mar 31 2023 Remi Collet - 1.0.6-9 - use SPDX license ID diff --git a/smbclient-bug98.patch b/smbclient-bug98.patch new file mode 100644 index 0000000..6457608 --- /dev/null +++ b/smbclient-bug98.patch @@ -0,0 +1,185 @@ +From 1f32b0da5fd8ea567bb408babea4cc090f5587ed Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Mon, 3 Apr 2023 11:38:01 +0200 +Subject: [PATCH 1/3] workaround for regression in libsmbclient 4.16.9/4.17.5 + +--- + smbclient.c | 58 ++++++++++++++++++++++++++++++++++------------------- + 1 file changed, 37 insertions(+), 21 deletions(-) + +diff --git a/smbclient.c b/smbclient.c +index 52b2bf1..64bb7d5 100644 +--- a/smbclient.c ++++ b/smbclient.c +@@ -1502,6 +1502,11 @@ PHP_FUNCTION(smbclient_listxattr) + RETURN_FALSE; + } + ++ ++/* loop from 4K to 16M */ ++#define DEFAULT_BUFFER_SIZE (4 << 10) ++#define MAXIMUM_BUFFER_SIZE (32 << 20) ++ + PHP_FUNCTION(smbclient_getxattr) + { + char *url, *name; +@@ -1511,11 +1516,7 @@ PHP_FUNCTION(smbclient_getxattr) + zval *zstate; + smbc_getxattr_fn smbc_getxattr; + php_smbclient_state *state; +-#if PHP_MAJOR_VERSION >= 7 +- zend_string *svalues = NULL; +-#else + char *values = NULL; +-#endif + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &zstate, &url, &url_len, &name, &name_len) == FAILURE) { + return; +@@ -1533,30 +1534,40 @@ PHP_FUNCTION(smbclient_getxattr) + } + + if (xattr_size == 0) { +- RETURN_EMPTY_STRING(); ++ /* since version 4.16.9 and 4.17.5 this means success :( ++ * so there is no way to compute the buffer size ++ * see https://bugzilla.samba.org/show_bug.cgi?id=14808 ++ */ ++ xattr_size = DEFAULT_BUFFER_SIZE; ++ do { ++ if (values) { ++ efree(values); ++ xattr_size *= 2; ++ } ++ values = emalloc(xattr_size + 1); ++ retsize = smbc_getxattr(state->ctx, url, name, values, xattr_size + 1); ++ } while (retsize < 0 && xattr_size < MAXIMUM_BUFFER_SIZE); ++ } else { ++ values = emalloc(xattr_size + 1); ++ retsize = smbc_getxattr(state->ctx, url, name, values, xattr_size + 1); + } + +-#if PHP_MAJOR_VERSION >= 7 +- svalues = zend_string_alloc(xattr_size, 0); +- retsize = smbc_getxattr(state->ctx, url, name, ZSTR_VAL(svalues), xattr_size + 1); +- if (retsize > xattr_size) { /* time-of-check, time-of-use error */ +- retsize = xattr_size; +- } else if (retsize < 0) { +- zend_string_release(svalues); +- goto fail; +- } +- RETURN_STR(svalues); +-#else +- values = emalloc(xattr_size + 1); +- retsize = smbc_getxattr(state->ctx, url, name, values, xattr_size + 1); +- if (retsize > xattr_size) { /* time-of-check, time-of-use error */ ++ if (retsize == 0) { /* success, since 4.16.9 and 4.17.5 */ ++ retsize = strlen(values); ++ } else if (retsize > xattr_size) { /* time-of-check, time-of-use error */ + retsize = xattr_size; + } else if (retsize < 0) { + efree(values); + goto fail; + } +- RETURN_STRINGL(values, retsize, 0); ++ /* realloc the string to its real size */ ++#if PHP_MAJOR_VERSION >= 7 ++ RETVAL_STRINGL(values, retsize); ++#else ++ RETVAL_STRINGL(values, retsize, 1); + #endif ++ efree(values); ++ return; + + fail: + hide_password(url, url_len); +@@ -1565,7 +1576,12 @@ PHP_FUNCTION(smbclient_getxattr) + case ENOMEM: php_error(E_WARNING, "Couldn't get xattr for %s: out of memory", url); break; + case EPERM: php_error(E_WARNING, "Couldn't get xattr for %s: permission denied", url); break; + case ENOTSUP: php_error(E_WARNING, "Couldn't get xattr for %s: file system does not support extended attributes", url); break; +- default: php_error(E_WARNING, "Couldn't get xattr for %s: unknown error (%d)", url, errno); break; ++ default: ++ if (xattr_size == MAXIMUM_BUFFER_SIZE) { ++ php_error(E_WARNING, "Couldn't get xattr for %s: internal buffer is too small", url); break; ++ } else { ++ php_error(E_WARNING, "Couldn't get xattr for %s: unknown error (%d)", url, errno); break; ++ } + } + RETURN_FALSE; + } + +From 78b519144521c22f917696500be77fb46d236813 Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Mon, 3 Apr 2023 15:56:01 +0200 +Subject: [PATCH 2/3] loop from 16K to 256M faster + +--- + smbclient.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/smbclient.c b/smbclient.c +index 64bb7d5..8186724 100644 +--- a/smbclient.c ++++ b/smbclient.c +@@ -1503,9 +1503,9 @@ PHP_FUNCTION(smbclient_listxattr) + } + + +-/* loop from 4K to 16M */ +-#define DEFAULT_BUFFER_SIZE (4 << 10) +-#define MAXIMUM_BUFFER_SIZE (32 << 20) ++/* loop from 16K to 256M */ ++#define DEFAULT_BUFFER_SIZE (16 << 10) ++#define MAXIMUM_BUFFER_SIZE (256 << 20) + + PHP_FUNCTION(smbclient_getxattr) + { +@@ -1542,7 +1542,7 @@ PHP_FUNCTION(smbclient_getxattr) + do { + if (values) { + efree(values); +- xattr_size *= 2; ++ xattr_size *= 4; + } + values = emalloc(xattr_size + 1); + retsize = smbc_getxattr(state->ctx, url, name, values, xattr_size + 1); + +From a7b076a05b16047a09b5194782505c68d98208b7 Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Mon, 3 Apr 2023 16:00:16 +0200 +Subject: [PATCH 3/3] test that smbclient_getxattr returns not empty string + +--- + tests/GetxattrTest.php | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tests/GetxattrTest.php b/tests/GetxattrTest.php +index 539a0d0..266f353 100644 +--- a/tests/GetxattrTest.php ++++ b/tests/GetxattrTest.php +@@ -8,7 +8,7 @@ public function + $state = smbclient_state_new(); + smbclient_state_init($state, null, SMB_USER, SMB_PASS); + $attr = smbclient_getxattr($state, 'smb://'.SMB_HOST.'/'.SMB_SHARE.'/testdir/testfile.txt', 'system.*'); +- $this->assertTrue(is_string($attr)); ++ $this->assertTrue(is_string($attr) && strlen($attr)); + } + + public function +@@ -17,7 +17,7 @@ public function + $state = smbclient_state_new(); + smbclient_state_init($state, null, SMB_USER, SMB_PASS); + $attr = smbclient_getxattr($state, 'smb://'.SMB_HOST.'/'.SMB_SHARE.'/testdir', 'system.*'); +- $this->assertTrue(is_string($attr)); ++ $this->assertTrue(is_string($attr) && strlen($attr)); + } + + public function +@@ -26,7 +26,7 @@ public function + $state = smbclient_state_new(); + smbclient_state_init($state, null, SMB_USER, SMB_PASS); + $attr = smbclient_getxattr($state, 'smb://'.SMB_HOST.'/'.SMB_SHARE, 'system.*'); +- $this->assertTrue(is_string($attr)); ++ $this->assertTrue(is_string($attr) && strlen($attr)); + } + + /** diff --git a/smbclient-stub.patch b/smbclient-stub.patch deleted file mode 100644 index 571ad1f..0000000 --- a/smbclient-stub.patch +++ /dev/null @@ -1,881 +0,0 @@ -From 4b17fed6363c109ef34baebce1e367acd97a3c13 Mon Sep 17 00:00:00 2001 -From: Remi Collet -Date: Mon, 7 Feb 2022 16:43:42 +0100 -Subject: [PATCH] generate arginfo from stub - fix smbclient_rename parameters - name - fix smbclient_chmod, mode is required - fix smbclient_utimes: mtime - and atime are optional - ---- - package.xml | 3 + - smbclient.c | 164 +----------------------- - smbclient.stub.php | 189 ++++++++++++++++++++++++++++ - smbclient_arginfo.h | 249 +++++++++++++++++++++++++++++++++++++ - smbclient_legacy_arginfo.h | 226 +++++++++++++++++++++++++++++++++ - 5 files changed, 671 insertions(+), 160 deletions(-) - create mode 100644 smbclient.stub.php - create mode 100644 smbclient_arginfo.h - create mode 100644 smbclient_legacy_arginfo.h - -diff --git a/smbclient.c b/smbclient.c -index a63bad4..6b98693 100644 ---- a/smbclient.c -+++ b/smbclient.c -@@ -147,172 +147,16 @@ hide_password (char *url, int len) - astfill(second_colon + 1, at_sign - 1); - } - --/* {{{ arginfo */ --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_void, 0) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO_EX(arginfo_smbclient_state_init, 0, 0, 1) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, workgroup) -- ZEND_ARG_INFO(0, user) -- ZEND_ARG_INFO(0, password) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_state, 0) -- ZEND_ARG_INFO(0, state) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_option_get, 0) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, option) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_option_set, 0) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, option) -- ZEND_ARG_INFO(0, value) --ZEND_END_ARG_INFO() -- --#if HAVE_SMBC_SETOPTIONPROTOCOLS --ZEND_BEGIN_ARG_INFO_EX(arginfo_smbclient_client_protocols, 0, 0, 1) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, minproto) -- ZEND_ARG_INFO(0, maxproto) --ZEND_END_ARG_INFO() --#endif -- --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_path, 0) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, path) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_rename, 0) -- ZEND_ARG_INFO(0, oldstate) -- ZEND_ARG_INFO(0, oldpath) -- ZEND_ARG_INFO(0, oldstate) -- ZEND_ARG_INFO(0, oldpath) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_dir, 0) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, dir) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_file, 0) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, file) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_read, 0) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, file) -- ZEND_ARG_INFO(0, count) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO_EX(arginfo_smbclient_open, 0, 0, 3) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, path) -- ZEND_ARG_INFO(0, flags) -- ZEND_ARG_INFO(0, mode) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO_EX(arginfo_smbclient_creat, 0, 0, 2) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, path) -- ZEND_ARG_INFO(0, mode) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO_EX(arginfo_smbclient_write, 0, 0, 3) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, file) -- ZEND_ARG_INFO(0, buffer) -- ZEND_ARG_INFO(0, count) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_lseek, 0) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, file) -- ZEND_ARG_INFO(0, offset) -- ZEND_ARG_INFO(0, whence) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_ftruncate, 0) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, file) -- ZEND_ARG_INFO(0, offset) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_utimes, 0) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, path) -- ZEND_ARG_INFO(0, mtime) -- ZEND_ARG_INFO(0, atime) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO(arginfo_smbclient_getxattr, 0) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, path) -- ZEND_ARG_INFO(0, name) --ZEND_END_ARG_INFO() -- --ZEND_BEGIN_ARG_INFO_EX(arginfo_smbclient_setxattr, 0, 0, 4) -- ZEND_ARG_INFO(0, state) -- ZEND_ARG_INFO(0, path) -- ZEND_ARG_INFO(0, name) -- ZEND_ARG_INFO(0, value) -- ZEND_ARG_INFO(0, flags) --ZEND_END_ARG_INFO() -- --/* }}} */ -- --static zend_function_entry smbclient_functions[] = --{ -- PHP_FE(smbclient_version, arginfo_smbclient_void) -- PHP_FE(smbclient_library_version, arginfo_smbclient_void) -- PHP_FE(smbclient_state_new, arginfo_smbclient_void) -- PHP_FE(smbclient_state_init, arginfo_smbclient_state_init) -- PHP_FE(smbclient_state_errno, arginfo_smbclient_state) -- PHP_FE(smbclient_state_free, arginfo_smbclient_state) -- PHP_FE(smbclient_option_get, arginfo_smbclient_option_get) -- PHP_FE(smbclient_option_set, arginfo_smbclient_option_set) --#if HAVE_SMBC_SETOPTIONPROTOCOLS -- PHP_FE(smbclient_client_protocols, arginfo_smbclient_client_protocols) --#endif -- PHP_FE(smbclient_opendir, arginfo_smbclient_path) -- PHP_FE(smbclient_readdir, arginfo_smbclient_dir) -- PHP_FE(smbclient_closedir, arginfo_smbclient_dir) -- PHP_FE(smbclient_stat, arginfo_smbclient_path) -- PHP_FE(smbclient_fstat, arginfo_smbclient_file) -- PHP_FE(smbclient_open, arginfo_smbclient_open) -- PHP_FE(smbclient_creat, arginfo_smbclient_creat) -- PHP_FE(smbclient_read, arginfo_smbclient_read) -- PHP_FE(smbclient_close, arginfo_smbclient_file) -- PHP_FE(smbclient_mkdir, arginfo_smbclient_creat) -- PHP_FE(smbclient_rmdir, arginfo_smbclient_path) -- PHP_FE(smbclient_rename, arginfo_smbclient_rename) -- PHP_FE(smbclient_write, arginfo_smbclient_write) -- PHP_FE(smbclient_unlink, arginfo_smbclient_path) -- PHP_FE(smbclient_lseek, arginfo_smbclient_lseek) -- PHP_FE(smbclient_ftruncate, arginfo_smbclient_ftruncate) -- PHP_FE(smbclient_chmod, arginfo_smbclient_creat) -- PHP_FE(smbclient_utimes, arginfo_smbclient_utimes) -- PHP_FE(smbclient_listxattr, arginfo_smbclient_path) -- PHP_FE(smbclient_getxattr, arginfo_smbclient_getxattr) -- PHP_FE(smbclient_setxattr, arginfo_smbclient_setxattr) -- PHP_FE(smbclient_removexattr, arginfo_smbclient_getxattr) -- PHP_FE(smbclient_statvfs, arginfo_smbclient_path) -- PHP_FE(smbclient_fstatvfs, arginfo_smbclient_file) --#ifdef PHP_FE_END -- PHP_FE_END -+#if PHP_VERSION_ID < 80000 -+#include "smbclient_legacy_arginfo.h" - #else -- {NULL, NULL, NULL} -+#include "smbclient_arginfo.h" - #endif --}; - - zend_module_entry smbclient_module_entry = - { STANDARD_MODULE_HEADER - , "smbclient" /* name */ -- , smbclient_functions /* functions */ -+ , ext_functions /* functions */ - , PHP_MINIT(smbclient) /* module_startup_func */ - , PHP_MSHUTDOWN(smbclient) /* module_shutdown_func */ - , PHP_RINIT(smbclient) /* request_startup_func */ -diff --git a/smbclient.stub.php b/smbclient.stub.php -new file mode 100644 -index 0000000..65f5fad ---- /dev/null -+++ b/smbclient.stub.php -@@ -0,0 +1,189 @@ -+