Skip to content

Commit 4f67359

Browse files
authored
Check for seekable stream for malformed uri handling (#1644)
- We must be able to seek to create a temporary file requried for uri handling - We should throw the same exception we did in v2.x - If compat mode is on, this will throw at open time (i.e. it will eagerly load everything) Fixes #1636
1 parent 3e35208 commit 4f67359

File tree

11 files changed

+183
-14
lines changed

11 files changed

+183
-14
lines changed

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
# Changelog
2+
23
All notable changes to this project will be documented in this file.
34

45
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
56
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
67

7-
## [3.1.0]
8+
## [3.0.1]
89

910
### Fixed
11+
1012
- Fixed issue where document type would not be correct unless content type was checked first (#1625)
13+
- Added check to only seek on packages where it is supported (#1644)
14+
- If a malformed URI is encountered, the exception is now the same as v2.x (`OpenXmlPackageException` with an inner `UriFormatException`) (#1644)
1115

1216
## [3.0.0] - 2023-11-15
1317

14-
## Added
18+
### Added
1519

1620
- `DocumentFormat.OpenXml.Office.PowerPoint.Y2023.M02.Main` namespace
1721
- `DocumentFormat.OpenXml.Office.PowerPoint.Y2022.M03.Main` namespace

src/DocumentFormat.OpenXml.Framework/Features/PackageFeatureBase.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,16 @@ protected override void Delete(string id)
243243
=> Feature.Package.GetPart(Uri).DeleteRelationship(id);
244244

245245
protected override IEnumerable<PackageRelationship> GetRelationships()
246-
=> Feature.Package.GetPart(Uri).GetRelationships();
246+
{
247+
try
248+
{
249+
return Feature.Package.GetPart(Uri).GetRelationships();
250+
}
251+
catch (UriFormatException ex)
252+
{
253+
throw new OpenXmlPackageException(ExceptionMessages.MalformedUri, ex);
254+
}
255+
}
247256
}
248257

249258
private abstract class RelationshipCollection : IRelationshipCollection

src/DocumentFormat.OpenXml.Framework/Features/StreamPackageFeature.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,14 @@ private void InitializePackage(FileMode? mode = default, FileAccess? access = de
111111
SetStream(GetStream(mode.Value, access.Value));
112112
}
113113

114-
_package = Package.Open(_stream, mode.Value, access.Value);
114+
try
115+
{
116+
_package = Package.Open(_stream, mode.Value, access.Value);
117+
}
118+
catch (ArgumentException ex)
119+
{
120+
throw new OpenXmlPackageException(ExceptionMessages.FailedToOpenPackage, ex);
121+
}
115122
}
116123

117124
protected override Package Package => _package;

src/DocumentFormat.OpenXml.Framework/Packaging/WriteableStreamExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ internal static class WriteableStreamExtensions
1515
[System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "Disposable is registered with package")]
1616
public static bool EnableWriteableStream(this IFeatureCollection features)
1717
{
18-
if (features.Get<IPackageStreamFeature>() is { Stream.CanWrite: false } feature &&
18+
if (features.Get<IPackageStreamFeature>() is { Stream: { CanWrite: false, CanSeek: true } } feature &&
1919
features.Get<IPackageFeature>() is { } packageFeature &&
2020
packageFeature.Capabilities.HasFlagFast(PackageCapabilities.Reload))
2121
{

src/DocumentFormat.OpenXml.Framework/Resources/ExceptionMessages.Designer.cs

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/DocumentFormat.OpenXml.Framework/Resources/ExceptionMessages.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,4 +408,10 @@
408408
<data name="NamespaceIdNotAvailable" xml:space="preserve">
409409
<value>Namespace ids are only available for namespaces for Office 2021 and before. Please use prefixes or URLs instead.</value>
410410
</data>
411+
<data name="MalformedUri" xml:space="preserve">
412+
<value>The package contains malformed URI relationships. Please ensure the package is opened with a stream (that is seekable) or a file path to have the SDK automatically handle these scenarios.</value>
413+
</data>
414+
<data name="FailedToOpenPackage" xml:space="preserve">
415+
<value>Package could not be opened for stream. See inner exception for details and be aware that there are behavior differences in stream support between .NET Framework and Core.</value>
416+
</data>
411417
</root>

test/DocumentFormat.OpenXml.Framework.Tests/DocumentFormat.OpenXml.Framework.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<ItemGroup>
2222
<ProjectReference Include="..\..\src\DocumentFormat.OpenXml.Framework\DocumentFormat.OpenXml.Framework.csproj" />
2323
<ProjectReference Include="..\..\src\DocumentFormat.OpenXml\DocumentFormat.OpenXml.csproj" />
24+
<ProjectReference Include="..\DocumentFormat.OpenXml.Tests.Assets\DocumentFormat.OpenXml.Tests.Assets.csproj" />
2425
</ItemGroup>
2526

2627
</Project>

test/DocumentFormat.OpenXml.Tests.Assets/IFile.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,9 @@ public interface IFile : IDisposable
1111
string Path { get; }
1212

1313
Stream Open();
14+
15+
bool IsEditable { get; }
16+
17+
FileAccess Access { get; }
1418
}
1519
}

test/DocumentFormat.OpenXml.Tests.Assets/TemporaryFile.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ private TemporaryFile(string path)
1616

1717
public string Path { get; }
1818

19+
public bool IsEditable => true;
20+
21+
public FileAccess Access => FileAccess.ReadWrite;
22+
1923
public Stream Open() => File.Open(Path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
2024

2125
public void Dispose()

test/DocumentFormat.OpenXml.Tests.Assets/TestAssets.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ public MemoryFile(Stream stream, string path)
9898

9999
public string Path { get; }
100100

101+
public bool IsEditable => _stream.CanWrite;
102+
103+
public FileAccess Access => _stream.CanWrite ? FileAccess.ReadWrite : FileAccess.Read;
104+
101105
public Stream Open() => _stream;
102106

103107
public void Dispose()
@@ -108,23 +112,22 @@ public void Dispose()
108112

109113
private class CopiedFile : IFile
110114
{
111-
private readonly FileAccess _access;
112-
113115
public CopiedFile(Stream stream, string extension, FileAccess access)
114116
{
115117
Path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), $"{Guid.NewGuid()}{extension}");
118+
Access = access;
116119

117-
_access = access;
118-
119-
using (var fs = File.OpenWrite(Path))
120-
{
121-
stream.CopyTo(fs);
122-
}
120+
using var fs = File.OpenWrite(Path);
121+
stream.CopyTo(fs);
123122
}
124123

125124
public string Path { get; }
126125

127-
public Stream Open() => File.Open(Path, FileMode.Open, _access);
126+
public bool IsEditable => Access == FileAccess.ReadWrite;
127+
128+
public FileAccess Access { get; }
129+
130+
public Stream Open() => File.Open(Path, FileMode.Open, Access);
128131

129132
public void Dispose()
130133
{

0 commit comments

Comments
 (0)