From 6ab913b164493f95aceaf412e2108d7369a4f9c6 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 3 Apr 2023 16:20:15 +0200 Subject: add workaround for regression in libsmbclient 4.16.9/4.17.5 from https://github.com/eduardok/libsmbclient-php/pull/100 --- php-smbclient.spec | 10 ++- smbclient-bug98.patch | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 smbclient-bug98.patch diff --git a/php-smbclient.spec b/php-smbclient.spec index 8c55e6b..a815019 100644 --- a/php-smbclient.spec +++ b/php-smbclient.spec @@ -39,7 +39,7 @@ Version: 1.1.0 %if 0%{?gh_date} Release: 0.9.%{gh_date}git%{gh_short}%{?dist}%{!?scl:%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}} %else -Release: 1%{?dist}%{!?scl:%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}} +Release: 2%{?dist}%{!?scl:%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}} %endif Summary: PHP wrapper for libsmbclient @@ -55,6 +55,8 @@ Source0: https://pecl.php.net/get/%{pecl_name}-%{version}%{?prever}.tgz Source2: %{pecl_name}-phpunit.xml %endif +Patch0: %{pecl_name}-bug98.patch + BuildRequires: %{?dtsprefix}gcc BuildRequires: %{?scl_prefix}php-devel BuildRequires: %{?scl_prefix}php-pear @@ -117,6 +119,8 @@ sed -e 's/role="test"/role="src"/' \ -i package.xml cd NTS +%patch -P0 -p1 -b .pr100 + # Check extension version ver=$(sed -n '/define PHP_SMBCLIENT_VERSION/{s/.* "//;s/".*$//;p}' php_smbclient.h) if test "$ver" != "%{version}%{?prever}%{?gh_date:-dev}"; then @@ -234,6 +238,10 @@ fi %changelog +* Mon Apr 3 2023 Remi Collet - 1.1.0-2 +- add workaround for regression in libsmbclient 4.16.9/4.17.5 + from https://github.com/eduardok/libsmbclient-php/pull/100 + * Mon Apr 3 2023 Remi Collet - 1.1.0-1 - update to 1.1.0 - drop patch merged upstream 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)); + } + + /** -- cgit