From 091d7c38593b480a83e60d4455797b8c285b260d Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Tue, 27 Jul 2021 13:17:47 -0500 Subject: [PATCH 1/5] Improve match() error messages. --- Zend/zend_vm_def.h | 20 +++++++++++++++++++- Zend/zend_vm_execute.h | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index e820aef46cf17..c4b96cde30880 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8935,7 +8935,25 @@ ZEND_VM_COLD_CONST_HANDLER(197, ZEND_MATCH_ERROR, CONST|TMPVARCV, UNUSED) SAVE_OPLINE(); op = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); + + // For simpler types where there is a convenient stringified version, include that + // in the error message. Otherwise just show its type. + switch (Z_TYPE_P(op)) { + case IS_FALSE: + case IS_TRUE: + case IS_LONG: + case IS_DOUBLE: + case IS_STRING: { + zend_string* stringified = zval_get_string(op); + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: %s", ZSTR_VAL(stringified)); + zend_string_release_ex(stringified, false); + break; + } + default: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); PUTS("UNKNOWN:0\n"); + break; + } + HANDLE_EXCEPTION(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 92acc5e9b32db..5e7a145899ff3 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -10507,7 +10507,25 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_ SAVE_OPLINE(); op = RT_CONSTANT(opline, opline->op1); - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); + + // For simpler types where there is a convenient stringified version, include that + // in the error message. Otherwise just show its type. + switch (Z_TYPE_P(op)) { + case IS_FALSE: + case IS_TRUE: + case IS_LONG: + case IS_DOUBLE: + case IS_STRING: { + zend_string* stringified = zval_get_string(op); + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: %s", ZSTR_VAL(stringified)); + zend_string_release_ex(stringified, false); + break; + } + default: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); PUTS("UNKNOWN:0\n"); + break; + } + HANDLE_EXCEPTION(); } @@ -14033,7 +14051,25 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUS SAVE_OPLINE(); op = EX_VAR(opline->op1.var); - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); + + // For simpler types where there is a convenient stringified version, include that + // in the error message. Otherwise just show its type. + switch (Z_TYPE_P(op)) { + case IS_FALSE: + case IS_TRUE: + case IS_LONG: + case IS_DOUBLE: + case IS_STRING: { + zend_string* stringified = zval_get_string(op); + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: %s", ZSTR_VAL(stringified)); + zend_string_release_ex(stringified, false); + break; + } + default: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); PUTS("UNKNOWN:0\n"); + break; + } + HANDLE_EXCEPTION(); } From d1975d7afd97f7250808ff362ce3ffb271c68183 Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Tue, 27 Jul 2021 15:27:55 -0500 Subject: [PATCH 2/5] Update tests. --- Zend/tests/match/006.phpt | 2 +- Zend/tests/match/007.phpt | 2 +- Zend/tests/match/037.phpt | 6 +++--- Zend/zend_vm_def.h | 6 +++++- Zend/zend_vm_execute.h | 12 ++++++++++-- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Zend/tests/match/006.phpt b/Zend/tests/match/006.phpt index fec28f82da631..cb731daea7baf 100644 --- a/Zend/tests/match/006.phpt +++ b/Zend/tests/match/006.phpt @@ -7,7 +7,7 @@ $x = match (true) {}; ?> --EXPECTF-- -Fatal error: Uncaught UnhandledMatchError: Unhandled match value of type bool in %s +Fatal error: Uncaught UnhandledMatchError: Unhandled match value: true in %s:%d Stack trace: #0 {main} thrown in %s on line %d diff --git a/Zend/tests/match/007.phpt b/Zend/tests/match/007.phpt index 7b442a66a03e5..ed79fe779609c 100644 --- a/Zend/tests/match/007.phpt +++ b/Zend/tests/match/007.phpt @@ -19,7 +19,7 @@ echo get_value(3) . "\n"; 1 2 -Fatal error: Uncaught UnhandledMatchError: Unhandled match value of type int in %s +Fatal error: Uncaught UnhandledMatchError: Unhandled match value: 3 in %s:%d Stack trace: #0 %s: get_value(3) #1 {main} diff --git a/Zend/tests/match/037.phpt b/Zend/tests/match/037.phpt index d3591fbfcba26..fb58221f1e379 100644 --- a/Zend/tests/match/037.phpt +++ b/Zend/tests/match/037.phpt @@ -53,13 +53,13 @@ var_dump(match(3) { ?> --EXPECTF-- -string(%d) "UnhandledMatchError: Unhandled match value of type bool in %s037.php:4 +string(%d) "UnhandledMatchError: Unhandled match value: true in %s:%d Stack trace: #0 {main}" -string(%d) "UnhandledMatchError: Unhandled match value of type int in %s037.php:12 +string(%d) "UnhandledMatchError: Unhandled match value: 6 in %s:%d Stack trace: #0 {main}" -string(%d) "UnhandledMatchError: Unhandled match value of type string in %s037.php:20 +string(%d) "UnhandledMatchError: Unhandled match value: 3 in %s:%d Stack trace: #0 {main}" string(3) "foo" diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index c4b96cde30880..75e7e387b41bd 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8940,7 +8940,11 @@ ZEND_VM_COLD_CONST_HANDLER(197, ZEND_MATCH_ERROR, CONST|TMPVARCV, UNUSED) // in the error message. Otherwise just show its type. switch (Z_TYPE_P(op)) { case IS_FALSE: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: false"); + break; case IS_TRUE: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: true"); + break; case IS_LONG: case IS_DOUBLE: case IS_STRING: { @@ -8950,7 +8954,7 @@ ZEND_VM_COLD_CONST_HANDLER(197, ZEND_MATCH_ERROR, CONST|TMPVARCV, UNUSED) break; } default: - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); PUTS("UNKNOWN:0\n"); + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); break; } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 5e7a145899ff3..80812e27c2ca2 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -10512,7 +10512,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_ // in the error message. Otherwise just show its type. switch (Z_TYPE_P(op)) { case IS_FALSE: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: false"); + break; case IS_TRUE: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: true"); + break; case IS_LONG: case IS_DOUBLE: case IS_STRING: { @@ -10522,7 +10526,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_ break; } default: - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); PUTS("UNKNOWN:0\n"); + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); break; } @@ -14056,7 +14060,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUS // in the error message. Otherwise just show its type. switch (Z_TYPE_P(op)) { case IS_FALSE: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: false"); + break; case IS_TRUE: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: true"); + break; case IS_LONG: case IS_DOUBLE: case IS_STRING: { @@ -14066,7 +14074,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUS break; } default: - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); PUTS("UNKNOWN:0\n"); + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); break; } From 00fc67bd785652e9652335b55f0aa685598a334f Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Tue, 27 Jul 2021 15:28:20 -0500 Subject: [PATCH 3/5] Add new test for error messages. --- Zend/tests/match/043.phpt | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Zend/tests/match/043.phpt diff --git a/Zend/tests/match/043.phpt b/Zend/tests/match/043.phpt new file mode 100644 index 0000000000000..140722da9437c --- /dev/null +++ b/Zend/tests/match/043.phpt @@ -0,0 +1,32 @@ +--TEST-- +Match expression error messages +--FILE-- +getMessage() . PHP_EOL; + } +} + +test(1); +test(5.5); +test("foo"); +test(true); +test(false); +test([1, 2, 3]); +test(new Beep()); + +?> +--EXPECT-- +Unhandled match value: 1 +Unhandled match value: 5.5 +Unhandled match value: foo +Unhandled match value: true +Unhandled match value: false +Unhandled match value of type array +Unhandled match value of type Beep From 2c58480e6156878503a8977858f8f9e5067b9b9f Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Tue, 27 Jul 2021 16:21:06 -0500 Subject: [PATCH 4/5] Code style fixes. --- Zend/zend_vm_def.h | 36 ++++++++++----------- Zend/zend_vm_execute.h | 72 +++++++++++++++++++++--------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 75e7e387b41bd..2f222f4369029 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8939,24 +8939,24 @@ ZEND_VM_COLD_CONST_HANDLER(197, ZEND_MATCH_ERROR, CONST|TMPVARCV, UNUSED) // For simpler types where there is a convenient stringified version, include that // in the error message. Otherwise just show its type. switch (Z_TYPE_P(op)) { - case IS_FALSE: - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: false"); - break; - case IS_TRUE: - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: true"); - break; - case IS_LONG: - case IS_DOUBLE: - case IS_STRING: { - zend_string* stringified = zval_get_string(op); - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: %s", ZSTR_VAL(stringified)); - zend_string_release_ex(stringified, false); - break; - } - default: - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); - break; - } + case IS_FALSE: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: false"); + break; + case IS_TRUE: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: true"); + break; + case IS_LONG: + case IS_DOUBLE: + case IS_STRING: { + zend_string* stringified = zval_get_string(op); + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: %s", ZSTR_VAL(stringified)); + zend_string_release_ex(stringified, false); + break; + } + default: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); + break; + } HANDLE_EXCEPTION(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 80812e27c2ca2..3785e83229edc 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -10511,24 +10511,24 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_ // For simpler types where there is a convenient stringified version, include that // in the error message. Otherwise just show its type. switch (Z_TYPE_P(op)) { - case IS_FALSE: - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: false"); - break; - case IS_TRUE: - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: true"); - break; - case IS_LONG: - case IS_DOUBLE: - case IS_STRING: { - zend_string* stringified = zval_get_string(op); - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: %s", ZSTR_VAL(stringified)); - zend_string_release_ex(stringified, false); - break; - } - default: - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); - break; - } + case IS_FALSE: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: false"); + break; + case IS_TRUE: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: true"); + break; + case IS_LONG: + case IS_DOUBLE: + case IS_STRING: { + zend_string* stringified = zval_get_string(op); + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: %s", ZSTR_VAL(stringified)); + zend_string_release_ex(stringified, false); + break; + } + default: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); + break; + } HANDLE_EXCEPTION(); } @@ -14059,24 +14059,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUS // For simpler types where there is a convenient stringified version, include that // in the error message. Otherwise just show its type. switch (Z_TYPE_P(op)) { - case IS_FALSE: - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: false"); - break; - case IS_TRUE: - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: true"); - break; - case IS_LONG: - case IS_DOUBLE: - case IS_STRING: { - zend_string* stringified = zval_get_string(op); - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: %s", ZSTR_VAL(stringified)); - zend_string_release_ex(stringified, false); - break; - } - default: - zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); - break; - } + case IS_FALSE: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: false"); + break; + case IS_TRUE: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: true"); + break; + case IS_LONG: + case IS_DOUBLE: + case IS_STRING: { + zend_string* stringified = zval_get_string(op); + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: %s", ZSTR_VAL(stringified)); + zend_string_release_ex(stringified, false); + break; + } + default: + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); + break; + } HANDLE_EXCEPTION(); } From 905c8b213fd2b838dd3abdc2c00c6cd732f5ca93 Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Thu, 29 Jul 2021 13:55:02 -0500 Subject: [PATCH 5/5] Quote and truncate string values in match errors. --- Zend/tests/match/037.phpt | 2 +- Zend/tests/match/043.phpt | 12 +++++++++++- Zend/zend_vm_def.h | 17 +++++++++++++++-- Zend/zend_vm_execute.h | 34 ++++++++++++++++++++++++++++++---- 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/Zend/tests/match/037.phpt b/Zend/tests/match/037.phpt index fb58221f1e379..2d561da74a53c 100644 --- a/Zend/tests/match/037.phpt +++ b/Zend/tests/match/037.phpt @@ -59,7 +59,7 @@ Stack trace: string(%d) "UnhandledMatchError: Unhandled match value: 6 in %s:%d Stack trace: #0 {main}" -string(%d) "UnhandledMatchError: Unhandled match value: 3 in %s:%d +string(%d) "UnhandledMatchError: Unhandled match value: "3" in %s:%d Stack trace: #0 {main}" string(3) "foo" diff --git a/Zend/tests/match/043.phpt b/Zend/tests/match/043.phpt index 140722da9437c..0e50bae15bb47 100644 --- a/Zend/tests/match/043.phpt +++ b/Zend/tests/match/043.phpt @@ -20,13 +20,23 @@ test(true); test(false); test([1, 2, 3]); test(new Beep()); +// Testing long strings. +test(str_repeat('e', 100)); +test(str_repeat("e\n", 100)); ?> --EXPECT-- Unhandled match value: 1 Unhandled match value: 5.5 -Unhandled match value: foo +Unhandled match value: "foo" Unhandled match value: true Unhandled match value: false Unhandled match value of type array Unhandled match value of type Beep +Unhandled match value: "eeeeeeeeee..." +Unhandled match value: "e +e +e +e +e +..." diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 2f222f4369029..00a8c617dc5c3 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8946,13 +8946,26 @@ ZEND_VM_COLD_CONST_HANDLER(197, ZEND_MATCH_ERROR, CONST|TMPVARCV, UNUSED) zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: true"); break; case IS_LONG: - case IS_DOUBLE: - case IS_STRING: { + case IS_DOUBLE: { zend_string* stringified = zval_get_string(op); zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: %s", ZSTR_VAL(stringified)); zend_string_release_ex(stringified, false); break; } + case IS_STRING: { + zend_string* stringified = zval_get_string(op); + // This number was chosen mostly arbitrarily. But in context, + // a match() on a string should only be using short strings so something + // longer is unlikely to happen to begin with. + const int max_strlen = 10; + if (ZSTR_LEN(stringified) > max_strlen) { + stringified = zend_string_realloc(stringified, max_strlen + 3, 0); + memcpy(&ZSTR_VAL(stringified)[max_strlen], "...", sizeof("...")); + } + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: \"%s\"", ZSTR_VAL(stringified)); + zend_string_release_ex(stringified, false); + break; + } default: zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); break; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 3785e83229edc..d513a8d720f0e 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -10518,13 +10518,26 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_ zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: true"); break; case IS_LONG: - case IS_DOUBLE: - case IS_STRING: { + case IS_DOUBLE: { zend_string* stringified = zval_get_string(op); zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: %s", ZSTR_VAL(stringified)); zend_string_release_ex(stringified, false); break; } + case IS_STRING: { + zend_string* stringified = zval_get_string(op); + // This number was chosen mostly arbitrarily. But in context, + // a match() on a string should only be using short strings so something + // longer is unlikely to happen to begin with. + const int max_strlen = 10; + if (ZSTR_LEN(stringified) > max_strlen) { + stringified = zend_string_realloc(stringified, max_strlen + 3, 0); + memcpy(&ZSTR_VAL(stringified)[max_strlen], "...", sizeof("...")); + } + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: \"%s\"", ZSTR_VAL(stringified)); + zend_string_release_ex(stringified, false); + break; + } default: zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); break; @@ -14066,13 +14079,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUS zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: true"); break; case IS_LONG: - case IS_DOUBLE: - case IS_STRING: { + case IS_DOUBLE: { zend_string* stringified = zval_get_string(op); zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: %s", ZSTR_VAL(stringified)); zend_string_release_ex(stringified, false); break; } + case IS_STRING: { + zend_string* stringified = zval_get_string(op); + // This number was chosen mostly arbitrarily. But in context, + // a match() on a string should only be using short strings so something + // longer is unlikely to happen to begin with. + const int max_strlen = 10; + if (ZSTR_LEN(stringified) > max_strlen) { + stringified = zend_string_realloc(stringified, max_strlen + 3, 0); + memcpy(&ZSTR_VAL(stringified)[max_strlen], "...", sizeof("...")); + } + zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value: \"%s\"", ZSTR_VAL(stringified)); + zend_string_release_ex(stringified, false); + break; + } default: zend_throw_exception_ex(zend_ce_unhandled_match_error, 0, "Unhandled match value of type %s", zend_zval_type_name(op)); break;