Bug 262140
| Summary: | SVGTests::isValid() does not correctly implement systemLanguage matching per SVG2 | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Ahmad Saleem <ahmad.saleem792> |
| Component: | SVG | Assignee: | Karl Dubost <karlcow> |
| Status: | NEW | ||
| Severity: | Normal | CC: | karlcow, sabouhallawa, simon.fraser, webkit-bug-importer, zimmermann |
| Priority: | P2 | Keywords: | BrowserCompat, InRadar |
| Version: | WebKit Nightly Build | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
| See Also: | https://bugs.webkit.org/show_bug.cgi?id=262146 | ||
Ahmad Saleem
Hi Team,
While going through Blink's commit, I came across another failing test case in Safari 17 (macOS Sonoma).
Test Case: https://jsfiddle.net/35yL6qnw/5/
^ above shows 'en FAIL' in Red (Safari) while show 'EN' in Black (Chrome Canary 119 and Firefox Nightly 120).
Blink Commit: https://chromium.googlesource.com/chromium/src.git/+/1f24b02c1e563e405a59d5d44eeb03a6f2c00d59
Web-Spec: https://www.w3.org/TR/SVG11/struct.html#ConditionalProcessingSystemLanguageAttribute
___
Just wanted to raise so we can fix it.
Thanks!
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Ahmad Saleem
Merge this as well: https://source.chromium.org/chromium/chromium/src/+/592442acb95d29bd54f068f70009a6ec47fa863b
Ahmad Saleem
static bool isLangTagPrefix(const String& langTag, const String& language)
{
if (!langTag.startsWithIgnoringASCIICase(language))
return false;
return langTag.length() == language.length() || langTag[language.length()] == '-';
}
static bool matchLanguageList(const String& langTag, const Vector<String>& languages)
{
for (const auto& value : languages) {
if (isLangTagPrefix(langTag, value))
return true;
}
return false;
}
and following changes here: "SVGTests::isValid()"
for (auto& langTag : attributes->systemLanguage().items()) {
if (matchLanguageList(langTag, genericDefaultLanguage))
return false;
}
___
It leads to following compile errors:
candidate function not viable: no known conversion from 'StringView' to 'const Vector<String>'
for 2nd argument
and
no matching function for call to 'matchLanguageList'
___
Still looking into it but if someone want to take it. Go ahead and run with it. Might not come back soon but good to share what tried to make it easier for others.
Karl Dubost
Probably fixing Bug 262146 first would help with this one.
Radar WebKit Bug Importer
<rdar://problem/116424326>
Karl Dubost
## Spec reference
https://w3c.github.io/svgwg/svg2-draft/struct.html#ConditionalProcessingSystemLanguageAttribute
> "Evaluates to "true" if one of the language tags indicated by user preferences
> is a case-insensitive match of one of the language tags given in the value of
> this parameter, or if one of the language tags indicated by user preferences is
> a case-insensitive prefix of one of the language tags given in the value of this
> parameter such that the first tag character following the prefix is "-"."
## Current code
https://searchfox.org/wubkat/rev/9971986dcebbc9ad5713a058e7951288c455bbee/Source/WebCore/svg/SVGTests.cpp#72-89
```cpp
bool SVGTests::isValid() const
{
auto attributes = conditionalProcessingAttributesIfExists();
if (!attributes)
return true;
String defaultLanguage = WTF::defaultLanguage();
auto genericDefaultLanguage = StringView(defaultLanguage).left(2);
for (auto& language : attributes->systemLanguage().items()) {
if (language != genericDefaultLanguage)
return false;
}
for (auto& extension : attributes->requiredExtensions().items()) {
if (!hasExtension(extension))
return false;
}
return true;
}
```
Karl Dubost
1. ALL vs ANY matching (most impactful)
The loop returns `false` if ANY listed language does NOT match. This means ALL languages must match. The spec says the opposite: return `true` if ANY listed language matches.
Current: `systemLanguage="en, fr, de"` with user language `en` → **false** (because `fr` and `de` don't match)
Expected: `systemLanguage="en, fr, de"` with user language `en` → **true** (because `en` matches)
This is the primary use case for `systemLanguage` — listing multiple acceptable languages in a `<switch>` element, e.g.:
```xml
<text systemLanguage="mi, en"><!-- content for Maori or English speakers --></text>
```
2. Language tag truncated to 2 characters
`StringView(defaultLanguage).left(2)` reduces the user's language tag to its first 2 characters. This means:
- User language `zh-Hans` becomes `zh`
loses the script subtag
- User language `pt-BR` becomes `pt`
loses the region subtag
- Comparison against listed tag `zh-Hans` would fail because `zh != zh-Hans`
3. Case-sensitive comparison
The spec requires "case-insensitive match". The current code uses `!=` which is case-sensitive. A listed tag `"EN"` would not match user language `"en"`.
### 4. No BCP 47 prefix matching
The spec says: evaluate to true if a user language tag "is a case-insensitive prefix of one of the language tags given in the value of this parameter such that the first tag character following the prefix is '-'".
This means:
- User `"en"` should match listed `"en-US"` (prefix + "-")
- User `"zh"` should match listed `"zh-Hans"` (prefix + "-")
The current code does none of this — it only does exact (truncated) comparison.
Karl Dubost
## Steps to reproduce
1. Set browser language to English (`en`)
2. Load an SVG with `<switch>` containing `<text systemLanguage="en, fr">Hello</text>`
3. Expected: text renders (because `en` matches)
4. Actual: text does not render (because `fr` doesn't match and ALL must match)
I have fixed the first part about parsing in Bug 262146.
This one will be about validation.
Karl Dubost
Pull request: https://github.com/WebKit/WebKit/pull/62975