diff --git a/main/POIFS/FileSystem/FileMagic.cs b/main/POIFS/FileSystem/FileMagic.cs index d3d2d75bc..29ec383c3 100644 --- a/main/POIFS/FileSystem/FileMagic.cs +++ b/main/POIFS/FileSystem/FileMagic.cs @@ -141,20 +141,9 @@ public static FileMagic ValueOf(byte[] magic) { foreach(var fm in Values) { - int i=0; - bool found = true; foreach(byte[] ma in fm.Value.magic) { - foreach(byte m in ma) - { - byte d = magic[i++]; - if(!(d == m || (m == 0x70 && (d == 0x10 || d == 0x20 || d == 0x40)))) - { - found = false; - break; - } - } - if(found) + if(FindMagic(ma, magic)) { return fm.Key; } @@ -162,7 +151,20 @@ public static FileMagic ValueOf(byte[] magic) } return FileMagic.UNKNOWN; } - + private static bool FindMagic(byte[] expected, byte[] actual) + { + int i=0; + foreach(byte expectedByte in expected) + { + byte actualByte = actual[i++]; + if((actualByte != expectedByte && + (expectedByte != 0x70 || (actualByte != 0x10 && actualByte != 0x20 && actualByte != 0x40)))) + { + return false; + } + } + return true; + } /** * Get the file magic of the supplied InputStream (which MUST * support mark and reset).

diff --git a/main/Util/IOUtils.cs b/main/Util/IOUtils.cs index dd5f921a6..4f297ad0f 100644 --- a/main/Util/IOUtils.cs +++ b/main/Util/IOUtils.cs @@ -113,6 +113,10 @@ public static byte[] PeekFirstNBytes(Stream stream, int limit) { is1.Mark(limit); } + else + { + stream.Seek(0, SeekOrigin.Begin); + } ByteArrayOutputStream bos = new ByteArrayOutputStream(limit); if(stream is ByteArrayInputStream inputStream) Copy(new BoundedInputStream(inputStream, limit), bos); @@ -146,7 +150,7 @@ public static byte[] PeekFirstNBytes(Stream stream, int limit) } else { - stream.Position = mark; + stream.Seek(mark, SeekOrigin.Begin); } return peekedBytes; diff --git a/testcases/ooxml/POIFS/FileSystem/TestFileMagic.cs b/testcases/ooxml/POIFS/FileSystem/TestFileMagic.cs new file mode 100644 index 000000000..60275ed28 --- /dev/null +++ b/testcases/ooxml/POIFS/FileSystem/TestFileMagic.cs @@ -0,0 +1,47 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.POIFS.FileSystem; +using NPOI.XSSF.UserModel; +using NUnit.Framework; +using NUnit.Framework.Legacy; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace TestCases.POIFS.FileSystem +{ + [TestFixture] + public class TestFileMagic + { + [Test] + public void TestXSSFWorkbookStreamPositionGreaterThanZero() + { + var workbook = new XSSFWorkbook(); + workbook.CreateSheet("Nothing here"); + var stream = new MemoryStream(); + workbook.Write(stream, leaveOpen: true); + ClassicAssert.AreEqual(FileMagic.OOXML, FileMagicContainer.ValueOf(stream)); + stream.Position = 1; + ClassicAssert.AreEqual(FileMagic.OOXML, FileMagicContainer.ValueOf(stream)); + workbook.Close(); + } + } +}