From bfd51c821277afe89b4bf9dc4c0f1e27cec7c3eb Mon Sep 17 00:00:00 2001 From: Durvesh Pilankar Date: Fri, 26 Jun 2026 14:42:13 -0700 Subject: [PATCH] Fix length validators wrongly accepting comma-prefixed values isAbsoluteLength and isRelativeLength built their regex with the character class [-,+], which includes a literal comma. As a result the `valid-styles` ESLint rule accepted malformed lengths such as ',4px' and ',4rem'. Change [-,+] to [+-] in both validators so only an optional leading sign is allowed. Legitimate values (4px, -4px, +4px, 4rem, ...) still validate. This is the same defect fixed for the percentage validator in #1574, which did not touch the two length files. Added regression tests (textUnderlineOffset is length-only) that fail before the change and pass after; full eslint-plugin suite is green. --- .../__tests__/stylex-valid-styles-test.js | 56 +++++++++++++++++++ .../src/rules/isAbsoluteLength.js | 2 +- .../src/rules/isRelativeLength.js | 2 +- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/packages/@stylexjs/eslint-plugin/__tests__/stylex-valid-styles-test.js b/packages/@stylexjs/eslint-plugin/__tests__/stylex-valid-styles-test.js index 27f4cefbb..4963bf5df 100644 --- a/packages/@stylexjs/eslint-plugin/__tests__/stylex-valid-styles-test.js +++ b/packages/@stylexjs/eslint-plugin/__tests__/stylex-valid-styles-test.js @@ -2424,6 +2424,62 @@ revert`, }, ], }, + { + // A leading comma must not be accepted as a valid length. Regression + // test for the length validators previously using the character class + // `[-,+]`, which accidentally allowed a literal comma prefix. + // `textUnderlineOffset` is length-only (it does not accept arbitrary + // strings), so this exercises the length validators directly. + code: ` + import * as stylex from '@stylexjs/stylex'; + const styles = stylex.create({ + invalidStyle: { + textUnderlineOffset: ',4px', + }, + }); + `, + errors: [ + { + message: `textUnderlineOffset value must be one of: +auto +a number literal or math expression +a number ending in px, mm, in, pc, pt +a number ending in ch, em, ex, ic, rem, vh, vw, vmin, vmax, svh, dvh, lvh, svw, dvw, ldw, cqw, cqh, cqmin, cqmax +A string literal representing a percentage (e.g. 100%) +null +initial +inherit +unset +revert`, + }, + ], + }, + { + // Same as above, for the relative-length validator. + code: ` + import * as stylex from '@stylexjs/stylex'; + const styles = stylex.create({ + invalidStyle: { + textUnderlineOffset: ',4rem', + }, + }); + `, + errors: [ + { + message: `textUnderlineOffset value must be one of: +auto +a number literal or math expression +a number ending in px, mm, in, pc, pt +a number ending in ch, em, ex, ic, rem, vh, vw, vmin, vmax, svh, dvh, lvh, svw, dvw, ldw, cqw, cqh, cqmin, cqmax +A string literal representing a percentage (e.g. 100%) +null +initial +inherit +unset +revert`, + }, + ], + }, { code: ` import * as stylex from '@stylexjs/stylex'; diff --git a/packages/@stylexjs/eslint-plugin/src/rules/isAbsoluteLength.js b/packages/@stylexjs/eslint-plugin/src/rules/isAbsoluteLength.js index e017bbc0f..3d96bc3cc 100644 --- a/packages/@stylexjs/eslint-plugin/src/rules/isAbsoluteLength.js +++ b/packages/@stylexjs/eslint-plugin/src/rules/isAbsoluteLength.js @@ -26,7 +26,7 @@ const isAbsoluteLength: RuleCheck = ( if ( typeof val === 'string' && Array.from(absoluteLengthUnits).some((unit) => - val.match(new RegExp(`^([-,+]?\\d+(\\.\\d+)?${unit})$`)), + val.match(new RegExp(`^([+-]?\\d+(\\.\\d+)?${unit})$`)), ) ) { return undefined; diff --git a/packages/@stylexjs/eslint-plugin/src/rules/isRelativeLength.js b/packages/@stylexjs/eslint-plugin/src/rules/isRelativeLength.js index eacdbf307..ce7c68142 100644 --- a/packages/@stylexjs/eslint-plugin/src/rules/isRelativeLength.js +++ b/packages/@stylexjs/eslint-plugin/src/rules/isRelativeLength.js @@ -49,7 +49,7 @@ const isRelativeLength: RuleCheck = ( if ( typeof val === 'string' && Array.from(relativeLengthUnits).some((unit) => - val.match(new RegExp(`^([-,+]?\\d+(\\.\\d+)?${unit})$`)), + val.match(new RegExp(`^([+-]?\\d+(\\.\\d+)?${unit})$`)), ) ) { return undefined;