[PECL-CVS] [pecl-file_formats-yaml] yaml12-schema-support: address reviews
[email protected] (Rasmus Lerdorf) Fri, 10 Apr 2026 21:09:12 +0000
| Newsgroups | php.pecl.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: Rasmus Lerdorf (rlerdorf)
Date: 2026-04-10T17:09:07-04:00
Commit: https://github.com/php/pecl-file_formats-yaml/commit/30b307fefc6671b78b31ad2f15166d1c3a48c133
Raw diff: https://github.com/php/pecl-file_formats-yaml/commit/30b307fefc6671b78b31ad2f15166d1c3a48c133.diff
address reviews
Changed paths:
A tests/yaml_parse_schema_12_edge_cases.phpt
A tests/yaml_parse_schema_12_not_numeric.phpt
M detect.c
Diff:
diff --git a/detect.c b/detect.c
index 5af2f72..63caa7e 100644
--- a/detect.c
+++ b/detect.c
@@ -674,11 +674,19 @@ scalar_is_bool_12(const char *value, size_t length, const yaml_event_t *event)
} else if (NULL != event &&
IS_NOT_IMPLICIT_AND_TAG_IS((*event), YAML_BOOL_TAG)) {
- if (0 == length || (1 == length && '0' == *value)) {
- return 0;
- } else {
+ /* explicit !!bool tag: parse true/false values */
+ if (STR_EQ("true", value) || STR_EQ("True", value) ||
+ STR_EQ("TRUE", value) ||
+ (1 == length && '1' == *value)) {
return 1;
}
+ if (STR_EQ("false", value) || STR_EQ("False", value) ||
+ STR_EQ("FALSE", value) ||
+ 0 == length || (1 == length && '0' == *value)) {
+ return 0;
+ }
+ /* unknown value with explicit bool tag, treat as true for compat */
+ return 1;
}
return -1;
@@ -811,6 +819,10 @@ scalar_is_numeric_12(const char *value, size_t length, zend_long *lval,
} else if (*value == '.') {
goto check_float_12;
+ } else if (*value == 'E' || *value == 'e') {
+ type = Y_SCALAR_IS_FLOAT | Y_SCALAR_IS_DECIMAL;
+ goto check_exp_12;
+
} else {
/* bare 0 followed by other digits is not valid in 1.2 */
goto not_numeric_12;
@@ -838,17 +850,22 @@ scalar_is_numeric_12(const char *value, size_t length, zend_long *lval,
type = Y_SCALAR_IS_INT | Y_SCALAR_IS_DECIMAL;
} else if (*value == '.') {
- /* float starting with dot: .[0-9]+ */
+ /* float starting with dot: .[0-9]+ requires digit after dot */
+ if (value + 1 >= end || *(value + 1) < '0' || *(value + 1) > '9') {
+ goto not_numeric_12;
+ }
*ptr++ = '0';
check_float_12:
*ptr++ = *value++;
if (value == end) {
- /* trailing dot with no digits - not a number */
- goto not_numeric_12;
+ /* trailing dot (e.g., 1.) — accept as float */
+ *ptr++ = '0';
+ type = Y_SCALAR_IS_FLOAT | Y_SCALAR_IS_DECIMAL;
+ goto terminate_12;
}
- /* need at least one digit, or could be exponent directly */
+ /* parse fractional digits and optional exponent */
while (value < end) {
if (*value >= '0' && *value <= '9') {
*ptr++ = *value++;
diff --git a/tests/yaml_parse_schema_12_edge_cases.phpt b/tests/yaml_parse_schema_12_edge_cases.phpt
new file mode 100644
index 0000000..c54d089
--- /dev/null
+++ b/tests/yaml_parse_schema_12_edge_cases.phpt
@@ -0,0 +1,61 @@
+--TEST--
+Yaml 1.2 Core Schema - edge cases (0e5, trailing dot, explicit bool tag)
+--SKIPIF--
+<?php if(!extension_loaded('yaml')) die('skip yaml n/a'); ?>
+--INI--
+yaml.decode_schema=2
+--FILE--
+<?php
+// Fix 1: 0e5 / 0E+10 should be valid floats
+// Fix 2: trailing dot (1., 0.) should be valid floats
+// Fix 3: explicit !!bool tag should parse true/false correctly
+var_dump(yaml_parse('
+# 0-prefixed exponent floats
+zero_exp: 0e5
+zero_exp_plus: 0E+10
+zero_exp_neg: 0e-3
+# trailing dot floats
+one_dot: 1.
+zero_dot: 0.
+neg_dot: -1.
+# trailing dot with exponent
+dot_exp: 1.e2
+# bare dot is NOT a float
+# explicit bool tags
+bool_false: !!bool "false"
+bool_true: !!bool "true"
+bool_FALSE: !!bool "FALSE"
+bool_TRUE: !!bool "TRUE"
+bool_zero: !!bool "0"
+bool_one: !!bool "1"
+'));
+?>
+--EXPECT--
+array(13) {
+ ["zero_exp"]=>
+ float(0)
+ ["zero_exp_plus"]=>
+ float(0)
+ ["zero_exp_neg"]=>
+ float(0)
+ ["one_dot"]=>
+ float(1)
+ ["zero_dot"]=>
+ float(0)
+ ["neg_dot"]=>
+ float(-1)
+ ["dot_exp"]=>
+ float(100)
+ ["bool_false"]=>
+ bool(false)
+ ["bool_true"]=>
+ bool(true)
+ ["bool_FALSE"]=>
+ bool(false)
+ ["bool_TRUE"]=>
+ bool(true)
+ ["bool_zero"]=>
+ bool(false)
+ ["bool_one"]=>
+ bool(true)
+}
diff --git a/tests/yaml_parse_schema_12_not_numeric.phpt b/tests/yaml_parse_schema_12_not_numeric.phpt
new file mode 100644
index 0000000..9c24892
--- /dev/null
+++ b/tests/yaml_parse_schema_12_not_numeric.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Yaml 1.2 Core Schema - values that are NOT numeric
+--SKIPIF--
+<?php if(!extension_loaded('yaml')) die('skip yaml n/a'); ?>
+--INI--
+yaml.decode_schema=2
+--FILE--
+<?php
+// Ensure these edge cases are correctly treated as strings
+var_dump(yaml_parse('
+bare_dot: .
+dot_e: .e5
+bare_plus: +
+bare_minus: "-"
+'));
+?>
+--EXPECT--
+array(4) {
+ ["bare_dot"]=>
+ string(1) "."
+ ["dot_e"]=>
+ string(3) ".e5"
+ ["bare_plus"]=>
+ string(1) "+"
+ ["bare_minus"]=>
+ string(1) "-"
+}