dotnet/wpf · error · FileFormatException

SR.Resource_XpsPackageBoundaryViolation

Error message

SR.Resource_XpsPackageBoundaryViolation

What it means

While resolving a PixelShader's UriSource inside XPS-loaded content, the URI pointed outside the current XPS package and XpsLoadingContext.IsUriAllowedInCurrentContext returned false, so the loader throws FileFormatException(SR.Resource_XpsPackageBoundaryViolation). This is a deliberate security guard against shader URIs escaping the package (SSRF/cross-package reads).

Solutions

  1. Re-author the XPS so the shader resource is embedded within the same package and referenced with a relative pack URI
  2. Only load shader content from trusted, application-shipped resources instead of document-supplied URIs
  3. Pre-process untrusted XPS to strip/replace external shader references before rendering
  4. If you own the content pipeline, validate shader URIs at authoring time against the package boundary

Example fix

// before (inside XPS-fixed-page markup)
<!-- UriSource="/ ../../otherPackage/shader.ps" --> <!-- escapes package, throws -->

// after: embed shader in the same package and reference relatively
<!-- UriSource="resources/shader.ps" -->
Defensive patterns

Strategy: validation

Validate before calling

// before rendering untrusted XPS content:
bool allowed = XpsLoadingContext.IsUriAllowedInCurrentContext(shaderUri);
if (!allowed)
{
    // reject document or replace the shader reference with an app-shipped resource
}

Try / catch

try { LoadXpsWithShaders(document); }
catch (FileFormatException ex) when (ex.Message.Contains("boundary"))
{
    // treat document as untrusted: quarantine or re-author
}

Prevention

When it happens

Trigger: An XPS document contains shader markup whose URI references another package, an absolute file/http path, or any target outside the current package boundary; loading untrusted XPS content.

Common situations: XPS documents produced by third-party tools embedding absolute shader references; documents tampered with or crafted to probe local resources; porting content that worked before the boundary check was added.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/38bbaddd8d930d18. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Effects/PixelShader.cs:97

                    }

                    Debug.Assert(newUri.IsAbsoluteUri);

                    // Now the URI is an absolute URI.

                    //
                    // Only allow file and pack URIs.
                    if (!newUri.IsFile && 
                        !MS.Internal.IO.Packaging.PackUriHelper.IsPackUri(newUri))
                    {
                        throw new ArgumentException(SR.Effect_SourceUriMustBeFileOrPack);
                    }

                    // Security: When loading XPS content, block shader URIs that
                    // escape the current package to prevent SSRF.
                    if (!XpsLoadingContext.IsUriAllowedInCurrentContext(newUri))
                    {
                        throw new FileFormatException(SR.Resource_XpsPackageBoundaryViolation);
                    }

                    stream = WpfWebRequestHelper.CreateRequestAndGetResponseStream(newUri);
                }

                LoadPixelShaderFromStreamIntoMemory(stream);            
            }
            finally
            {
                stream?.Dispose();
            }
        }

        /// <summary>
        /// Reads the byte code for the pixel shader into a local byte array. If the stream is null, the byte array
        /// will be empty (length 0). The compositor will use an identity shader.
        /// </summary>
        private void LoadPixelShaderFromStreamIntoMemory(Stream source) 

View on GitHub (pinned to 81131a70a4)