Repository navigation
Conversation
Both filter ids had no arm in filter_var and fell through to the FILTER_DEFAULT catch-all, so every string validated. - 274: port of php_filter_validate_email (320-byte cap, then the logical_filters.c pattern; the \pL\pN /u variant under FILTER_FLAG_EMAIL_UNICODE). - 277: port of php_filter_validate_domain_ex (FILTER_FLAG_HOSTNAME label rules). A miss returns default_or_miss(), honouring the `default` option and FILTER_NULL_ON_FAILURE. Tests are oracle-verified against PHP 8.5.11. Fixes francescotinti#6
…ken from a pipe in 02b5a47) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ilter_validate.rs (emend of PR #7) tests/builtins.rs sits exactly at its `loc_dente` cap (4772 lines, REGOLE §8: caps rise only in a promotion commit), so the +34 lines of PR #7 made the dente test fail. The two tests move verbatim to a new integration-test file (unlisted files are capped at 2000) with the same `out` helper; tests/builtins.rs is back to 4772 lines. var.rs is the PR's, untouched. Expectations re-checked against the project oracle (php 8.5.7 CLI): both outputs byte-identical; the two PCRE patterns are byte-identical to php-src `regexp0`/`regexp1` (ext/filter/logical_filters.c). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Thanks — merged into
Why the follow-up: Independent checks here: the two PCRE patterns are byte-identical to php-src Closing this PR since the commits are on |
… into s186-firma — REGOLE §5 frozen corpus 1407, §3.36 trait __CLASS__/__METHOD__ catalogued, NEXT scoreboard/pre-flight/openings, session verbal Gates on the triage tree (dev-release): build rc=0, loc_dente rc=0 with no cap raised, battery 1755/0 (+3 new dente), corpus-gate rc=0 (names == frozen 1407 x2 modes, content == golden 1404, off/on zero diffs), oracle diff IDENTICAL on the filter_var and enum fixtures. Route B stays dead (S-186 bis rc=4). S-188 order unchanged: O(1) cure v2 -> pin s184 -> t26/t28 pair -> merge on user signature. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Problem
filter_var()had no arm for filter ids274(FILTER_VALIDATE_EMAIL) or277(FILTER_VALIDATE_DOMAIN). Both fell through to theFILTER_DEFAULTcatch-all, which returns the input unchanged, so every string validated:Fixes #6.
Change
crates/php-builtins/src/var.rs274 =>calls a newvalidate_email, a port ofphp_filter_validate_email(ext/filter/logical_filters.c). It rejects input over 320 bytes, then requires a full match of the same PCRE pattern:regexp1, orregexp0(\pL\pN,/u) underFILTER_FLAG_EMAIL_UNICODE. Both patterns are byte-identical to php-src, checked by script. Matching goes throughphp_runtime::pregthe same way theFILTER_VALIDATE_REGEXParm does.277 =>calls a newvalidate_domain, a port ofphp_filter_validate_domain_ex. It ignores one trailing dot, then checks the 253-byte total, no empty labels, labels of at most 63 bytes, and the alnum/-rules underFILTER_FLAG_HOSTNAME. The C code reads one byte past the label (s[1]), which sees the NUL terminator or the dropped trailing dot.at(i)reproduces that without going out of bounds.default_or_miss(), so thedefaultoption andFILTER_NULL_ON_FAILUREbehave as in PHP.No other arm or helper changed.
Tests
crates/php-builtins/tests/builtins.rs: two tests next tofilter_validate_regexp_miss_and_null_on_failure. Expected output is taken from PHP 8.5.11 (php:8.5-cli).filter_validate_emailcovers:+tagwith subdomains,[IPv4]and[IPv6:…]literals@, empty,a@b, leading space,.., trailing dot, a domain starting with-, a quoted local part with a space, a 65-byte local part, a 64-byte domain label, over 320 bytesFILTER_FLAG_EMAIL_UNICODEFILTER_NULL_ON_FAILUREanddefaultfilter_validate_domaincovers 16 inputs, each checked with and withoutFILTER_FLAG_HOSTNAME:., a trailing dot, leading and double dots-/_/space at the edges of a labelFILTER_NULL_ON_FAILUREanddefaultI also checked this on a small app that validates emails with
filter_var. Its PHPUnit suite went from 27/29 to 29/29 on phprust, and an HTTP check againstphp -S(same requests, compared response by response) went from 18/19 to 19/19 identical.