From 0033a243d080331806249d3a6ae7e7e399742ba9 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 8 Jan 2026 19:10:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=9B=B4=E5=A4=9A=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=EF=BC=8Cphp=20std=20=E6=A0=87=E5=87=86=E5=BA=93?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=EF=BC=8C=E6=94=AF=E6=8C=81=20list=20?= =?UTF-8?q?=E8=AF=AD=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/list.php | 2 + src/Php/Translator.php | 24 +++++ src/cpp/main.cc | 25 +++--- tests/aot/list.phpt | 14 +++ tests/std/directory/directory_constants.phpt | 26 ++++++ tests/std/serialize/002.phpt | 42 +++++++++ tests/std/time/001.phpt | 33 +++++++ tests/std/time/bug38524.phpt | 34 +++++++ tests/std/time/bug60222.phpt | 19 ++++ tests/std/time/idate.phpt | 33 +++++++ tests/std/time/idate_iso.phpt | 23 +++++ tests/std/time/strptime_basic.phpt | 95 ++++++++++++++++++++ tests/std/time/strptime_error.phpt | 25 ++++++ tests/std/time/strptime_parts.phpt | 69 ++++++++++++++ 14 files changed, 452 insertions(+), 12 deletions(-) create mode 100644 examples/list.php create mode 100644 tests/aot/list.phpt create mode 100644 tests/std/directory/directory_constants.phpt create mode 100644 tests/std/serialize/002.phpt create mode 100644 tests/std/time/001.phpt create mode 100644 tests/std/time/bug38524.phpt create mode 100644 tests/std/time/bug60222.phpt create mode 100644 tests/std/time/idate.phpt create mode 100644 tests/std/time/idate_iso.phpt create mode 100644 tests/std/time/strptime_basic.phpt create mode 100644 tests/std/time/strptime_error.phpt create mode 100644 tests/std/time/strptime_parts.phpt diff --git a/examples/list.php b/examples/list.php new file mode 100644 index 00000000..74ebe13f --- /dev/null +++ b/examples/list.php @@ -0,0 +1,2 @@ +items; + $code = '{'; + $this->indentLevel++; + $tmpVar = $this->genTmpVarName(); + $this->addLocalVar($tmpVar, self::TYPE_VAR); + $code .= $this->getIndent() . $tmpVar . ' = ' . $this->parseExpr($right) . '; '; + foreach ($items as $k => $item) { + if (!$item) { + continue; + } + if ($item instanceof Node\Expr\ArrayItem) { + $var = $this->parseIdentifier($item->value); + if (!$this->hasVar($var)) { + $this->addLocalVar($var, self::TYPE_VAR); + } + $code .= "$var = $tmpVar.offsetGet($k); "; + } else { + abort($item); + } + } + $this->indentLevel--; + return $code . '}'; + } $var = $this->parseIdentifier($left); $expr = $this->parseExpr($right); diff --git a/src/cpp/main.cc b/src/cpp/main.cc index 2bbbc9e1..dbbccb56 100644 --- a/src/cpp/main.cc +++ b/src/cpp/main.cc @@ -4,6 +4,9 @@ #endif #include +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_void, 0, 0, IS_VOID, 0) +ZEND_END_ARG_INFO() + void php_main(); extern php::Var argc; @@ -13,21 +16,18 @@ extern void php_init_constant_vars(); extern void php_init_global_vars(); extern void php_unset_global_vars(); -static void throw_exception(zend_object *ex) { - zend_bailout(); +static ZEND_FUNCTION(main) { + php_main(); } +static const zend_function_entry ext_functions[] = { + ZEND_FE(main, arginfo_void) + ZEND_FE_END +}; + int main(int cpp_argc, char **cpp_argv) { php_embed_init(cpp_argc, cpp_argv); - - zend_execute_data fake_execute_data; - memset(&fake_execute_data, 0, sizeof(zend_execute_data)); - zend_function fake_func {}; - fake_func.type = ZEND_INTERNAL_FUNCTION; - fake_execute_data.func = &fake_func; - EG(current_execute_data) = &fake_execute_data; - - zend_throw_exception_hook = throw_exception; + zend_register_functions(nullptr, ext_functions, nullptr, 0); int rc = 0; #if PPROF_ON @@ -36,7 +36,7 @@ int main(int cpp_argc, char **cpp_argv) { zend_first_try { php_init_global_vars(); php_init_constant_vars(); - php_main(); + php::eval("main();"); } zend_catch { rc = EG(exit_status); @@ -51,5 +51,6 @@ int main(int cpp_argc, char **cpp_argv) { php_unset_global_vars(); php::request_shutdown(); php_embed_shutdown(); + return rc; } diff --git a/tests/aot/list.phpt b/tests/aot/list.phpt new file mode 100644 index 00000000..b09ebf41 --- /dev/null +++ b/tests/aot/list.phpt @@ -0,0 +1,14 @@ +--TEST-- +strlen +--FILE-- + +--EXPECTF-- +string(%d) "%s" +string(%d) "%s" +string(%d) "%s" diff --git a/tests/std/directory/directory_constants.phpt b/tests/std/directory/directory_constants.phpt new file mode 100644 index 00000000..f8e143bc --- /dev/null +++ b/tests/std/directory/directory_constants.phpt @@ -0,0 +1,26 @@ +--TEST-- +Test that the Directory extension constants are correctly defined. +--SKIPIF-- + +--FILE-- + +--EXPECT-- +/ +: +done diff --git a/tests/std/serialize/002.phpt b/tests/std/serialize/002.phpt new file mode 100644 index 00000000..9d06f22d --- /dev/null +++ b/tests/std/serialize/002.phpt @@ -0,0 +1,42 @@ +--TEST-- +Bug #25378 (unserialize() crashes with invalid data) +--FILE-- + +--EXPECTF-- +bool(false) +bool(true) +int(823) +string(0) "" +string(3) "foo" +array(1) { + [0]=> + string(2) "12" +} +array(2) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } +} +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "bar" + [2]=> + string(3) "baz" +} +object(stdClass)#%d (0) { +} diff --git a/tests/std/time/001.phpt b/tests/std/time/001.phpt new file mode 100644 index 00000000..afd32375 --- /dev/null +++ b/tests/std/time/001.phpt @@ -0,0 +1,33 @@ +--TEST-- +microtime() function +--SKIPIF-- + +--FILE-- + $last_t || ($time == $last_t && $micro >= $last_m)) { + $passed++; + } else if ($failed++ <=10) { + $result .= sprintf('%06d', $i).": $time $micro < $last_t $last_m\n"; + } + $last_m = $micro; + $last_t = $time; +} +echo "Passed: $passed\n"; +echo "Failed: $failed\n"; +echo $result; +?> +--EXPECT-- +Passed: 100000 +Failed: 0 diff --git a/tests/std/time/bug38524.phpt b/tests/std/time/bug38524.phpt new file mode 100644 index 00000000..81031963 --- /dev/null +++ b/tests/std/time/bug38524.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #38524 (strptime() does not initialize the internal date storage structure) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +array(9) { + ["tm_sec"]=> + int(0) + ["tm_min"]=> + int(0) + ["tm_hour"]=> + int(0) + ["tm_mday"]=> + int(20) + ["tm_mon"]=> + int(7) + ["tm_year"]=> + int(106) + ["tm_wday"]=> + int(0) + ["tm_yday"]=> + int(%d) + ["unparsed"]=> + string(0) "" +} diff --git a/tests/std/time/bug60222.phpt b/tests/std/time/bug60222.phpt new file mode 100644 index 00000000..0256e2de --- /dev/null +++ b/tests/std/time/bug60222.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #60222 (time_nanosleep() does validate input params) +--FILE-- +getMessage() . "\n"; + } + + try { + time_nanosleep(0, -1); + } catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; + } +?> +--EXPECT-- +time_nanosleep(): Argument #1 ($seconds) must be greater than or equal to 0 +time_nanosleep(): Argument #2 ($nanoseconds) must be greater than or equal to 0 diff --git a/tests/std/time/idate.phpt b/tests/std/time/idate.phpt new file mode 100644 index 00000000..dc006f7a --- /dev/null +++ b/tests/std/time/idate.phpt @@ -0,0 +1,33 @@ +--TEST-- +idate() function +--FILE-- + +--EXPECT-- +U: 1043324459 +Y: 2003 +o: 2003 +z: 22 +y: 3 +m: 1 +n: 1 +d: 23 +j: 23 +H: 12 +G: 12 +h: 12 +g: 12 +i: 20 +s: 59 +t: 31 +w: 4 +N: 4 +L: 0 +B: 556 +I: 0 +W: 4 diff --git a/tests/std/time/idate_iso.phpt b/tests/std/time/idate_iso.phpt new file mode 100644 index 00000000..326f8ecb --- /dev/null +++ b/tests/std/time/idate_iso.phpt @@ -0,0 +1,23 @@ +--TEST-- +idate() function: ISO Day-of-Week and ISO Year +--FILE-- + +--EXPECT-- +U: 1041808859 +w: 0 +N: 7 +W: 1 +U: 1072912859 +Y: 2003 +o: 2004 +W: 1 diff --git a/tests/std/time/strptime_basic.phpt b/tests/std/time/strptime_basic.phpt new file mode 100644 index 00000000..c9c25f2c --- /dev/null +++ b/tests/std/time/strptime_basic.phpt @@ -0,0 +1,95 @@ +--TEST-- +Test strptime() function : basic functionality +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Testing strptime() : basic functionality *** +array(9) { + ["tm_sec"]=> + int(0) + ["tm_min"]=> + int(0) + ["tm_hour"]=> + int(10) + ["tm_mday"]=> + int(2) + ["tm_mon"]=> + int(6) + ["tm_year"]=> + int(63) + ["tm_wday"]=> + int(2) + ["tm_yday"]=> + int(182) + ["unparsed"]=> + string(4) " GMT" +} +array(9) { + ["tm_sec"]=> + int(0) + ["tm_min"]=> + int(0) + ["tm_hour"]=> + int(10) + ["tm_mday"]=> + int(2) + ["tm_mon"]=> + int(6) + ["tm_year"]=> + int(163) + ["tm_wday"]=> + int(1) + ["tm_yday"]=> + int(182) + ["unparsed"]=> + string(0) "" +} +array(9) { + ["tm_sec"]=> + int(0) + ["tm_min"]=> + int(0) + ["tm_hour"]=> + int(10) + ["tm_mday"]=> + int(2) + ["tm_mon"]=> + int(6) + ["tm_year"]=> + int(0) + ["tm_wday"]=> + int(2) + ["tm_yday"]=> + int(182) + ["unparsed"]=> + string(0) "" +} diff --git a/tests/std/time/strptime_error.phpt b/tests/std/time/strptime_error.phpt new file mode 100644 index 00000000..3697124e --- /dev/null +++ b/tests/std/time/strptime_error.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test localtime() function : error conditions +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Testing strptime() : error conditions *** + +-- Testing strptime() function on failure -- +bool(false) diff --git a/tests/std/time/strptime_parts.phpt b/tests/std/time/strptime_parts.phpt new file mode 100644 index 00000000..006715ca --- /dev/null +++ b/tests/std/time/strptime_parts.phpt @@ -0,0 +1,69 @@ +--TEST-- +Test strptime() function : basic functionality +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Testing strptime() : basic functionality *** +int(20) +int(1) +int(10) +int(2) +int(6) +int(63) +int(20) +int(1) +int(10) +int(2) +int(6) +int(163) +int(0) +int(1) +int(10) +int(2) +int(6) +int(0)