]> granicus.if.org Git - php/commitdiff
Promote pack/unpack format errors
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 22 Sep 2020 12:08:13 +0000 (14:08 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 22 Sep 2020 13:12:05 +0000 (15:12 +0200)
Errors related to invalid format strings (unlike data mismatch
errors) should throw ValueError.

Closes GH-6185.

ext/opcache/Optimizer/zend_func_info.c
ext/standard/basic_functions.stub.php
ext/standard/basic_functions_arginfo.h
ext/standard/pack.c
ext/standard/tests/strings/bug78833.phpt
ext/standard/tests/strings/pack64_32.phpt
ext/standard/tests/strings/unpack.phpt [deleted file]
ext/standard/tests/strings/unpack_error.phpt

index 936e8a8915ff48f49b3183b65521cee0474cfe22..e3b4da720c4d17ad77efd6ae4ab115b901f768f7 100644 (file)
@@ -324,7 +324,7 @@ static const func_info_t func_infos[] = {
        F1("realpath",                     MAY_BE_FALSE | MAY_BE_STRING),
        F1("fsockopen",                    MAY_BE_FALSE | MAY_BE_RESOURCE),
        FN("pfsockopen",                   MAY_BE_FALSE | MAY_BE_RESOURCE),
-       F1("pack",                         MAY_BE_FALSE | MAY_BE_STRING),
+       F1("pack",                         MAY_BE_STRING),
        F1("unpack",                       MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY),
        F1("get_browser",                  MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_OBJECT | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ANY),
        F1("crypt",                        MAY_BE_STRING),
index 0bc7bd8aef7548b9d1459d60141cd28e0afc009d..58f09ca2a19ba42de39f3ec5dc664442a1ad35af 100755 (executable)
@@ -1134,7 +1134,7 @@ function getrusage(int $who = 0): array|false {}
 
 /* pack.c */
 
-function pack(string $format, mixed ...$args): string|false {}
+function pack(string $format, mixed ...$args): string {}
 
 function unpack(string $format, string $data, int $offset = 0): array|false {}
 
index 6aff74adcfd3a58e74722093624e530026761c8a..1c90803d96dff8630416bdcf588955edb49fbd97 100644 (file)
@@ -1,5 +1,5 @@
 /* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 3c02183529eed2eb21d801ed2ba615deaf749b1d */
+ * Stub hash: f029ab7f1d9fa2a99a5612a928d0b731de6aaeed */
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0)
        ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0)
@@ -1747,10 +1747,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_getrusage, 0, 0, MAY_BE_ARRAY|MA
 ZEND_END_ARG_INFO()
 #endif
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pack, 0, 1, MAY_BE_STRING|MAY_BE_FALSE)
-       ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0)
-       ZEND_ARG_VARIADIC_TYPE_INFO(0, args, IS_MIXED, 0)
-ZEND_END_ARG_INFO()
+#define arginfo_pack arginfo_sprintf
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_unpack, 0, 2, MAY_BE_ARRAY|MAY_BE_FALSE)
        ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0)
index bbae59c6ae9c0ef8276b1daf393fb4df4d0bc2ee..bfa6708f66d862b3e4319aea5239957eb08ecab7 100644 (file)
@@ -47,8 +47,8 @@
        if ((a) < 0 || ((INT_MAX - outputpos)/((int)b)) < (a)) { \
                efree(formatcodes);     \
                efree(formatargs);      \
-               php_error_docref(NULL, E_WARNING, "Type %c: integer overflow in format string", code); \
-               RETURN_FALSE; \
+               zend_value_error("Type %c: integer overflow in format string", code); \
+               RETURN_THROWS(); \
        } \
        outputpos += (a)*(b);
 
@@ -282,8 +282,8 @@ PHP_FUNCTION(pack)
                                if (currentarg >= num_args) {
                                        efree(formatcodes);
                                        efree(formatargs);
-                                       php_error_docref(NULL, E_WARNING, "Type %c: not enough arguments", code);
-                                       RETURN_FALSE;
+                                       zend_value_error("Type %c: not enough arguments", code);
+                                       RETURN_THROWS();
                                }
 
                                if (arg < 0) {
@@ -313,8 +313,8 @@ PHP_FUNCTION(pack)
 #if SIZEOF_ZEND_LONG < 8
                                        efree(formatcodes);
                                        efree(formatargs);
-                                       php_error_docref(NULL, E_WARNING, "64-bit format codes are not available for 32-bit versions of PHP");
-                                       RETURN_FALSE;
+                                       zend_value_error("64-bit format codes are not available for 32-bit versions of PHP");
+                                       RETURN_THROWS();
 #endif
                        case 'c':
                        case 'C':
@@ -346,16 +346,16 @@ PHP_FUNCTION(pack)
 too_few_args:
                                        efree(formatcodes);
                                        efree(formatargs);
-                                       php_error_docref(NULL, E_WARNING, "Type %c: too few arguments", code);
-                                       RETURN_FALSE;
+                                       zend_value_error("Type %c: too few arguments", code);
+                                       RETURN_THROWS();
                                }
                                break;
 
                        default:
                                efree(formatcodes);
                                efree(formatargs);
