dotnet / dotnet/Open-XML-SDK

MarkupCompatibilityProcessSettings corrupt document for ligatures set in document text

Open
#2,086 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
4.6k
Forks
605
PR merge metrics
No merged PRs in 30d

Description

**Describe the bug**
Opening a Docx-Document with OpenSettings using MarkupCompatibilityProcessSettings corrupts the document on saving if:
- the document has a ligature setting (w14:ligatures) in the document text
- the FileFormatVersions of the MarkupCompatibilityProcessSettings is set to a version that supports ligatures (Office2013 and above)
- the MarkupCompatibilityProcessMode is set to ProcessAllParts

No further operation is needed on the document, just opening and save.

In the original document the document.xml contains a ligature setting (e.g. ``).
In the document.xml of the saved document the ligature setting has been changed to `` which lost its required value attribute and is therefore malformatted.
See [Open Specifications - 2.6.1.17 ligatures](https://learn.microsoft.com/en-us/openspecs/office_standards/ms-docx/d0e2eaf6-ed50-445f-ad90-2bd0fa24a442)

**To Reproduce**
[LigaturesHistorical.docx](https://github.com/user-attachments/files/27794417/LigaturesHistorical.docx)

```
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;

namespace BreakLigatures
{
internal class Program
{
static void Main(string[] args)
{
var inputFullFilePath = args.Length > 0 ? args[0] : throw new ArgumentException("Input file path is required as the first argument.");
var outputFullFilePath = args.Length > 1 ? args[1] : throw new ArgumentException("Output file path is required as the second argument.");

using var documentStream = new MemoryStream(File.ReadAllBytes(inputFullFilePath));

var openSettings = new OpenSettings()
{
MarkupCompatibilityProcessSettings = new MarkupCompatibilityProcessSettings(MarkupCompatibilityProcessMode.ProcessAllParts, FileFormatVersions.Office2013),
};

using var document = WordprocessingDocument.Open(documentStream, true, openSettings);
{
// do nothing, just save
document.Save();
}

File.WriteAllBytes(outputFullFilePath, documentStream.ToArray());
}
}
}
```
Steps to reproduce the behavior:
1. Use attached LigaturesHistorical.docx and continue at 8 or proceed to generate own document
2. Open MS Word and create a new blank document
3. Insert some text
4. Select some text
5. Right click selected text and select "Font..." from the menu
6. In tab "Advanced" set "Ligatures" setting to a different value
7. Save document
8. Run attached program with the document
9. Open resulting document in MS Word
10. See error "Word found unreadable content..."

**Observed behavior**
Opening a document with a ligature setting using MarkupCompatibilityProcessSettings and saving the document produces an invalid document.

**Expected behavior**
Opening a document with a ligature setting using MarkupCompatibilityProcessSettings and saving the document should produce a valid document.
If the file format version supports the feature the ligature setting should be retained as is.

**Desktop (please complete the following information):**
- OS: Windows 10/11
- Office version 16.0.19929.20136
- .NET Target: .Net Core 8
- DocumentFormat.OpenXml Version: 3.3.0 .. 3.5.1

Contributor guide

Open the contributing guide

Research direction

Start with the OpenSettings MarkupCompatibilityProcessSettings entry point and reproduce the issue using the attached LigaturesHistorical.docx and the C# program in the report. Trace ProcessAllParts with Office2013 handling, then add a regression test that opens and saves the document and verifies document.xml retains the w14:ligatures w14:val attribute and remains valid.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
54/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.