Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions NanoXLSX.Reader/Internal/Readers/DiscoveryReader.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* NanoXLSX is a small .NET library to generate and read XLSX (Microsoft Excel 2007 or newer) files in an easy and native way
* Copyright Raphael Stoeckli © 2026
* This library is licensed under the MIT License.
Expand Down Expand Up @@ -238,10 +238,23 @@ private RelationshipInfo ParseRelationship(XmlReader reader, string relationship
string resolvedTargetPath = null;
if (targetMode == TargetMode.Internal)
{
if (targetUri.IsAbsoluteUri)
// [VENDOR-PATCH NanoXLSX#mono-rootrelative-target] A target beginning with '/' is a
// ROOT-RELATIVE path, which OPC permits for an internal relationship. Mono's System.Uri
// parses such a string as an ABSOLUTE Uri while .NET's does not, so testing IsAbsoluteUri
// alone silently discards every root-relative relationship on Mono. In practice that is
// sharedStrings.xml: the relationship is dropped from the catalog, the (optional) shared
// strings part is never read, and every string cell is left holding its raw shared-string
// INDEX instead of its text -- with no exception raised. Test for a real scheme instead,
// and rebuild the target as relative so ResolvePartUri agrees on both runtimes.
bool rootRelativeTarget = target.StartsWith("/", StringComparison.Ordinal);
if (targetUri.IsAbsoluteUri && !rootRelativeTarget)
{
return HandleRelationshipIssue(relationshipPartPath, id, "An internal relationship target cannot be an absolute URI.", issues, null);
}
if (rootRelativeTarget)
{
targetUri = new Uri(target, UriKind.Relative);
}
Uri sourceUri = new Uri("/" + sourcePartPath, UriKind.Relative);
Uri resolvedTargetUri = PackUriHelper.ResolvePartUri(sourceUri, targetUri);
resolvedTargetPath = resolvedTargetUri.OriginalString.TrimStart('/');
Expand Down
Loading