[pecl-file_formats-yaml] yaml12-schema-support: address reviews

From: Date: Fri, 10 Apr 2026 21:09:12 +0000
Subject: [pecl-file_formats-yaml] yaml12-schema-support: address reviews
Groups: php.pecl.cvs 
Request: Send a blank email to pecl-cvs+get-28529@lists.php.net to get a copy of this message
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) "-" +}

« previous php.pecl.cvs (#28529) next »