<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>262140</bug_id>
          
          <creation_ts>2023-09-26 14:21:13 -0700</creation_ts>
          <short_desc>SVGTests::isValid() does not correctly implement systemLanguage matching per SVG2</short_desc>
          <delta_ts>2026-04-17 07:49:58 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>SVG</component>
          <version>WebKit Nightly Build</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Unspecified</op_sys>
          <bug_status>NEW</bug_status>
          <resolution></resolution>
          
          <see_also>https://bugs.webkit.org/show_bug.cgi?id=262146</see_also>
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>BrowserCompat, InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Ahmad Saleem">ahmad.saleem792</reporter>
          <assigned_to name="Karl Dubost">karlcow</assigned_to>
          <cc>karlcow</cc>
    
    <cc>sabouhallawa</cc>
    
    <cc>simon.fraser</cc>
    
    <cc>webkit-bug-importer</cc>
    
    <cc>zimmermann</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1980288</commentid>
    <comment_count>0</comment_count>
    <who name="Ahmad Saleem">ahmad.saleem792</who>
    <bug_when>2023-09-26 14:21:13 -0700</bug_when>
    <thetext>Hi Team,

While going through Blink&apos;s commit, I came across another failing test case in Safari 17 (macOS Sonoma).

Test Case: https://jsfiddle.net/35yL6qnw/5/

^ above shows &apos;en FAIL&apos; in Red (Safari) while show &apos;EN&apos; 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!</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1980304</commentid>
    <comment_count>1</comment_count>
    <who name="Ahmad Saleem">ahmad.saleem792</who>
    <bug_when>2023-09-26 14:57:34 -0700</bug_when>
    <thetext>Merge this as well: https://source.chromium.org/chromium/chromium/src/+/592442acb95d29bd54f068f70009a6ec47fa863b</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1980309</commentid>
    <comment_count>2</comment_count>
    <who name="Ahmad Saleem">ahmad.saleem792</who>
    <bug_when>2023-09-26 14:59:15 -0700</bug_when>
    <thetext>static bool isLangTagPrefix(const String&amp; langTag, const String&amp; language)
{
    if (!langTag.startsWithIgnoringASCIICase(language))
        return false;
    return langTag.length() == language.length() || langTag[language.length()] == &apos;-&apos;;
}

static bool matchLanguageList(const String&amp; langTag, const Vector&lt;String&gt;&amp; languages)
{
    for (const auto&amp; value : languages) {
        if (isLangTagPrefix(langTag, value))
            return true;
    }
    return false;
}

and following changes here: &quot;SVGTests::isValid()&quot;

    for (auto&amp; langTag : attributes-&gt;systemLanguage().items()) {
        if (matchLanguageList(langTag, genericDefaultLanguage))
            return false;
    }

___

It leads to following compile errors:

candidate function not viable: no known conversion from &apos;StringView&apos; to &apos;const Vector&lt;String&gt;&apos;
      for 2nd argument

and

      no matching function for call to &apos;matchLanguageList&apos;

___

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.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1980428</commentid>
    <comment_count>3</comment_count>
    <who name="Karl Dubost">karlcow</who>
    <bug_when>2023-09-27 01:13:27 -0700</bug_when>
    <thetext>Probably fixing Bug 262146 first would help with this one.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1982224</commentid>
    <comment_count>4</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2023-10-03 14:22:21 -0700</bug_when>
    <thetext>&lt;rdar://problem/116424326&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2197981</commentid>
    <comment_count>5</comment_count>
    <who name="Karl Dubost">karlcow</who>
    <bug_when>2026-04-08 08:03:06 -0700</bug_when>
    <thetext>## Spec reference

https://w3c.github.io/svgwg/svg2-draft/struct.html#ConditionalProcessingSystemLanguageAttribute

&gt; &quot;Evaluates to &quot;true&quot; if one of the language tags indicated by user preferences
&gt; is a case-insensitive match of one of the language tags given in the value of
&gt; this parameter, or if one of the language tags indicated by user preferences is
&gt; a case-insensitive prefix of one of the language tags given in the value of this
&gt; parameter such that the first tag character following the prefix is &quot;-&quot;.&quot;

## 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&amp; language : attributes-&gt;systemLanguage().items()) {
        if (language != genericDefaultLanguage)
            return false;
    }
    for (auto&amp; extension : attributes-&gt;requiredExtensions().items()) {
        if (!hasExtension(extension))
            return false;
    }
    return true;
}
```</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2197984</commentid>
    <comment_count>6</comment_count>
    <who name="Karl Dubost">karlcow</who>
    <bug_when>2026-04-08 08:05:51 -0700</bug_when>
    <thetext>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=&quot;en, fr, de&quot;` with user language `en` → **false** (because `fr` and `de` don&apos;t match)

Expected: `systemLanguage=&quot;en, fr, de&quot;` with user language `en` → **true** (because `en` matches)

This is the primary use case for `systemLanguage` — listing multiple acceptable languages in a `&lt;switch&gt;` element, e.g.:

```xml
&lt;text systemLanguage=&quot;mi, en&quot;&gt;&lt;!-- content for Maori or English speakers --&gt;&lt;/text&gt;
```

2. Language tag truncated to 2 characters

`StringView(defaultLanguage).left(2)` reduces the user&apos;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 &quot;case-insensitive match&quot;. The current code uses `!=` which is case-sensitive. A listed tag `&quot;EN&quot;` would not match user language `&quot;en&quot;`.

### 4. No BCP 47 prefix matching

The spec says: evaluate to true if a user language tag &quot;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 &apos;-&apos;&quot;.

This means:
- User `&quot;en&quot;` should match listed `&quot;en-US&quot;` (prefix + &quot;-&quot;)
- User `&quot;zh&quot;` should match listed `&quot;zh-Hans&quot;` (prefix + &quot;-&quot;)

The current code does none of this — it only does exact (truncated) comparison.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2197985</commentid>
    <comment_count>7</comment_count>
    <who name="Karl Dubost">karlcow</who>
    <bug_when>2026-04-08 08:07:57 -0700</bug_when>
    <thetext>## Steps to reproduce

1. Set browser language to English (`en`)
2. Load an SVG with `&lt;switch&gt;` containing `&lt;text systemLanguage=&quot;en, fr&quot;&gt;Hello&lt;/text&gt;`
3. Expected: text renders (because `en` matches)
4. Actual: text does not render (because `fr` doesn&apos;t match and ALL must match)


I have fixed the first part about parsing in Bug 262146.
This one will be about validation.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2201504</commentid>
    <comment_count>8</comment_count>
    <who name="Karl Dubost">karlcow</who>
    <bug_when>2026-04-17 07:49:58 -0700</bug_when>
    <thetext>Pull request: https://github.com/WebKit/WebKit/pull/62975</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>