summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemi Collet <remi@remirepo.net>2023-04-03 16:20:15 +0200
committerRemi Collet <remi@php.net>2023-04-03 16:20:15 +0200
commit6ab913b164493f95aceaf412e2108d7369a4f9c6 (patch)
treeeaecf75bb1e3d363948ee690978e7a19aa525349
parente8efd658b28f8f07c3555d011113c01d88aada39 (diff)
add workaround for regression in libsmbclient 4.16.9/4.17.5
from https://github.com/eduardok/libsmbclient-php/pull/100
-rw-r--r--php-smbclient.spec10
-rw-r--r--smbclient-bug98.patch185
2 files changed, 194 insertions, 1 deletions
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 <remi@remirepo.net> - 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 <remi@remirepo.net> - 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 <remi@remirepo.net>
+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 <remi@remirepo.net>
+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 <remi@remirepo.net>
+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));
+ }
+
+ /**