{"record":{"id":"595b3d7b11f0844c","repo":"swc-project/swc","slug":"failed-to-parse-using-lexical","errorCode":null,"errorMessage":"failed to parse `{}` using lexical: {:?}","messagePattern":"failed to parse `(.+?)` using lexical: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_css_parser/src/parser/selectors/mod.rs","lineNumber":1389,"sourceCode":"                        };\n\n                        b = Some(b_sign * number.0 as i32);\n\n                        let mut b_raw_str = String::new();\n\n                        b_raw_str.push(' ');\n                        b_raw_str.push(b_sign_raw);\n                        b_raw_str.push(' ');\n                        b_raw_str.push_str(&number.1);\n                        b_raw = Some(self.input.atom(b_raw_str));\n                    }\n                    // '+'? <ndashdigit-ident>\n                    // <dashndashdigit-ident>\n                    // <ndashdigit-dimension>\n                    _ if dash_after_n == Some('-') => {\n                        let b_from_ident = &n_value[2..];\n                        let parsed: i32 = lexical::parse(b_from_ident).unwrap_or_else(|err| {\n                            unreachable!(\n                                \"failed to parse `{}` using lexical: {:?}\",\n                                b_from_ident, err\n                            )\n                        });\n\n                        b = Some(-parsed);\n\n                        let mut b_raw_str = String::new();\n\n                        b_raw_str.push('-');\n                        b_raw_str.push_str(b_from_ident);\n\n                        b_raw = Some(self.input.atom(b_raw_str));\n                    }\n                    // '+'? n\n                    // -n\n                    _ if dash_after_n.is_none() => {}\n                    _ => {","sourceCodeStart":1371,"sourceCodeEnd":1407,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_css_parser/src/parser/selectors/mod.rs#L1371-L1407","documentation":"This code parses the An+B microsyntax (`:nth-child(2n-3)`). In the branch for `n-<digits>` forms it feeds the digits after 'n-' to lexical's i32 parser inside unwrap_or_else(unreachable!) — the tokenizer already validated the shape, so failure means the digits are grammatically valid but overflow i32 (|B| beyond 2,147,483,647).","triggerScenarios":"Parsing a selector like `:nth-child(3n-99999999999)` or `:nth-last-of-type(2n+3000000000)` where the B component exceeds the signed 32-bit range.","commonSituations":"Machine-generated CSS (utility frameworks, spreadsheet/export tools) emitting enormous nth offsets; fuzzing corpora; minified third-party stylesheets with pathological selectors.","solutions":["Fix the selector: keep the B term of An+B within signed 32-bit range (usually `2n` or small offsets suffice)","Sanitize generated CSS before parsing: reject :nth-* selectors whose B component does not fit i32","Report the selector upstream — swc should return a parse error instead of panicking"],"exampleFix":"/* before */\nli:nth-child(2n-99999999999) { color: red }\n\n/* after */\nli:nth-child(2n) { color: red }","handlingStrategy":"validation","validationCode":"// Reject :nth-* selectors whose B term overflows i32 before parsing\nuse regex::Regex;\n\nfn nth_b_in_range(css: &str) -> bool {\n    let re = Regex::new(\n        r#\":nth(?:-last)?-(?:child|of-type)\\(\\s*[+-]?\\d*n[^)]*?([+-]\\s*\\d+)\"#,\n    ).unwrap();\n    re.captures_iter(css).all(|c| {\n        c[1].replace(' ', \"\").parse::<i32>().map(|_| true).unwrap_or(false)\n    })\n}\nassert!(nth_b_in_range(&css), \"nth-child B term exceeds i32\");","typeGuard":null,"tryCatchPattern":"match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| parse_css(&css))) {\n    Ok(v) => v,\n    Err(p) if panic_message(&p).contains(\"lexical\") => {\n        // fallback: strip/rewrite the oversized :nth-* selector and reparse\n    }\n    Err(p) => std::panic::resume_unwind(p),\n}","preventionTips":["Keep An+B offsets small and meaningful; huge B values are almost always generation bugs","Sanitize machine-generated selectors before handing CSS to the parser","Pin i32 bounds in your CSS generator's nth rules"],"tags":["swc","css","selector","nth-child","integer-overflow"],"backgroundTag":"anb-selector-overflow","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}