From c672e32c6672b5e53ab8e9cc4f150c21a05484c1 Mon Sep 17 00:00:00 2001 From: mohammadmseet-hue Date: Sat, 4 Jul 2026 04:29:00 +0200 Subject: [PATCH] language: count underscores in the ParseAcceptLanguage size limit ParseAcceptLanguage limits the number of dashes in its input to 1000 to bound the quadratic-time cost of the tag scanner on untrusted input (CVE-2022-32149, golang/go#56152). The scanner also treats '_' as a subtag separator, normalizing it to '-' before scanning, but the limit counts only '-'. Input that uses '_' as its separators therefore contains no dashes and is not subject to the limit, so it can still reach the quadratic scanner. Count '_' as well as '-' when enforcing the limit, and add a regression test. Updates golang/go#56152 --- language/parse.go | 7 ++++++- language/parse_test.go | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/language/parse.go b/language/parse.go index 053336e2..1bac5b10 100644 --- a/language/parse.go +++ b/language/parse.go @@ -166,7 +166,12 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { } }() - if strings.Count(s, "-") > 1000 { + // Reject excessively large input to avoid quadratic behavior in the + // scanner (see Go issue 56152). Underscores are treated as separators + // equivalent to dashes (they are normalized to '-' during scanning), so + // they must be counted here as well; otherwise an underscore-separated + // value bypasses this limit. + if strings.Count(s, "-")+strings.Count(s, "_") > 1000 { return nil, nil, errTagListTooLarge } diff --git a/language/parse_test.go b/language/parse_test.go index 0eee033e..116a1edc 100644 --- a/language/parse_test.go +++ b/language/parse_test.go @@ -406,4 +406,11 @@ func TestParseAcceptLanguageTooBig(t *testing.T) { if err != errTagListTooLarge { t.Errorf("ParseAcceptLanguage() unexpected error: got %v, want %v", err, errTagListTooLarge) } + + // Underscores are normalized to dashes by the scanner, so they are + // separators too and must be subject to the same limit. + u := strings.Repeat("en_x_a_", 333) + "en_x_a" + if _, _, err = ParseAcceptLanguage(u); err != errTagListTooLarge { + t.Errorf("ParseAcceptLanguage(underscores) unexpected error: got %v, want %v", err, errTagListTooLarge) + } }