-                               php_error_docref(NULL, E_WARNING, "Type %c: unknown format code", code);
-                               RETURN_FALSE;
+                               zend_value_error("Type %c: unknown format code", code);
+                               RETURN_THROWS();
                }
 
                formatcodes[formatcount] = code;
@@ -845,9 +845,9 @@ PHP_FUNCTION(unpack)
                                size = 8;
                                break;
 #else
-                               php_error_docref(NULL, E_WARNING, "64-bit format codes are not available for 32-bit versions of PHP");
+                               zend_value_error("64-bit format codes are not available for 32-bit versions of PHP");
                                zend_array_destroy(Z_ARR_P(return_value));
-                               RETURN_FALSE;
+                               RETURN_THROWS();
 #endif
 
                        /* Use sizeof(float) bytes of input */
@@ -865,10 +865,9 @@ PHP_FUNCTION(unpack)
                                break;
 
                        default:
-                               php_error_docref(NULL, E_WARNING, "Invalid format type %c", type);
+                               zend_value_error("Invalid format type %c", type);
                                zend_array_destroy(Z_ARR_P(return_value));
-                               RETURN_FALSE;
-                               break;
+                               RETURN_THROWS();
                }
 
                if (size != 0 && size != -1 && size < 0) {
index 763b6ec4eac322c3beec6a6dc91279087a51af32..7712e133facecc0edf5b6583836cac9bb05a8ee3 100644 (file)
@@ -2,8 +2,11 @@
 Bug #78833 (Integer overflow in pack causes out-of-bound access)
 --FILE--
 <?php
-var_dump(pack("E2E2147483647H*", 0x0, 0x0, 0x0));
+try {
+    var_dump(pack("E2E2147483647H*", 0x0, 0x0, 0x0));
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
 ?>
---EXPECTF--
-Warning: pack(): Type E: too few arguments in %s on line %d
-bool(false)
+--EXPECT--
+Type E: too few arguments
index 978e04449de612eeb0afaf1f734f5e262978db01..87e945c5fac66d2631bf646d198e3033598d7f0c 100644 (file)
@@ -8,37 +8,55 @@ if (PHP_INT_SIZE > 4) {
 ?>
 --FILE--
 <?php
-var_dump(pack("Q", 0));
-var_dump(pack("J", 0));
-var_dump(pack("P", 0));
-var_dump(pack("q", 0));
+try {
+    var_dump(pack("Q", 0));
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    var_dump(pack("J", 0));
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    var_dump(pack("P", 0));
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    var_dump(pack("q", 0));
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+
+try {
+    var_dump(unpack("Q", ''));
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    var_dump(unpack("J", ''));
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    var_dump(unpack("P", ''));
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    var_dump(unpack("q", ''));
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
 
-var_dump(unpack("Q", ''));
-var_dump(unpack("J", ''));
-var_dump(unpack("P", ''));
-var_dump(unpack("q", ''));
 ?>
 --EXPECTF--
-Warning: pack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
-bool(false)
-
-Warning: pack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
-bool(false)
-
-Warning: pack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
-bool(false)
-
-Warning: pack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
-bool(false)
-
-Warning: unpack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
-bool(false)
-
-Warning: unpack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
-bool(false)
-
-Warning: unpack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
-bool(false)
-
-Warning: unpack(): 64-bit format codes are not available for 32-bit versions of PHP in %s on line %d
-bool(false)
+64-bit format codes are not available for 32-bit versions of PHP
+64-bit format codes are not available for 32-bit versions of PHP
+64-bit format codes are not available for 32-bit versions of PHP
+64-bit format codes are not available for 32-bit versions of PHP
+64-bit format codes are not available for 32-bit versions of PHP
+64-bit format codes are not available for 32-bit versions of PHP
+64-bit format codes are not available for 32-bit versions of PHP
+64-bit format codes are not available for 32-bit versions of PHP
diff --git a/ext/standard/tests/strings/unpack.phpt b/ext/standard/tests/strings/unpack.phpt
deleted file mode 100644 (file)
index 435361c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---TEST--
-Invalid format type validation
---FILE--
-<?php
-    var_dump(unpack("-2222", 1));
-    echo "Done\n";
-?>
---EXPECTF--
-Warning: unpack(): Invalid format type - in %sunpack.php on line %d
-bool(false)
-Done
index 5da3cee2733727afb94809ce13bfd6f702a1ae2e..c41185b23acef8d328121a0065a32e82c2786335 100644 (file)
@@ -3,16 +3,12 @@ Test unpack() function : error conditions
 --FILE--
 <?php
 
-echo "*** Testing unpack() : error conditions ***\n";
+try {
+    var_dump(unpack("B", pack("I", 65534)));
+} catch (ValueError $e) {
+    echo $e->getMessage(), "\n";
+}
 
-echo "\n-- Testing unpack() function with invalid format character --\n";
-$extra_arg = 10;
-var_dump(unpack("B", pack("I", 65534)));
 ?>
---EXPECTF--
-*** Testing unpack() : error conditions ***
-
--- Testing unpack() function with invalid format character --
-
-Warning: unpack(): Invalid format type B in %s on line %d
-bool(false)
+--EXPECT--
+Invalid format type B