Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RelationshipErrorHandlerFactory fails with "Data at the root level is invalid" #883

Closed
Muppets opened this issue Feb 11, 2021 · 3 comments · Fixed by #885
Closed

RelationshipErrorHandlerFactory fails with "Data at the root level is invalid" #883

Muppets opened this issue Feb 11, 2021 · 3 comments · Fixed by #885

Comments

@Muppets
Copy link
Contributor

Muppets commented Feb 11, 2021

Using RelationshipErrorHandlerFactory.Rewrite with an output that is shorter than the original URI causes the output XML to be malformed in this Word document.

        static void Main(string[] args)
        {
            var doc = WordprocessingDocument.Open("BrokenURI.docx", isEditable: true, new OpenSettings
            {
                RelationshipErrorHandlerFactory = _ => new RemoveMalformedHyperlinksRelationshipErrorHandler(),
            });
        }

        private sealed class RemoveMalformedHyperlinksRelationshipErrorHandler : RelationshipErrorHandler
        {
            // Works
            //public override string Rewrite(Uri partUri, string id, string uri) => $"https://error{new string('r', uri.Length)}";

            // Fails with "Data at the root level is invalid"
            public override string Rewrite(Uri partUri, string id, string uri) => $"https://error";
        }

When the above is run on a Word document with the following document.xml.rels:

<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
	<Relationship Id="rId8" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/>
	<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/>
	<Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="mailto:test@test.com;%20test2@test.com;%252test3@test.com;%20test3@test.com;%20test4@test.com;%20test5@test.com?subject=Unsubscribe%20Request&amp;body=Please%20unsubscribe%20me%20from%20all%20future%20communications" TargetMode="External"/>
	<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
	<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" Target="numbering.xml"/>
	<Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes" Target="endnotes.xml"/>
	<Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/>
	<Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/>
	<Relationship Id="rId9" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>
</Relationships>

It fails with "Data at the root level is invalid. Line 12, position 17." and has produced the following in the output document:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  <Relationship Id="rId8" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml" />
  <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml" />
  <Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="https://error" TargetMode="External" />
  <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml" />
  <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" Target="numbering.xml" />
  <Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes" Target="endnotes.xml" />
  <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml" />
  <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml" />
  <Relationship Id="rId9" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml" />
</Relationships>l"/><Relationship Id="rId9" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/></Relationships>

As you can see, the end part of the XML has now been malformed. This is probably a buffer issue with the shorter string being returned from the Rewrite method. I've seen this in a few places when working with the Package classes.

Extending the Rewrite output to match the length of the original URI resolves the issue:

public override string Rewrite(Uri partUri, string id, string uri) => $"https://error{new string('r', uri.Length)}";

Information

  • .NET Target: .NET Core
  • DocumentFormat.OpenXml Version: 2.12.1

Please see example console app with sample Word document repo'ing the issue:

https://github.com/Muppets/RelationshipErrorHandlerFactoryTest

Observed

Exception thrown: System.Xml.XmlException: 'Data at the root level is invalid. Line 12, position 17.'

Expected

Invalid URI is replaced with https://error

Just as a footnote, I'm loving the new RelationshipErrorHandlerFactory support added recently, great work! 🎉

@Muppets
Copy link
Contributor Author

Muppets commented Feb 11, 2021

Update on this. Turns out my hack to resolve the issue comes with a glaring issue.

public override string Rewrite(Uri partUri, string id, string uri) => $"https://error{new string('r', uri.Length)}";

If the output produced is over 265 characters, it blows up with:

System.InvalidOperationException: Provided URI was invalid after rewriting malformed relationship URI
   at DocumentFormat.OpenXml.Packaging.RelationshipErrorHandler.ValidateLink(PackagePart part, XElement child)
   at DocumentFormat.OpenXml.Packaging.RelationshipErrorHandler.WalkRelationships(PackagePart part)
   at DocumentFormat.OpenXml.Packaging.RelationshipErrorHandler.Handle(Package package)
   at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.Load()
   at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.OpenCore(String path, Boolean readWriteMode)
   at DocumentFormat.OpenXml.Packaging.WordprocessingDocument.Open(String path, Boolean isEditable, OpenSettings openSettings)

@twsouthwick
Copy link
Member

Oh good catch on the bufferring! Probably need to set the stream to 0 before writing it.

I'm fairly busy right now, but will happily review PRs!

As for your workaround - just subract the length of the new string part. Didn't realize there was a length limit there

Muppets pushed a commit to Muppets/Open-XML-SDK that referenced this issue Feb 12, 2021
Muppets pushed a commit to Muppets/Open-XML-SDK that referenced this issue Feb 12, 2021
twsouthwick pushed a commit to twsouthwick/Open-XML-SDK that referenced this issue Feb 16, 2021
@Muppets
Copy link
Contributor Author

Muppets commented Feb 17, 2021

@twsouthwick Just wanted to give a big thank you for helping get that fix in and the speed you got it rolled out on Nuget. Kudos to you sir! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants