This is an automated email from the ASF dual-hosted git repository. chibenwa pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-mime4j.git
commit 9b76561f927920e34da53e4cb97af1cab69b1506 Author: Benoit TELLIER <[email protected]> AuthorDate: Mon Nov 2 15:26:13 2026 +0000 [FIX] Strict Content-Language parser: a subtag needs its hyphen, without whitespace The alternative of the subtag loop held a bare ALPHANUM, the "-" being in the first alternative only, and its action still added a "-": "en 4t" read as en-4t. Whitespace is a special token, so "zh-Hant- in" read as zh-Hant-in. A subtag is now "-" then ALPHA or ALPHANUM, and whitespace around that "-" is a parse error. --- .../mime4j/field/language/ContentLanguageParser.jj | 21 +++++++++--------- .../mime4j/field/ContentLanguageFieldTest.java | 25 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/dom/src/main/javacc/org/apache/james/mime4j/field/language/ContentLanguageParser.jj b/dom/src/main/javacc/org/apache/james/mime4j/field/language/ContentLanguageParser.jj index 11c0c698..f8b33ae9 100644 --- a/dom/src/main/javacc/org/apache/james/mime4j/field/language/ContentLanguageParser.jj +++ b/dom/src/main/javacc/org/apache/james/mime4j/field/language/ContentLanguageParser.jj @@ -79,6 +79,7 @@ private List<String> doParse() : String language() : { Token token; + Token dash; StringBuffer languageTag = new StringBuffer(); String result; } @@ -88,19 +89,17 @@ String language() : languageTag.append(token.image); } ( - "-" + dash = "-" // This keeps TOKENising simple - token = <ALPHA> - { - languageTag.append('-'); - languageTag.append(token.image); - } - | - token = <ALPHANUM> - { - languageTag.append('-'); - languageTag.append(token.image); + ( token = <ALPHA> | token = <ALPHANUM> ) + { + // A subtag directly follows its "-": no whitespace inside a tag + if (dash.specialToken != null || token.specialToken != null) { + throw new ParseException("Whitespace inside language tag " + languageTag + "-" + token.image); } + languageTag.append('-'); + languageTag.append(token.image); + } )* { diff --git a/dom/src/test/java/org/apache/james/mime4j/field/ContentLanguageFieldTest.java b/dom/src/test/java/org/apache/james/mime4j/field/ContentLanguageFieldTest.java index b6d809cb..1e3615d5 100644 --- a/dom/src/test/java/org/apache/james/mime4j/field/ContentLanguageFieldTest.java +++ b/dom/src/test/java/org/apache/james/mime4j/field/ContentLanguageFieldTest.java @@ -19,6 +19,7 @@ package org.apache.james.mime4j.field; +import java.util.Arrays; import java.util.List; import org.apache.james.mime4j.MimeException; @@ -85,4 +86,28 @@ public class ContentLanguageFieldTest extends TestCase { assertEquals(2, f.getLanguages().size()); assertNull(f.getParseException()); } + + public void testSubtagWithoutHyphenIsAParseError() throws Exception { + ContentLanguageField f = parse("Content-Language: en 4t"); + List<String> langs = f.getLanguages(); + assertNotNull(f.getParseException()); + assertFalse(langs.contains("en-4t")); + } + + public void testWhitespaceInsideTagIsAParseError() throws Exception { + for (String value : new String[] {"en-US, zh-Hant- in", "en -US", "et-\r\n n", "en- 4t"}) { + ContentLanguageField f = parse("Content-Language: " + value); + assertEquals(value, 0, f.getLanguages().size()); + assertNotNull(value, f.getParseException()); + } + } + + public void testValidTagsStillParse() throws Exception { + ContentLanguageField f = parse("Content-Language: en-US, zh-Hant-TW, x-4t"); + assertEquals(Arrays.asList("en-US", "zh-Hant-TW", "x-4t"), f.getLanguages()); + assertNull(f.getParseException()); + f = parse("Content-Language: en-US , de ,fr"); + assertEquals(Arrays.asList("en-US", "de", "fr"), f.getLanguages()); + assertNull(f.getParseException()); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
