Skip to content

Commit

Permalink
Bug fixes epplus 7 (#1081)
Browse files Browse the repository at this point in the history
* Documented and removed unused function on the FunctionArgument class. Fixed error handling issue in Averageif/CountIf and SumIf functions. Removed ErrorHandlingFunction base class.

* Fixed tests referensing ExcelStateFlagIsSet

* Added new MemorySettings property to ExcelPackage to config RecyclableMemoryStream. Fixed some issues where MemoryStreams were not disposed.

* Fixed a bug with whitespaces when loading cell values
  • Loading branch information
JanKallman authored Oct 2, 2023
1 parent 5af9d33 commit b11ab39
Show file tree
Hide file tree
Showing 30 changed files with 583 additions and 686 deletions.
1 change: 1 addition & 0 deletions src/EPPlus.Interfaces/EPPlus.Interfaces.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<RootNamespace>OfficeOpenXml.Interfaces</RootNamespace>
<PackageReadmeFile>readme.md</PackageReadmeFile>
<PackageIcon>EPPlusLogo.png</PackageIcon>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">
Expand Down
1 change: 1 addition & 0 deletions src/EPPlus.System.Drawing/EPPlus.System.Drawing.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<RootNamespace>OfficeOpenXml.System.Drawing</RootNamespace>
<PackageReadmeFile>readme.md</PackageReadmeFile>
<PackageIcon>EPPlusLogo.png</PackageIcon>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">
<DefineConstants>Core;Standard20</DefineConstants>
Expand Down
48 changes: 25 additions & 23 deletions src/EPPlus/Drawing/ExcelImage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -278,20 +278,21 @@ internal ExcelImage SetImageNoContainer(byte[] image, ePictureType pictureType)
{
ImageBytes = image;
}
var ms = RecyclableMemory.GetStream(image);
var imageHandler = new GenericImageHandler();
if (imageHandler.GetImageBounds(ms, pictureType, out double height, out double width, out double horizontalResolution, out double verticalResolution))
using(var ms = RecyclableMemory.GetStream(image))
{
Bounds.Width = width;
Bounds.Height = height;
Bounds.HorizontalResolution = horizontalResolution;
Bounds.VerticalResolution = verticalResolution;
}
else
{
throw (new InvalidOperationException($"The image format is not supported: {pictureType} or the image is corrupt "));
var imageHandler = new GenericImageHandler();
if (imageHandler.GetImageBounds(ms, pictureType, out double height, out double width, out double horizontalResolution, out double verticalResolution))
{
Bounds.Width = width;
Bounds.Height = height;
Bounds.HorizontalResolution = horizontalResolution;
Bounds.VerticalResolution = verticalResolution;
}
else
{
throw (new InvalidOperationException($"The image format is not supported: {pictureType} or the image is corrupt "));
}
}

return this;

}
Expand Down Expand Up @@ -338,19 +339,20 @@ private ExcelImage SetImageContainer(byte[] image, ePictureType pictureType, boo
ImageBytes = image;
}
PictureStore.SavePicture(image, _container, pictureType);
var ms = RecyclableMemory.GetStream(image);
if (_container.RelationDocument.Package.Settings.ImageSettings.GetImageBounds(ms, pictureType, out double height, out double width, out double horizontalResolution, out double verticalResolution))
using (var ms = RecyclableMemory.GetStream(image))
{
Bounds.Width = width;
Bounds.Height = height;
Bounds.HorizontalResolution = horizontalResolution;
Bounds.VerticalResolution = verticalResolution;
}
else
{
throw (new InvalidOperationException($"Image format not supported or: {pictureType} or corrupt image"));
if (_container.RelationDocument.Package.Settings.ImageSettings.GetImageBounds(ms, pictureType, out double height, out double width, out double horizontalResolution, out double verticalResolution))
{
Bounds.Width = width;
Bounds.Height = height;
Bounds.HorizontalResolution = horizontalResolution;
Bounds.VerticalResolution = verticalResolution;
}
else
{
throw (new InvalidOperationException($"Image format not supported or: {pictureType} or corrupt image"));
}
}

