mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.4'
* PHP-8.4: Fix bug #79075: FFI header parser chokes on comments
This commit is contained in:
131
ext/ffi/ffi.c
131
ext/ffi/ffi.c
@@ -4995,38 +4995,85 @@ ZEND_METHOD(FFI_CType, getFuncParameterType) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static char *zend_ffi_skip_ws_and_comments(char *p, bool allow_standalone_newline)
|
||||
{
|
||||
while (true) {
|
||||
if (*p == ' ' || *p == '\t') {
|
||||
p++;
|
||||
} else if (allow_standalone_newline && (*p == '\r' || *p == '\n' || *p == '\f' || *p == '\v')) {
|
||||
p++;
|
||||
} else if (allow_standalone_newline && *p == '/' && p[1] == '/') {
|
||||
p += 2;
|
||||
while (*p && *p != '\r' && *p != '\n') {
|
||||
p++;
|
||||
}
|
||||
} else if (*p == '/' && p[1] == '*') {
|
||||
p += 2;
|
||||
while (*p && (*p != '*' || p[1] != '/')) {
|
||||
p++;
|
||||
}
|
||||
if (*p == '*') {
|
||||
p++;
|
||||
if (*p == '/') {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *zend_ffi_parse_directives(const char *filename, char *code_pos, char **scope_name, char **lib, bool preload) /* {{{ */
|
||||
{
|
||||
char *p;
|
||||
|
||||
code_pos = zend_ffi_skip_ws_and_comments(code_pos, true);
|
||||
|
||||
*scope_name = NULL;
|
||||
*lib = NULL;
|
||||
while (*code_pos == '#') {
|
||||
if (strncmp(code_pos, "#define FFI_SCOPE", sizeof("#define FFI_SCOPE") - 1) == 0
|
||||
&& (code_pos[sizeof("#define FFI_SCOPE") - 1] == ' '
|
||||
|| code_pos[sizeof("#define FFI_SCOPE") - 1] == '\t')) {
|
||||
p = code_pos + sizeof("#define FFI_SCOPE");
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
p++;
|
||||
if (strncmp(code_pos, ZEND_STRL("#define")) == 0) {
|
||||
p = zend_ffi_skip_ws_and_comments(code_pos + sizeof("#define") - 1, false);
|
||||
|
||||
char **target = NULL;
|
||||
const char *target_name = NULL;
|
||||
if (strncmp(p, ZEND_STRL("FFI_SCOPE")) == 0) {
|
||||
p = zend_ffi_skip_ws_and_comments(p + sizeof("FFI_SCOPE") - 1, false);
|
||||
target = scope_name;
|
||||
target_name = "FFI_SCOPE";
|
||||
} else if (strncmp(p, ZEND_STRL("FFI_LIB")) == 0) {
|
||||
p = zend_ffi_skip_ws_and_comments(p + sizeof("FFI_LIB") - 1, false);
|
||||
target = lib;
|
||||
target_name = "FFI_LIB";
|
||||
} else {
|
||||
while (*p && *p != '\n' && *p != '\r') {
|
||||
p++;
|
||||
}
|
||||
code_pos = zend_ffi_skip_ws_and_comments(p, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*p != '"') {
|
||||
if (preload) {
|
||||
zend_error(E_WARNING, "FFI: failed pre-loading '%s', bad FFI_SCOPE define", filename);
|
||||
zend_error(E_WARNING, "FFI: failed pre-loading '%s', bad %s define", filename, target_name);
|
||||
} else {
|
||||
zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', bad FFI_SCOPE define", filename);
|
||||
zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', bad %s define", filename, target_name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
p++;
|
||||
if (*scope_name) {
|
||||
if (*target) {
|
||||
if (preload) {
|
||||
zend_error(E_WARNING, "FFI: failed pre-loading '%s', FFI_SCOPE defined twice", filename);
|
||||
zend_error(E_WARNING, "FFI: failed pre-loading '%s', %s defined twice", filename, target_name);
|
||||
} else {
|
||||
zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', FFI_SCOPE defined twice", filename);
|
||||
zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', %s defined twice", filename, target_name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
*scope_name = p;
|
||||
*target = p;
|
||||
while (1) {
|
||||
if (*p == '\"') {
|
||||
*p = 0;
|
||||
@@ -5034,68 +5081,16 @@ static char *zend_ffi_parse_directives(const char *filename, char *code_pos, cha
|
||||
break;
|
||||
} else if (*p <= ' ') {
|
||||
if (preload) {
|
||||
zend_error(E_WARNING, "FFI: failed pre-loading '%s', bad FFI_SCOPE define", filename);
|
||||
zend_error(E_WARNING, "FFI: failed pre-loading '%s', bad %s define", filename, target_name);
|
||||
} else {
|
||||
zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', bad FFI_SCOPE define", filename);
|
||||
zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', bad %s define", filename, target_name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
p++;
|
||||
}
|
||||
while (*p == '\r' || *p == '\n') {
|
||||
p++;
|
||||
}
|
||||
code_pos = p;
|
||||
} else if (strncmp(code_pos, "#define FFI_LIB", sizeof("#define FFI_LIB") - 1) == 0
|
||||
&& (code_pos[sizeof("#define FFI_LIB") - 1] == ' '
|
||||
|| code_pos[sizeof("#define FFI_LIB") - 1] == '\t')) {
|
||||
p = code_pos + sizeof("#define FFI_LIB");
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
p++;
|
||||
}
|
||||
if (*p != '"') {
|
||||
if (preload) {
|
||||
zend_error(E_WARNING, "FFI: failed pre-loading '%s', bad FFI_LIB define", filename);
|
||||
} else {
|
||||
zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', bad FFI_LIB define", filename);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
p++;
|
||||
if (*lib) {
|
||||
if (preload) {
|
||||
zend_error(E_WARNING, "FFI: failed pre-loading '%s', FFI_LIB defined twice", filename);
|
||||
} else {
|
||||
zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', FFI_LIB defined twice", filename);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
*lib = p;
|
||||
while (1) {
|
||||
if (*p == '\"') {
|
||||
*p = 0;
|
||||
p++;
|
||||
break;
|
||||
} else if (*p <= ' ') {
|
||||
if (preload) {
|
||||
zend_error(E_WARNING, "FFI: failed pre-loading '%s', bad FFI_LIB define", filename);
|
||||
} else {
|
||||
zend_throw_error(zend_ffi_exception_ce, "Failed loading '%s', bad FFI_LIB define", filename);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
p++;
|
||||
}
|
||||
while (*p == '\r' || *p == '\n') {
|
||||
p++;
|
||||
}
|
||||
code_pos = p;
|
||||
|
||||
code_pos = zend_ffi_skip_ws_and_comments(p, true);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
12
ext/ffi/tests/bug79075.h
Normal file
12
ext/ffi/tests/bug79075.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Multiline comment
|
||||
*/
|
||||
// whitespace line
|
||||
|
||||
#define ignore_this_line 1
|
||||
//
|
||||
#define/* inline */FFI_SCOPE /* multi-
|
||||
line */ "bug79075" /* end
|
||||
*/
|
||||
|
||||
int printf(const char *format, ...);
|
||||
3
ext/ffi/tests/bug79075.inc
Normal file
3
ext/ffi/tests/bug79075.inc
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
FFI::load(__DIR__ . "/bug79075.h");
|
||||
25
ext/ffi/tests/bug79075.phpt
Normal file
25
ext/ffi/tests/bug79075.phpt
Normal file
@@ -0,0 +1,25 @@
|
||||
--TEST--
|
||||
Bug #79075 (FFI header parser chokes on comments)
|
||||
--EXTENSIONS--
|
||||
ffi
|
||||
opcache
|
||||
posix
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (substr(PHP_OS, 0, 3) == 'WIN') die('skip not for Windows');
|
||||
if (posix_geteuid() == 0) die('skip Cannot run test as root.');
|
||||
?>
|
||||
--INI--
|
||||
ffi.enable=1
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.optimization_level=-1
|
||||
opcache.preload={PWD}/bug79075.inc
|
||||
opcache.file_cache_only=0
|
||||
--FILE--
|
||||
<?php
|
||||
$ffi = FFI::scope("bug79075");
|
||||
$ffi->printf("Hello World from %s!\n", "PHP");
|
||||
?>
|
||||
--EXPECT--
|
||||
Hello World from PHP!
|
||||
Reference in New Issue
Block a user