dotnet / dotnet/Open-XML-SDK

The second attempt to open an unchanged presentation file for edit throws a "file contains corrupted data" error.

Open
#1,135 6 comments 0 reactions 0 assignees View on GitHub
more-information-needed
Dominant language
C#
Stars
4.6k
Forks
605
PR merge metrics
No merged PRs in 30d

Description

**Description**

We are trying to access PowerPoint presentation via MS-Graph from a SharepPoint Online document library.

Our PowerPoint Addin adds data as CustomXmlParts to presentation and the slides as well. It can be opened, manipulated and saved without problems as long as working files arer on a local computer.

The problem occurs when the file is uploaded to a SharePoint document library.
I open a small example presentation file as a stream, copy it to a memory stream and provide it to the presentation document to open it for edit. I do not change anything and after saving the presentation I copy the stream back to the SharePoint replacing the previously opened file. This works well!
But, trying this for the second time, a "File contains corrupted data." occurs, when trying to open the presentation document for edit from the memory stream.

The error's stack trace suggest that "MS.Internal.IO.Zip.ZipIOLocalFileBlock.Validate" has a problem with the data from the second stream.

` at MS.Internal.IO.Zip.ZipIOLocalFileBlock.Validate(String fileName, ZipIOCentralDirectoryBlock centralDir, ZipIOCentralDirectoryFileHeader centralDirFileHeader)
at MS.Internal.IO.Zip.ZipIOLocalFileBlock.ParseRecord(BinaryReader reader, String fileName, Int64 position, ZipIOCentralDirectoryBlock centralDir, ZipIOCentralDirectoryFileHeader centralDirFileHeader)
at MS.Internal.IO.Zip.ZipIOLocalFileBlock.SeekableLoad(ZipIOBlockManager blockManager, String fileName)
at MS.Internal.IO.Zip.ZipIOBlockManager.LoadLocalFileBlock(String zipFileName)
at MS.Internal.IO.Zip.ZipArchive.GetFile(String zipFileName)
at MS.Internal.IO.Zip.ZipArchive.GetFiles()
at System.IO.Packaging.ZipPackage.ContentTypeHelper..ctor(ZipArchive zipArchive, IgnoredItemHelper ignoredItemHelper)
at System.IO.Packaging.ZipPackage..ctor(Stream s, FileMode mode, FileAccess access, Boolean streaming)
at System.IO.Packaging.Package.Open(Stream stream, FileMode packageMode, FileAccess packageAccess, Boolean streaming)
at DocumentFormat.OpenXml.Packaging.PackageLoader.OpenCore(Stream stream, Boolean readWriteMode)
at DocumentFormat.OpenXml.Packaging.PresentationDocument.Open(Stream stream, Boolean isEditable, OpenSettings openSettings)
at DocumentFormat.OpenXml.Packaging.PresentationDocument.Open(Stream stream, Boolean isEditable)
...`

Even the "corrupted" file can be opened from SharePoint in a PowerPoint browser app. After a small change, it is saved automatically and after this I can reopen and save it as often as I like to. It seems as if this has a healing effect on the file.

I know that different opening and saving mechanisms use different methods optimizing OpenXml files. I know as well that these mechanisms use different zippers, but I cannot steer, to use right one for my file.

Comparing both files (corrupted and healed) shows that the CustomXmlParts are reorganized and renumbered in the healed one. By I cannot find a crucial difference.

The question is, what is going wrong or is processed different in "MS.Internal.IO.Zip.ZipIOLocalFileBlock.Validate"? What can it
not accept that is accepted elsewhere?

[CorruptedAtSecondOpen.pptx](https://github.com/OfficeDev/Open-XML-SDK/files/8251294/CorruptedAtSecondOpen.pptx)

**Information**

- .NET Target: Net4.8
- DocumentFormat.OpenXml Version: (2.15.0)

**Repro**

```csharp
private bool OpenCloseAndSave(IReadOnlyStorageAccessInfo presAccessInfo)
{
try
{
using (MemoryStream memStream = OpenPresentationAsWritableStream(presAccessInfo))
{
using (var presentationDocument = PresentationDocument.Open(memStream, true))
{
// Save the presentation.
presentationDocument.PresentationPart.Presentation.Save();
presentationDocument.Save();
presentationDocument.Close();

if (presAccessInfo is IEditableStorageAccessInfo editablePresentationStorageInfo)
{
editablePresentationStorageInfo.SaveStream(memStream);
}
}
}
return true;
}
catch (Exception ex)
{
Logging.Log.Error(nameof(TestSharePointDocUpload), nameof(OpenCloseAndSave), ex);
}
return false;
}
```

**Observed**

Opening a by user unchanged file for the second time causes a "file contains corrupted data" error.

**Expected**

Opening a by user unchanged file for the second time should be opened without error as it was openend for the first time.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.