_container.SetNewImage();
return this;
}
Expand Down
67 changes: 37 additions & 30 deletions src/EPPlus/Drawing/ImageHandling/ImageReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ internal struct TifIfd
Stream newMs = RecyclableMemory.GetStream();
StreamUtil.CopyStream(stream, ref newMs);
pt = GetPictureTypeFromMs((MemoryStream)newMs);
newMs.Dispose();
}
if (throwException && pt == null) throw new InvalidOperationException("Cannot identify the image format of the stream.");
return pt;
Expand All @@ -62,9 +63,11 @@ internal struct TifIfd
}
else
{
Stream newMs = RecyclableMemory.GetStream();
await StreamUtil.CopyStreamAsync(stream, newMs, new CancellationToken()).ConfigureAwait(false);
pt = GetPictureTypeFromMs((MemoryStream)newMs);
using (Stream newMs = RecyclableMemory.GetStream())
{
await StreamUtil.CopyStreamAsync(stream, newMs, new CancellationToken()).ConfigureAwait(false);
pt = GetPictureTypeFromMs((MemoryStream)newMs);
}
}
if (pt == null) throw new InvalidOperationException("Cannot identify the image format of the stream.");
return pt;
Expand Down Expand Up @@ -196,38 +199,42 @@ internal static byte[] ExtractImage(byte[] img, out ePictureType? type)
{
try
{
var ms = RecyclableMemory.GetStream(img);
var msOut = RecyclableMemory.GetStream();
const int bufferSize = 4096;
var buffer = new byte[bufferSize];
using (var z = new OfficeOpenXml.Packaging.Ionic.Zlib.GZipStream(ms, Packaging.Ionic.Zlib.CompressionMode.Decompress))
using(var ms = RecyclableMemory.GetStream(img))
{
int size = 0;
do
using(var msOut = RecyclableMemory.GetStream())
{
size = z.Read(buffer, 0, bufferSize);
if (size > 0)
const int bufferSize = 4096;
var buffer = new byte[bufferSize];
using (var z = new OfficeOpenXml.Packaging.Ionic.Zlib.GZipStream(ms, Packaging.Ionic.Zlib.CompressionMode.Decompress))
{
msOut.Write(buffer, 0, size);
int size = 0;
do
{
size = z.Read(buffer, 0, bufferSize);
if (size > 0)
{
msOut.Write(buffer, 0, size);
}
}
while (size == bufferSize);
msOut.Position = 0;
var br = new BinaryReader(msOut);
if (IsEmf(br))
{
type = ePictureType.Emf;
}
else if (IsWmf(br))
{
type = ePictureType.Wmf;
}
else
{
type = null;
}
msOut.Position = 0;
return msOut.ToArray();
}
}
while (size == bufferSize);
msOut.Position = 0;
var br = new BinaryReader(msOut);
if (IsEmf(br))
{
type = ePictureType.Emf;
}
else if (IsWmf(br))
{
type = ePictureType.Wmf;
}
else
{
type = null;
}
msOut.Position = 0;
return msOut.ToArray();
}
}
catch
Expand Down
17 changes: 9 additions & 8 deletions src/EPPlus/Drawing/ImageHandling/PictureStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,18 @@ private static void SaveImageToPart(byte[] image, ZipPackagePart imagePart)
internal static ExcelImageInfo GetImageBounds(byte[] image, ePictureType type, ExcelPackage pck)
{
var ret = new ExcelImageInfo();
var ms = RecyclableMemory.GetStream(image);
var s = pck.Settings.ImageSettings;

if(s.GetImageBounds(ms, type, out double width, out double height, out double horizontalResolution, out double verticalResolution)==false)
using(var ms = RecyclableMemory.GetStream(image))
{
throw (new InvalidOperationException($"No image handler for image type {type}"));
if (s.GetImageBounds(ms, type, out double width, out double height, out double horizontalResolution, out double verticalResolution) == false)
{
throw (new InvalidOperationException($"No image handler for image type {type}"));
}
ret.Width = width;
ret.Height = height;
ret.HorizontalResolution = horizontalResolution;
ret.VerticalResolution = verticalResolution;
}
ret.Width = width;
ret.Height = height;
ret.HorizontalResolution = horizontalResolution;
ret.VerticalResolution = verticalResolution;
return ret;
}
internal static string GetExtension(Uri uri)
Expand Down
43 changes: 22 additions & 21 deletions src/EPPlus/EPPlus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>OpenOfficeXml.snk</AssemblyOriginatorKeyFile>
<NeutralLanguage />
<LangVersion>latest</LangVersion>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<RepositoryType>git</RepositoryType>
<PackageIcon>EPPlusLogo.png</PackageIcon>
Expand Down Expand Up @@ -445,10 +446,13 @@
<ItemGroup>
<Compile Remove="Core\Worksheet\Fonts\Tables\**" />
<Compile Remove="FormulaParsing\Excel\Functions\DynamicArray\**" />
<Compile Remove="Utils\RecyclableMemoryStream\**" />
<EmbeddedResource Remove="Core\Worksheet\Fonts\Tables\**" />
<EmbeddedResource Remove="FormulaParsing\Excel\Functions\DynamicArray\**" />
<EmbeddedResource Remove="Utils\RecyclableMemoryStream\**" />
<None Remove="Core\Worksheet\Fonts\Tables\**" />
<None Remove="FormulaParsing\Excel\Functions\DynamicArray\**" />
<None Remove="Utils\RecyclableMemoryStream\**" />
</ItemGroup>


Expand All @@ -472,17 +476,14 @@
<Reference Include="System.Data" />
<Reference Include="System.Security" />
<Reference Include="System.Xml" />
<Reference Include="System.Threading.Tasks" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream">
<Version>1.4.1</Version>
</PackageReference>
<Reference Include="System.Threading.Tasks" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream">
<Version>1.4.1</Version>
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream">
<Version>2.2.1</Version>
</PackageReference>
<PackageReference Include="System.ComponentModel.Annotations">
<Version>5.0.0</Version>
</PackageReference>
Expand All @@ -491,13 +492,13 @@
</PackageReference>
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="4.7.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.1" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream">
<Version>2.3.2</Version>
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.30" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream">
<Version>2.2.1</Version>
</PackageReference>
<PackageReference Include="System.ComponentModel.Annotations">
<Version>5.0.0</Version>
</PackageReference>
Expand All @@ -506,35 +507,35 @@
</PackageReference>
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="4.7.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.1" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream">
<Version>2.3.2</Version>
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream">
<Version>2.2.1</Version>
</PackageReference>
<PackageReference Include="System.ComponentModel.Annotations">
<Version>5.0.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="6.0.3" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="6.0.0" />
</ItemGroup>
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream">
<Version>2.3.2</Version>
</PackageReference>
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream">
<Version>2.2.1</Version>
</PackageReference>
<PackageReference Include="System.ComponentModel.Annotations">
<Version>5.0.0</Version>
</PackageReference>
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="7.0.2" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream">
<Version>2.3.2</Version>
</PackageReference>
</ItemGroup>

<ItemGroup>
<Compile Remove="FormulaParsing\CalculateExtentionsOld.cs" />
</ItemGroup>

<ItemGroup>
<None Remove="resources\DefaultTableStyles.cst" />
Expand Down
20 changes: 11 additions & 9 deletions src/EPPlus/Encryption/EncryptionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -333,18 +333,20 @@ private void CreateDataSpaces(CompoundDocument doc)
}
private byte[] CreateStrongEncryptionDataSpaceStream()
{
MemoryStream ms = RecyclableMemory.GetStream();
BinaryWriter bw = new BinaryWriter(ms);
using (MemoryStream ms = RecyclableMemory.GetStream())
{
BinaryWriter bw = new BinaryWriter(ms);

bw.Write((int)8); //HeaderLength
bw.Write((int)1); //EntryCount
bw.Write((int)8); //HeaderLength
bw.Write((int)1); //EntryCount

string tr = "StrongEncryptionTransform";
bw.Write((int)tr.Length*2);
bw.Write(UTF8Encoding.Unicode.GetBytes(tr + "\0")); // end \0 is for padding
string tr = "StrongEncryptionTransform";
bw.Write((int)tr.Length * 2);
bw.Write(UTF8Encoding.Unicode.GetBytes(tr + "\0")); // end \0 is for padding

bw.Flush();
return ms.ToArray();
bw.Flush();
return ms.ToArray();
}
}
private byte[] CreateVersionStream()
{
Expand Down
2 changes: 1 addition & 1 deletion src/EPPlus/ExcelEncryption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public static MemoryStream DecryptPackage(Stream stream, string password)
ms = new MemoryStream(b);
#else
ms = RecyclableMemory.GetStream();
stream.CopyTo(ms);
stream.CopyTo(ms);
#endif
}
return e.DecryptPackage(ms, new ExcelEncryption() { Password = password, _isEncrypted=true });
Expand Down
Loading

0 comments on commit b11ab39

Please sign in to comment.