Fix percentage opacity parsing during SVG load#520
Merged
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 30105c8224
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…-parsing # Conflicts: # src/Svg.Custom/Compatibility/SvgElementFactory.cs # tests/Svg.Controls.Skia.Avalonia.UnitTests/SvgSourceTests.cs
This was referenced May 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Summary: Handle Percentage Opacity Load Failures
Overview
This change fixes SVG load failures caused by percentage-valued opacity declarations such as
opacity="100%"while preserving existing SVG 1.1 / resvg behavior for invalid percentageopacity values.
The reported failure came through the Avalonia integration path (
SvgSource.LoadFromSvg(...)),but the root cause was lower in the shared compatibility loader: staged opacity declarations were
eventually forwarded into the generated float-conversion path, which cannot parse
%tokens.Problem
The failing SVG used:
During style flushing,
SvgElementFactory.SetPropertyValue(...)forwarded that raw value to thegenerated descriptor pipeline. Opacity-backed descriptors expect a plain numeric token, so
100%could trigger aFormatExceptionbefore rendering.At the same time, the repository already has conformance coverage that treats other percentage
opacity values such as
opacity="0.1%"as invalid input. A broad “parse all percentages” fixwould stop the exception, but it would also regress those existing renderer expectations.
What Changed
1. Narrow the parser fix to the safe case
File:
src/Svg.Custom/Compatibility/SvgElementFactory.csThe compatibility loader now special-cases percentage opacity values as follows:
100%is normalized to1That avoids the load-time exception for the reported SVG without changing the rendered result for
the safe
100%case, and it preserves the prior behavior for invalid percentage opacity input.The change still applies only to opacity-related properties:
opacityfill-opacitystroke-opacitystop-opacityflood-opacityIt also keeps the existing compatibility handling for:
opacity="undefined"stop-opacity="inherit"2. Use newer span APIs where the target framework supports them
File:
src/Svg.Custom/Compatibility/SvgElementFactory.csThe helper path now uses framework span APIs on newer target frameworks and keeps a local fallback
for
netstandard2.0:ReadOnlySpan<char>.Trim()on newer TFMsNETSTANDARD20float.TryParse(...)where availableThis keeps the code allocation-lean on modern targets without breaking the existing target matrix.
3. Update regression coverage to match the intended semantics
File:
tests/Svg.Skia.UnitTests/SvgDocumentCompatibilityLoaderTests.csThe parser tests now verify:
opacity="100%"loads and resolves to the default opacity value (1)This aligns the tests with the actual compatibility policy instead of asserting broad percentage
parsing support.
4. Keep the public Avalonia regression
File:
tests/Svg.Controls.Skia.Avalonia.UnitTests/SvgSourceTests.csThe Avalonia regression test remains in place to cover the original user-visible entry point:
SvgSource.LoadFromSvg(...)with the reportedopacity="100%"SVG no longer throwsCommit Breakdown
Normalize percentage opacity attributesAdd SvgSource opacity regression testUse spans in opacity normalizationIgnore invalid percentage opacity valuesValidation
Commands run:
dotnet format Svg.Skia.slnx --no-restore dotnet build Svg.Skia.slnx -c Release dotnet test Svg.Skia.slnx -c ReleaseFocused checks also run during investigation:
Results:
a-opacity-005): passedRisk Assessment
Risk is low because:
100%case,