Repository navigation
fix(cp): bound and anchor the name-normalization rules - #300
Merged
Merged
Conversation
netravnen
force-pushed
the
fix/cp-name-normalization-guards
branch
from
August 19, 2026 22:27
1bedc3e to
cd6edae
Compare
netravnen
force-pushed
the
fix/cp-name-normalization-guards
branch
from
August 19, 2026 22:28
cd6edae to
2131890
Compare
netravnen
force-pushed
the
fix/cp-name-normalization-guards
branch
from
August 19, 2026 22:29
2131890 to
90f8124
Compare
netravnen
force-pushed
the
fix/cp-name-normalization-guards
branch
from
August 19, 2026 22:31
90f8124 to
fd35790
Compare
Four defects in lib/cp-name-normalization.js let third-party RDAP strings either freeze the tab or silently corrupt an organization name that an admin then approves. All four were reproduced by execution before being fixed, and each guard was proven to fail without its fix. A separator-dense name backtracks quadratically through the legal-form patterns -- 6,400 characters measured about 1.9 seconds, 20,000 took 20. Two other rules matched in the wrong place: the trading-as extraction was unanchored, so "DBA Systems Inc" became "Systems Inc" and "Sundba Media Group" became "Media Group"; and the Polish civil-partnership rule let a *leading* S.C. match with nothing before it, so Romania's "Societate Comerciala" prefix collapsed "S.C. Digital Cable Systems Romania SRL" to "S.C". The "Trade Me" false-positive guard compared the function's input rather than the working candidate, so it held for the bare brand and evaporated on the commoner registered form, leaving "Trade". Changes: - Add MAX_NORMALIZABLE_NAME_LENGTH (200) and return early from stripCompanyTypeSuffix above it. The quadratic patterns remain but are unreachable with a pathological input; rewriting 150+ jurisdiction patterns would risk exactly the silent regressions this module's characterization suite exists to catch. - Extract the false-positive list into KNOWN_INTACT_NAMES plus an isKnownIntactName() helper, and consult it on every pass of the suffix-strip loop rather than once on the input. - Anchor sanitizeRdapOrgName's trading-as regex and take its second group, matching the already-correct twin in parseRdapTradingAsIdentity instead of keeping a second, divergent copy. - Require a company part before the marker in parsePolishScPartnerIdentity (`.+?\s+S.C.` rather than `.*?\bS.C.`). Security: - Removes a denial-of-service reachable from unvalidated third-party RDAP data: a long org name froze the admin's tab for seconds per call. - The two anchoring fixes remove silent data corruption on a path whose output an admin approves into PeeringDB; a truncated or mis-split legal name previously looked like a legitimate normalization result. Testing: - node --test: 505 tests, 504 pass, 1 skipped (live tests are opt-in). - Five new cases in tests/cp-name-normalization.test.js covering all four defects plus the inputs that must keep working: the genuine Polish "NET-KONT@KT S.C." split, a real "trading as" extraction, and a long-but-plausible name that must still normalize. - Each fix reverted individually and confirmed red: the length guard (20s, then failure), the per-layer Trade Me guard, the anchored trading-as regex, and the required S.C. company part. - build_userscripts.py regenerated CP and reports up to date; all three .user.js pass node --check. Backwards Compatibility: - No API or storage changes. Behavior changes only for inputs that were previously mishandled; the existing characterization suite, which locks in current output for every other shape, is unchanged and still green. Assisted-by: Claude:claude-opus-5
netravnen
force-pushed
the
fix/cp-name-normalization-guards
branch
from
August 19, 2026 23:05
fd35790 to
fddc4a7
Compare
netravnen
marked this pull request as ready for review
August 19, 2026 23:06
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four defects in lib/cp-name-normalization.js let third-party RDAP strings
either freeze the tab or silently corrupt an organization name that an
admin then approves. All four were reproduced by execution before being
fixed, and each guard was proven to fail without its fix.
A separator-dense name backtracks quadratically through the legal-form
patterns -- 6,400 characters measured about 1.9 seconds, 20,000 took 20.
Two other rules matched in the wrong place: the trading-as extraction was
unanchored, so "DBA Systems Inc" became "Systems Inc" and "Sundba Media
Group" became "Media Group"; and the Polish civil-partnership rule let a
leading S.C. match with nothing before it, so Romania's "Societate
Comerciala" prefix collapsed "S.C. Digital Cable Systems Romania SRL" to
"S.C". The "Trade Me" false-positive guard compared the function's input
rather than the working candidate, so it held for the bare brand and
evaporated on the commoner registered form, leaving "Trade".
Changes:
stripCompanyTypeSuffix above it. The quadratic patterns remain but are
unreachable with a pathological input; rewriting 150+ jurisdiction
patterns would risk exactly the silent regressions this module's
characterization suite exists to catch.
isKnownIntactName() helper, and consult it on every pass of the
suffix-strip loop rather than once on the input.
group, matching the already-correct twin in parseRdapTradingAsIdentity
instead of keeping a second, divergent copy.
(
.+?\s+S.C.rather than.*?\bS.C.).Security:
data: a long org name froze the admin's tab for seconds per call.
output an admin approves into PeeringDB; a truncated or mis-split legal
name previously looked like a legitimate normalization result.
Testing:
defects plus the inputs that must keep working: the genuine Polish
"NET-KONT@KT S.C." split, a real "trading as" extraction, and a
long-but-plausible name that must still normalize.
(20s, then failure), the per-layer Trade Me guard, the anchored
trading-as regex, and the required S.C. company part.
.user.js pass node --check.
Backwards Compatibility:
previously mishandled; the existing characterization suite, which locks
in current output for every other shape, is unchanged and still green.
Assisted-by: Claude:claude-opus-5
Stack created with GitHub Stacks CLI • Give Feedback 💬