From 67f9b0b754654e76ef8d5b5539fb520541092950 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" <cmbecker69@gmx.de> Date: Tue, 28 Apr 2020 18:33:19 +0200 Subject: [PATCH] Fix #79532: sizeof off_t can be wrong We have to actually determine the proper `SIZEOF_OFF_T`. Interestingly, it is `4` on Windows x64. We also have to prevent the redefinition in pg_config.h. The clean solution would likely be to not include pg_config.h at all, but that's out of scope for BC reasons for now. --- NEWS | 4 ++++ build/php.m4 | 1 + ext/ffi/tests/bug79532.phpt | 38 ++++++++++++++++++++++++++++++++++++ ext/pdo_pgsql/pdo_pgsql.c | 1 + ext/pdo_pgsql/pgsql_driver.c | 1 + ext/pgsql/php_pgsql.h | 1 + ext/zend_test/php_test.h | 1 + ext/zend_test/test.c | 8 ++++++++ win32/build/config.w32.h.in | 1 + 9 files changed, 56 insertions(+) create mode 100644 ext/ffi/tests/bug79532.phpt diff --git a/NEWS b/NEWS index ba008a7ba7..f131225675 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +?? ??? ????, PHP 7.4.7 + +- FFI: + . Fixed bug #79532 (sizeof off_t can be wrong). (cmb) ?? ??? ????, PHP 7.4.6 diff --git a/build/php.m4 b/build/php.m4 index 7392876478..51fa37446a 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -2416,6 +2416,7 @@ AC_DEFUN([PHP_CHECK_STDINT_TYPES], [ AC_CHECK_SIZEOF([long]) AC_CHECK_SIZEOF([long long]) AC_CHECK_SIZEOF([size_t]) + AC_CHECK_SIZEOF([off_t]) AC_CHECK_TYPES([int8, int16, int32, int64, int8_t, int16_t, int32_t, int64_t, uint8, uint16, uint32, uint64, uint8_t, uint16_t, uint32_t, uint64_t, u_int8_t, u_int16_t, u_int32_t, u_int64_t], [], [], [ #if HAVE_STDINT_H # include <stdint.h> diff --git a/ext/ffi/tests/bug79532.phpt b/ext/ffi/tests/bug79532.phpt new file mode 100644 index 0000000000..b6887dc7cb --- /dev/null +++ b/ext/ffi/tests/bug79532.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #79532 (sizeof off_t can be wrong) +--SKIPIF-- +<?php +if (!extension_loaded('ffi')) die('skip ffi extension not available'); +if (!extension_loaded('zend-test')) die('skip zend-test extension not available'); +?> +--FILE-- +<?php +require_once('utils.inc'); + +$header = <<<HEADER +void bug79532(off_t *array, size_t elems); +HEADER; + +if (PHP_OS_FAMILY !== 'Windows') { + $ffi = FFI::cdef($header); +} else { + try { + $ffi = FFI::cdef($header, 'php_zend_test.dll'); + } catch (FFI\Exception $ex) { + $ffi = FFI::cdef($header, ffi_get_php_dll_name()); + } +} + +$array = FFI::new("off_t[3]"); +$ffi->bug79532($array, 3); +var_dump($array); +?> +--EXPECTF-- +object(FFI\CData:int%d_t[3])#%d (3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) +} diff --git a/ext/pdo_pgsql/pdo_pgsql.c b/ext/pdo_pgsql/pdo_pgsql.c index 8d60fe420b..8d4158198d 100644 --- a/ext/pdo_pgsql/pdo_pgsql.c +++ b/ext/pdo_pgsql/pdo_pgsql.c @@ -29,6 +29,7 @@ #include "php_pdo_pgsql_int.h" #ifdef HAVE_PG_CONFIG_H +#undef SIZEOF_OFF_T #include <pg_config.h> #endif diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index b6f008071c..403bfd611a 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -31,6 +31,7 @@ #include "pdo/php_pdo_driver.h" #include "pdo/php_pdo_error.h" #include "ext/standard/file.h" +#undef SIZEOF_OFF_T #include "pg_config.h" /* needed for PG_VERSION */ #include "php_pdo_pgsql.h" #include "php_pdo_pgsql_int.h" diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index cecd2cc95b..a6c884d912 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -51,6 +51,7 @@ extern zend_module_entry pgsql_module_entry; #endif #ifdef HAVE_PG_CONFIG_H +#undef SIZEOF_OFF_T #include <pg_config.h> #endif diff --git a/ext/zend_test/php_test.h b/ext/zend_test/php_test.h index 325484c434..da57f7efc9 100644 --- a/ext/zend_test/php_test.h +++ b/ext/zend_test/php_test.h @@ -38,5 +38,6 @@ struct bug79096 { }; ZEND_API struct bug79096 bug79096(void); +ZEND_API void bug79532(off_t *array, size_t elems); #endif diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index b097a2412b..dfae54e880 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -328,3 +328,11 @@ struct bug79096 bug79096(void) b.b = 1; return b; } + +void bug79532(off_t *array, size_t elems) +{ + int i; + for (i = 0; i < elems; i++) { + array[i] = i; + } +} diff --git a/win32/build/config.w32.h.in b/win32/build/config.w32.h.in index 864bc882ff..36a45fb76c 100644 --- a/win32/build/config.w32.h.in +++ b/win32/build/config.w32.h.in @@ -101,6 +101,7 @@ # define SIZEOF_SIZE_T 4 # define SIZEOF_PTRDIFF_T 4 #endif +#define SIZEOF_OFF_T 4 #define HAVE_FNMATCH #define HAVE_GLOB #define PHP_SHLIB_SUFFIX "dll" -- 2.40.0