a .NET library that can read/write Office formats without Microsoft Office installed. No COM+, no interop.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1055 lines
42 KiB

/* ====================================================================
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.OpenXml4Net.OPC;
using NPOI.OpenXml4Net.OPC.Internal;
using System.IO;
using System.Collections.Generic;
using System;
using TestCases.OpenXml4Net;
using NPOI.Util;
using System.Reflection;
using System.Text.RegularExpressions;
using NUnit.Framework;
using System.Xml;
using System.Text;
using ICSharpCode.SharpZipLib.Zip;
using System.Collections;
using NPOI.SS.UserModel;
using NPOI;
using NPOI.Openxml4Net.Exceptions;
namespace TestCases.OpenXml4Net.OPC
{
[TestFixture]
public class TestPackage
{
private static POILogger logger = POILogFactory.GetLogger(typeof(TestPackage));
/**
* Test that just opening and closing the file doesn't alter the document.
*/
[Test]
public void TestOpenSave()
{
String originalFile = OpenXml4NetTestDataSamples.GetSampleFileName("TestPackageCommon.docx");
FileInfo targetFile = OpenXml4NetTestDataSamples.GetOutputFile("TestPackageOpenSaveTMP.docx");
OPCPackage p = OPCPackage.Open(originalFile, PackageAccess.READ_WRITE);
try
{
p.Save(targetFile.FullName);
// Compare the original and newly saved document
Assert.IsTrue(File.Exists(targetFile.FullName));
ZipFileAssert.AssertEqual(new FileInfo(originalFile), targetFile);
File.Delete(targetFile.FullName);
}
finally
{
// use revert to not re-write the input file
p.Revert();
}
}
/**
* Test that when we create a new Package, we give it
* the correct default content types
*/
[Test]
public void TestCreateGetsContentTypes()
{
FileInfo targetFile = OpenXml4NetTestDataSamples.GetOutputFile("TestCreatePackageTMP.docx");
// Zap the target file, in case of an earlier run
if (File.Exists(targetFile.FullName))
{
File.Delete(targetFile.FullName);
Assert.IsFalse(File.Exists(targetFile.FullName));
}
OPCPackage pkg = OPCPackage.Create(targetFile.FullName);
// Check it has content types for rels and xml
ContentTypeManager ctm = GetContentTypeManager(pkg);
Assert.AreEqual(
"application/xml",
ctm.GetContentType(
PackagingUriHelper.CreatePartName("/foo.xml")
)
);
Assert.AreEqual(
ContentTypes.RELATIONSHIPS_PART,
ctm.GetContentType(
PackagingUriHelper.CreatePartName("/foo.rels")
)
);
Assert.IsNull(
ctm.GetContentType(
PackagingUriHelper.CreatePartName("/foo.txt")
)
);
}
/**
* Test namespace creation.
*/
[Test]
public void TestCreatePackageAddPart()
{
FileInfo targetFile = OpenXml4NetTestDataSamples.GetOutputFile("TestCreatePackageTMP.docx");
FileInfo expectedFile = OpenXml4NetTestDataSamples.GetSampleFile("TestCreatePackageOUTPUT.docx");
// Zap the target file, in case of an earlier run
if (targetFile.Exists)
{
targetFile.Delete();
targetFile.Refresh();
Assert.IsFalse(targetFile.Exists);
}
// Create a namespace
OPCPackage pkg = OPCPackage.Create(targetFile.FullName);
PackagePartName corePartName = PackagingUriHelper
.CreatePartName("/word/document.xml");
pkg.AddRelationship(corePartName, TargetMode.Internal,
PackageRelationshipTypes.CORE_DOCUMENT, "rId1");
PackagePart corePart = pkg
.CreatePart(
corePartName,
"application/vnd.openxmlformats-officedocument.wordProcessingml.document.main+xml");
XmlDocument doc = new XmlDocument();
XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
string wuri = "http://schemas.openxmlformats.org/wordProcessingml/2006/main";
mgr.AddNamespace("w", wuri);
XmlElement elDocument = doc.CreateElement("w:document", wuri);
doc.AppendChild(elDocument);
XmlElement elBody = doc.CreateElement("w:body", wuri);
elDocument.AppendChild(elBody);
XmlElement elParagraph = doc.CreateElement("w:p", wuri);
elBody.AppendChild(elParagraph);
XmlElement elRun = doc.CreateElement("w:r", wuri);
elParagraph.AppendChild(elRun);
XmlElement elText = doc.CreateElement("w:t", wuri);
elRun.AppendChild(elText);
elText.InnerText = ("Hello Open XML !");
StreamHelper.SaveXmlInStream(doc, corePart.GetOutputStream());
pkg.Close();
ZipFileAssert.AssertEqual(expectedFile, targetFile);
File.Delete(targetFile.FullName);
}
/**
* Tests that we can create a new namespace, add a core
* document and another part, save and re-load and
* have everything Setup as expected
*/
[Test, RunSerialyAndSweepTmpFiles]
//[Ignore("add relation Uri #Sheet1!A1")]
public void TestCreatePackageWithCoreDocument()
{
MemoryStream baos = new MemoryStream();
OPCPackage pkg = OPCPackage.Create(baos);
// Add a core document
PackagePartName corePartName = PackagingUriHelper.CreatePartName("/xl/workbook.xml");
// Create main part relationship
pkg.AddRelationship(corePartName, TargetMode.Internal, PackageRelationshipTypes.CORE_DOCUMENT, "rId1");
// Create main document part
PackagePart corePart = pkg.CreatePart(corePartName, "application/vnd.Openxmlformats-officedocument.spreadsheetml.sheet.main+xml");
// Put in some dummy content
Stream coreOut = corePart.GetOutputStream();
byte[] buffer = Encoding.UTF8.GetBytes("<dummy-xml />");
coreOut.Write(buffer, 0, buffer.Length);
coreOut.Close();
// And another bit
PackagePartName sheetPartName = PackagingUriHelper.CreatePartName("/xl/worksheets/sheet1.xml");
PackageRelationship rel =
corePart.AddRelationship(sheetPartName, TargetMode.Internal, "http://schemas.Openxmlformats.org/officeDocument/2006/relationships/worksheet", "rSheet1");
Assert.IsNotNull(rel);
PackagePart part = pkg.CreatePart(sheetPartName, "application/vnd.Openxmlformats-officedocument.spreadsheetml.worksheet+xml");
Assert.IsNotNull(part);
// Dummy content again
coreOut = corePart.GetOutputStream();
buffer = Encoding.UTF8.GetBytes("<dummy-xml2 />");
coreOut.Write(buffer, 0, buffer.Length);
coreOut.Close();
//add a relationship with internal target: "#Sheet1!A1"
corePart.AddRelationship(PackagingUriHelper.ToUri("#Sheet1!A1"), TargetMode.Internal, "http://schemas.Openxmlformats.org/officeDocument/2006/relationships/hyperlink", "rId2");
// Check things are as expected
PackageRelationshipCollection coreRels =
pkg.GetRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT);
Assert.AreEqual(1, coreRels.Size);
PackageRelationship coreRel = coreRels.GetRelationship(0);
Assert.IsNotNull(coreRel);
Assert.AreEqual("/", coreRel.SourceUri.ToString());
Assert.AreEqual("/xl/workbook.xml", coreRel.TargetUri.ToString());
Assert.IsNotNull(pkg.GetPart(coreRel));
// Save and re-load
pkg.Close();
FileInfo tmp = TempFile.CreateTempFile("testCreatePackageWithCoreDocument", ".zip");
FileStream fout = new FileStream(tmp.FullName, FileMode.Create, FileAccess.ReadWrite);
try
{
buffer = baos.ToArray();
fout.Write(buffer, 0 , buffer.Length);
}
finally
{
fout.Close();
}
pkg = OPCPackage.Open(tmp.FullName);
//tmp.Delete();
try
{
// Check still right
coreRels = pkg.GetRelationshipsByType(PackageRelationshipTypes.CORE_DOCUMENT);
Assert.AreEqual(1, coreRels.Size);
coreRel = coreRels.GetRelationship(0);
Assert.IsNotNull(coreRel);
Assert.AreEqual("/", coreRel.SourceUri.ToString());
Assert.AreEqual("/xl/workbook.xml", coreRel.TargetUri.ToString());
corePart = pkg.GetPart(coreRel);
Assert.IsNotNull(corePart);
PackageRelationshipCollection rels = corePart.GetRelationshipsByType("http://schemas.Openxmlformats.org/officeDocument/2006/relationships/hyperlink");
Assert.AreEqual(1, rels.Size);
rel = rels.GetRelationship(0);
Assert.IsNotNull(rel);
Assert.Warn(" 'Sheet1!A1' and rel.TargetUri.Fragment should be equal.");
//Assert.AreEqual("Sheet1!A1", rel.TargetUri.Fragment);
assertMSCompatibility(pkg);
}
finally
{
pkg.Close();
}
Assert.AreEqual(0, Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.tmp").Length, "At Last: There are no temporary files.");
}
private void assertMSCompatibility(OPCPackage pkg)
{
PackagePartName relName = PackagingUriHelper.CreatePartName(PackageRelationship.ContainerPartRelationship);
PackagePart relPart = pkg.GetPart(relName);
XmlDocument xmlRelationshipsDoc = DocumentHelper.LoadDocument(relPart.GetInputStream());
XmlElement root = xmlRelationshipsDoc.DocumentElement;
XmlNodeList nodeList = root.GetElementsByTagName(PackageRelationship.RELATIONSHIP_TAG_NAME);
int nodeCount = nodeList.Count;
for (int i = 0; i < nodeCount; i++)
{
XmlElement element = (XmlElement)nodeList.Item(i);
String value = element.GetAttribute(PackageRelationship.TARGET_ATTRIBUTE_NAME);
Assert.IsTrue(value[0] != '/', "Root target must not start with a leading slash ('/'): " + value);
}
}
/**
* Test namespace opening.
*/
[Test, RunSerialyAndSweepTmpFiles]
public void TestOpenPackage()
{
FileInfo targetFile = OpenXml4NetTestDataSamples.GetOutputFile("TestOpenPackageTMP.docx");
FileInfo inputFile = OpenXml4NetTestDataSamples.GetSampleFile("TestOpenPackageINPUT.docx");
FileInfo expectedFile = OpenXml4NetTestDataSamples.GetSampleFile("TestOpenPackageOUTPUT.docx");
// Copy the input file in the output directory
FileHelper.CopyFile(inputFile.FullName, targetFile.FullName);
// Create a namespace
OPCPackage pkg = OPCPackage.Open(targetFile.FullName);
// Modify core part
PackagePartName corePartName = PackagingUriHelper
.CreatePartName("/word/document.xml");
PackagePart corePart = pkg.GetPart(corePartName);
// Delete some part to have a valid document
foreach (PackageRelationship rel in corePart.Relationships)
{
corePart.RemoveRelationship(rel.Id);
pkg.RemovePart(PackagingUriHelper.CreatePartName(PackagingUriHelper
.ResolvePartUri(corePart.PartName.URI, rel
.TargetUri)));
}
// Create a content
XmlDocument doc = new XmlDocument();
XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable);
string wuri = "http://schemas.openxmlformats.org/wordProcessingml/2006/main";
mgr.AddNamespace("w", wuri);
XmlElement elDocument = doc.CreateElement("w:document", wuri);
doc.AppendChild(elDocument);
XmlElement elBody = doc.CreateElement("w:body", wuri);
elDocument.AppendChild(elBody);
XmlElement elParagraph = doc.CreateElement("w:p", wuri);
elBody.AppendChild(elParagraph);
XmlElement elRun = doc.CreateElement("w:r", wuri);
elParagraph.AppendChild(elRun);
XmlElement elText = doc.CreateElement("w:t", wuri);
elRun.AppendChild(elText);
elText.InnerText = ("Hello Open XML !");
StreamHelper.SaveXmlInStream(doc, corePart.GetOutputStream());
// Save and close
try
{
pkg.Close();
}
catch (IOException)
{
Assert.Fail();
}
ZipFileAssert.AssertEqual(expectedFile, targetFile);
File.Delete(targetFile.FullName);
Assert.AreEqual(0, Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.tmp").Length, "At Last: There are no temporary files.");
}
/**
* Checks that we can write a namespace to a simple
* OutputStream, in Addition to the normal writing
* to a file
*/
[Test]
public void TestSaveToOutputStream()
{
String originalFile = OpenXml4NetTestDataSamples.GetSampleFileName("TestPackageCommon.docx");
FileInfo targetFile = OpenXml4NetTestDataSamples.GetOutputFile("TestPackageOpenSaveTMP.docx");
OPCPackage p = OPCPackage.Open(originalFile, PackageAccess.READ_WRITE);
try
{
FileStream fs = targetFile.OpenWrite();
try
{
p.Save(fs);
}
finally
{
fs.Close();
}
// Compare the original and newly saved document
Assert.IsTrue(File.Exists(targetFile.FullName));
ZipFileAssert.AssertEqual(new FileInfo(originalFile), targetFile);
File.Delete(targetFile.FullName);
}
finally
{
p.Revert();
}
}
/**
* Checks that we can open+read a namespace from a
* simple InputStream, in Addition to the normal
* Reading from a file
*/
[Test]
public void TestOpenFromInputStream()
{
String originalFile = OpenXml4NetTestDataSamples.GetSampleFileName("TestPackageCommon.docx");
FileStream finp = new FileStream(originalFile, FileMode.Open, FileAccess.Read);
OPCPackage p = OPCPackage.Open(finp);
Assert.IsNotNull(p);
Assert.IsNotNull(p.Relationships);
Assert.AreEqual(12, p.GetParts().Count);
// Check it has the usual bits
Assert.IsTrue(p.HasRelationships);
Assert.IsTrue(p.ContainPart(PackagingUriHelper.CreatePartName("/_rels/.rels")));
}
/**
* TODO: fix and enable
*/
[Test, Ignore("by poi")]
public void TestRemovePartRecursive()
{
String originalFile = OpenXml4NetTestDataSamples.GetSampleFileName("TestPackageCommon.docx");
FileInfo targetFile = OpenXml4NetTestDataSamples.GetOutputFile("TestPackageRemovePartRecursiveOUTPUT.docx");
FileInfo tempFile = OpenXml4NetTestDataSamples.GetOutputFile("TestPackageRemovePartRecursiveTMP.docx");
OPCPackage p = OPCPackage.Open(originalFile, PackageAccess.READ_WRITE);
p.RemovePartRecursive(PackagingUriHelper.CreatePartName(new Uri(
"/word/document.xml", UriKind.Relative)));
p.Save(tempFile.FullName);
// Compare the original and newly saved document
Assert.IsTrue(File.Exists(targetFile.FullName));
ZipFileAssert.AssertEqual(targetFile, tempFile);
File.Delete(targetFile.FullName);
}
[Test]
public void TestDeletePart()
{
Dictionary<PackagePartName, String> expectedValues;
Dictionary<PackagePartName, String> values;
values = new Dictionary<PackagePartName, String>();
// Expected values
expectedValues = new Dictionary<PackagePartName, String>();
expectedValues.Add(PackagingUriHelper.CreatePartName("/_rels/.rels"),
"application/vnd.openxmlformats-package.relationships+xml");
expectedValues
.Add(PackagingUriHelper.CreatePartName("/docProps/app.xml"),
"application/vnd.openxmlformats-officedocument.extended-properties+xml");
expectedValues.Add(PackagingUriHelper
.CreatePartName("/docProps/core.xml"),
"application/vnd.openxmlformats-package.core-properties+xml");
expectedValues
.Add(PackagingUriHelper.CreatePartName("/word/fontTable.xml"),
"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml");
expectedValues.Add(PackagingUriHelper
.CreatePartName("/word/media/image1.gif"), "image/gif");
expectedValues
.Add(PackagingUriHelper.CreatePartName("/word/settings.xml"),
"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml");
expectedValues
.Add(PackagingUriHelper.CreatePartName("/word/styles.xml"),
"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml");
expectedValues.Add(PackagingUriHelper
.CreatePartName("/word/theme/theme1.xml"),
"application/vnd.openxmlformats-officedocument.theme+xml");
expectedValues
.Add(
PackagingUriHelper
.CreatePartName("/word/webSettings.xml"),
"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml");
String filepath = OpenXml4NetTestDataSamples.GetSampleFileName("sample.docx");
OPCPackage p = OPCPackage.Open(filepath, PackageAccess.READ_WRITE);
// Remove the core part
p.DeletePart(PackagingUriHelper.CreatePartName("/word/document.xml"));
foreach (PackagePart part in p.GetParts())
{
values.Add(part.PartName, part.ContentType);
logger.Log(POILogger.DEBUG, part.PartName);
}
// Compare expected values with values return by the namespace
foreach (PackagePartName partName in expectedValues.Keys)
{
Assert.IsNotNull(values[partName]);
Assert.AreEqual(expectedValues[partName], values[partName]);
}
// Don't save modifications
p.Revert();
}
[Test]
public void TestDeletePartRecursive()
{
Dictionary<PackagePartName, String> expectedValues;
Dictionary<PackagePartName, String> values;
values = new Dictionary<PackagePartName, String>();
// Expected values
expectedValues = new Dictionary<PackagePartName, String>();
expectedValues.Add(PackagingUriHelper.CreatePartName("/_rels/.rels"),
"application/vnd.openxmlformats-package.relationships+xml");
expectedValues
.Add(PackagingUriHelper.CreatePartName("/docProps/app.xml"),
"application/vnd.openxmlformats-officedocument.extended-properties+xml");
expectedValues.Add(PackagingUriHelper
.CreatePartName("/docProps/core.xml"),
"application/vnd.openxmlformats-package.core-properties+xml");
String filepath = OpenXml4NetTestDataSamples.GetSampleFileName("sample.docx");
OPCPackage p = OPCPackage.Open(filepath, PackageAccess.READ_WRITE);
// Remove the core part
p.DeletePartRecursive(PackagingUriHelper.CreatePartName("/word/document.xml"));
foreach (PackagePart part in p.GetParts())
{
values.Add(part.PartName, part.ContentType);
logger.Log(POILogger.DEBUG, part.PartName);
}
// Compare expected values with values return by the namespace
foreach (PackagePartName partName in expectedValues.Keys)
{
Assert.IsNotNull(values[partName]);
Assert.AreEqual(expectedValues[partName], values[partName]);
}
// Don't save modifications
p.Revert();
}
/**
* Test that we can open a file by path, and then
* write Changes to it.
*/
[Test, RunSerialyAndSweepTmpFiles]
public void TestOpenFileThenOverWrite()
{
string tempFile = TempFile.GetTempFilePath("poiTesting", "tmp");
FileInfo origFile = OpenXml4NetTestDataSamples.GetSampleFile("TestPackageCommon.docx");
FileHelper.CopyFile(origFile.FullName, tempFile);
// Open the temp file
OPCPackage p = OPCPackage.Open(tempFile, PackageAccess.READ_WRITE);
// Close it
p.Close();
// Delete it
File.Delete(tempFile);
// Reset
FileHelper.CopyFile(origFile.FullName, tempFile);
p = OPCPackage.Open(tempFile, PackageAccess.READ_WRITE);
// Save it to the same file - not allowed
try
{
p.Save(tempFile);
Assert.Fail("You shouldn't be able to call save(File) to overwrite the current file");
}
catch (IOException) { }
p.Close();
// Delete it
File.Delete(tempFile);
// Open it read only, then close and delete - allowed
FileHelper.CopyFile(origFile.FullName, tempFile);
p = OPCPackage.Open(tempFile, PackageAccess.READ);
p.Close();
File.Delete(tempFile);
Assert.AreEqual(0, Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.tmp").Length, "At Last: There are no temporary files.");
}
/**
* Test that we can open a file by path, save it
* to another file, then delete both
*/
[Test, RunSerialyAndSweepTmpFiles]
public void TestOpenFileThenSaveDelete()
{
string tempFile = TempFile.GetTempFilePath("poiTesting", "tmp");
string tempFile2 = TempFile.GetTempFilePath("poiTesting", "tmp");
FileInfo origFile = OpenXml4NetTestDataSamples.GetSampleFile("TestPackageCommon.docx");
FileHelper.CopyFile(origFile.FullName, tempFile);
// Open the temp file
OPCPackage p = OPCPackage.Open(tempFile, PackageAccess.READ_WRITE);
// Save it to a different file
p.Save(tempFile2);
p.Close();
// Delete both the files
File.Delete(tempFile);
File.Delete(tempFile2);
Assert.AreEqual(0, Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.tmp").Length, "At Last: There are no temporary files.");
}
private static ContentTypeManager GetContentTypeManager(OPCPackage pkg)
{
FieldInfo f = typeof(OPCPackage).GetField("contentTypeManager", BindingFlags.NonPublic | BindingFlags.Instance);
//f.SetAccessible(true);
return (ContentTypeManager)f.GetValue(pkg);
}
[Test]
public void TestGetPartsByName()
{
String filepath = OpenXml4NetTestDataSamples.GetSampleFileName("sample.docx");
OPCPackage pkg = OPCPackage.Open(filepath, PackageAccess.READ_WRITE);
try
{
List<PackagePart> rs = pkg.GetPartsByName(new Regex("^/word/.*?\\.xml$"));
Dictionary<String, PackagePart> selected = new Dictionary<String, PackagePart>();
foreach (PackagePart p in rs)
selected.Add(p.PartName.Name, p);
Assert.AreEqual(6, selected.Count);
Assert.IsTrue(selected.ContainsKey("/word/document.xml"));
Assert.IsTrue(selected.ContainsKey("/word/fontTable.xml"));
Assert.IsTrue(selected.ContainsKey("/word/settings.xml"));
Assert.IsTrue(selected.ContainsKey("/word/styles.xml"));
Assert.IsTrue(selected.ContainsKey("/word/theme/theme1.xml"));
Assert.IsTrue(selected.ContainsKey("/word/webSettings.xml"));
}
finally
{
pkg.Revert();
}
}
[Test]
public void TestGetPartSize()
{
String filepath = OpenXml4NetTestDataSamples.GetSampleFileName("sample.docx");
OPCPackage pkg = OPCPackage.Open(filepath, PackageAccess.READ);
try
{
int checked1 = 0;
foreach (PackagePart part in pkg.GetParts())
{
// Can get the size of zip parts
if (part.PartName.Name.Equals("/word/document.xml"))
{
checked1++;
Assert.AreEqual(typeof(ZipPackagePart), part.GetType());
Assert.AreEqual(6031L, part.Size);
}
if (part.PartName.Name.Equals("/word/fontTable.xml"))
{
checked1++;
Assert.AreEqual(typeof(ZipPackagePart), part.GetType());
Assert.AreEqual(1312L, part.Size);
}
// But not from the others
if (part.PartName.Name.Equals("/docProps/core.xml"))
{
checked1++;
Assert.AreEqual(typeof(PackagePropertiesPart), part.GetType());
Assert.AreEqual(-1, part.Size);
}
}
// Ensure we actually found the parts we want to check
Assert.AreEqual(3, checked1);
}
finally
{
pkg.Revert();
}
}
[Test]
public void TestReplaceContentType()
{
Stream is1 = OpenXml4NetTestDataSamples.OpenSampleStream("sample.xlsx");
OPCPackage p = OPCPackage.Open(is1);
ContentTypeManager mgr = GetContentTypeManager(p);
Assert.True(mgr.IsContentTypeRegister("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"));
Assert.False(mgr.IsContentTypeRegister("application/vnd.ms-excel.sheet.macroEnabled.main+xml"));
Assert.True(
p.ReplaceContentType(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
"application/vnd.ms-excel.sheet.macroEnabled.main+xml")
);
Assert.False(mgr.IsContentTypeRegister("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"));
Assert.True(mgr.IsContentTypeRegister("application/vnd.ms-excel.sheet.macroEnabled.main+xml"));
}
/**
* Verify we give helpful exceptions (or as best we can) when
* supplied with non-OOXML file types (eg OLE2, ODF)
*/
[Ignore("not found in poi test cases")]
[Test]
public void NonOOXMLFileTypes()
{
// Spreadsheet has a good mix of alternate file types
POIDataSamples files = POIDataSamples.GetSpreadSheetInstance();
// OLE2 - Stream
try
{
Stream stream = files.OpenResourceAsStream("SampleSS.xls");
try
{
OPCPackage.Open(stream);
}
finally
{
stream.Dispose();//.Close();
}
Assert.Fail("Shouldn't be able to open OLE2");
}
catch (OLE2NotOfficeXmlFileException e)
{
Assert.IsTrue(e.Message.Contains("The supplied data appears to be in the OLE2 Format"));
Assert.IsTrue(e.Message.Contains("You are calling the part of POI that deals with OOXML"));
}
// OLE2 - File
try
{
OPCPackage.Open(files.GetFile("SampleSS.xls"));
Assert.Fail("Shouldn't be able to open OLE2");
}
catch (OLE2NotOfficeXmlFileException e)
{
Assert.IsTrue(e.Message.Contains("The supplied data appears to be in the OLE2 Format"));
Assert.IsTrue(e.Message.Contains("You are calling the part of POI that deals with OOXML"));
}
// Raw XML - Stream
try
{
Stream stream = files.OpenResourceAsStream("SampleSS.xml");
try
{
OPCPackage.Open(stream);
}
finally
{
stream.Dispose();//.Close();
}
Assert.Fail("Shouldn't be able to open XML");
}
catch (NotOfficeXmlFileException e)
{
Assert.IsTrue(e.Message.Contains("The supplied data appears to be a raw XML file"));
Assert.IsTrue(e.Message.Contains("Formats such as Office 2003 XML"));
}
// Raw XML - File
try
{
OPCPackage.Open(files.GetFile("SampleSS.xml"));
Assert.Fail("Shouldn't be able to open XML");
}
catch (NotOfficeXmlFileException e)
{
Assert.IsTrue(e.Message.Contains("The supplied data appears to be a raw XML file"));
Assert.IsTrue(e.Message.Contains("Formats such as Office 2003 XML"));
}
// ODF / ODS - Stream
try
{
Stream stream = files.OpenResourceAsStream("SampleSS.ods");
try
{
OPCPackage.Open(stream);
}
finally
{
stream.Dispose();//.Close();
}
Assert.Fail("Shouldn't be able to open ODS");
}
catch (ODFNotOfficeXmlFileException e)
{
Assert.IsTrue(e.ToString().Contains("The supplied data appears to be in ODF"));
Assert.IsTrue(e.ToString().Contains("Formats like these (eg ODS"));
}
// ODF / ODS - File
try
{
OPCPackage.Open(files.GetFile("SampleSS.ods"));
Assert.Fail("Shouldn't be able to open ODS");
}
catch (ODFNotOfficeXmlFileException e)
{
Assert.IsTrue(e.ToString().Contains("The supplied data appears to be in ODF"));
Assert.IsTrue(e.ToString().Contains("Formats like these (eg ODS"));
}
// Plain Text - Stream
try
{
Stream stream = files.OpenResourceAsStream("SampleSS.txt");
try
{
OPCPackage.Open(stream);
}
finally
{
stream.Dispose();//.Close();
}
Assert.Fail("Shouldn't be able to open Plain Text");
}
catch (NotOfficeXmlFileException e)
{
Assert.IsTrue(e.Message.Contains("No valid entries or contents found"));
Assert.IsTrue(e.Message.Contains("not a valid OOXML"));
}
// Plain Text - File
try
{
OPCPackage.Open(files.GetFile("SampleSS.txt"));
Assert.Fail("Shouldn't be able to open Plain Text");
}
catch (UnsupportedFileFormatException)
{
// Unhelpful low-level error, sorry
}
}
//[Test, Ignore("need ZipSecureFile and ByteArrayOutputStream class")]
//public void ZipBombCreateAndHandle()
//{
// // #50090 / #56865
// ZipFile zipFile = ZipHelper.OpenZipFile(OpenXml4NetTestDataSamples.GetSampleFile("sample.xlsx"));
// Assert.IsNotNull(zipFile);
// ByteArrayOutputStream bos = new ByteArrayOutputStream(2500000);
// ZipOutputStream append = new ZipOutputStream(bos);
// // first, copy contents from existing war
// IEnumerator entries = zipFile.GetEnumerator();
// while (entries.MoveNext())
// {
// ZipEntry e2 = (ZipEntry)entries.Current;
// ZipEntry e = new ZipEntry(e2.Name);
// e.DateTime = (e2.DateTime);
// e.Comment = (e2.Comment);
// e.Size = (e2.Size);
// append.PutNextEntry(e);
// if (!e.IsDirectory)
// {
// Stream is1 = zipFile.GetInputStream(e);
// if (e.Name.Equals("[Content_Types].xml"))
// {
// ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
// IOUtils.Copy(is1, bos2);
// long size = bos2.Length - "</Types>".Length;
// append.Write(bos2.ToByteArray(), 0, (int)size);
// byte[] spam = new byte[0x7FFF];
// for (int i = 0; i < spam.Length; i++) spam[i] = (byte)' ';
// // 0x7FFF0000 is the maximum for 32-bit zips, but less still works
// while (size < 0x7FFF0000)
// {
// append.Write(spam, 0, spam.Length);
// size += spam.Length;
// }
// append.Write(Encoding.ASCII.GetBytes("</Types>"), 0, 8);
// size += 8;
// e.Size = (size);
// }
// else
// {
// IOUtils.Copy(is1, append);
// }
// }
// append.CloseEntry();
// }
// append.Close();
// zipFile.Close();
// byte[] buf = bos.ToByteArray();
// bos = null;
// IWorkbook wb = WorkbookFactory.Create(new ByteArrayInputStream(buf));
// wb.GetSheetAt(0);
// wb.Close();
// zipFile.Close();
//}
[Test, Ignore("need ZipSecureFile class")]
public void ZipBombCheckSizes()
{
//FileInfo file = OpenXml4NetTestDataSamples.GetSampleFile("sample.xlsx");
//try
//{
// double min_ratio = Double.MaxValue;
// long max_size = 0;
// ZipFile zf = ZipHelper.OpenZipFile(file);
// assertNotNull(zf);
// IEnumerator entries = zf.GetEnumerator();
// while (entries.MoveNext())
// {
// ZipEntry ze = (ZipEntry)entries.Current;
// double ratio = (double)ze.CompressedSize / (double)ze.Size;
// min_ratio = Math.Min(min_ratio, ratio);
// max_size = Math.Max(max_size, ze.Size);
// }
// zf.Close();
// // use values close to, but within the limits
// ZipSecureFile.SetMinInflateRatio(min_ratio - 0.002);
// assertEquals(min_ratio - 0.002, ZipSecureFile.getMinInflateRatio(), 0.00001);
// ZipSecureFile.SetMaxEntrySize(max_size + 1);
// assertEquals(max_size + 1, ZipSecureFile.getMaxEntrySize());
// IWorkbook wb = WorkbookFactory.Create(file.FullName, null, true);
// wb.Close();
// // check ratio ouf of bounds
// ZipSecureFile.setMinInflateRatio(min_ratio + 0.002);
// try
// {
// wb = WorkbookFactory.Create(file.FullName, null, true);
// wb.Close();
// // this is a bit strange, as there will be different exceptions thrown
// // depending if this executed via "ant test" or within eclipse
// // maybe a difference in JDK ...
// }
// catch (InvalidDataException e)
// {
// checkForZipBombException(e);
// }
// catch (POIXMLException e)
// {
// checkForZipBombException(e);
// }
// // check max entry size ouf of bounds
// ZipSecureFile.SetMinInflateRatio(min_ratio - 0.002);
// ZipSecureFile.SetMaxEntrySize(max_size - 1);
// try
// {
// wb = WorkbookFactory.Create(file.FullName, null, true);
// wb.Close();
// }
// catch (InvalidDataException e)
// {
// checkForZipBombException(e);
// }
// catch (POIXMLException e)
// {
// checkForZipBombException(e);
// }
//}
//finally
//{
// // reset otherwise a lot of ooxml tests will fail
// ZipSecureFile.SetMinInflateRatio(0.01d);
// ZipSecureFile.SetMaxEntrySize(0xFFFFFFFFL);
//}
}
private void checkForZipBombException(Exception e)
{
//if (e is InvocationTargetException) {
// InvocationTargetException t = (InvocationTargetException)e;
// IOException t2 = (IOException)t.getTargetException();
// if (t2.Message.StartsWith("Zip bomb detected!"))
// {
// return;
// }
//}
if (e.Message.StartsWith("Zip bomb detected! Exiting."))
{
return;
}
// recursively check the causes for the message as it can be nested further down in the exception-tree
if (e.InnerException != null && e.InnerException != e)
{
checkForZipBombException(e.InnerException);
return;
}
throw new InvalidOperationException("Expected to catch an Exception because of a detected Zip Bomb, but did not find the related error message in the exception", e);
}
[Ignore("need ZipSecureFile class")]
[Test]
public void TestConstructors()
{
//// verify the various ways to construct a ZipSecureFile
//File file = OpenXML4JTestDataSamples.GetSampleFile("sample.xlsx");
//ZipSecureFile zipFile = new ZipSecureFile(file);
//Assert.IsNotNull(zipFile.Name);
//zipFile.close();
//zipFile = new ZipSecureFile(file, ZipFile.OPEN_READ);
//Assert.IsNotNull(zipFile.Name);
//zipFile.close();
//zipFile = new ZipSecureFile(file.AbsolutePath);
//Assert.IsNotNull(zipFile.Name);
//zipFile.close();
}
[Ignore("need ZipSecureFile class")]
[Test]
public void TestMaxTextSize()
{
//long before = ZipSecureFile.MaxTextSize;
//try
//{
// ZipSecureFile.MaxTextSize = 12345;
// Assert.AreEqual(12345, ZipSecureFile.MaxTextSize);
//}
//finally
//{
// ZipSecureFile.MaxTextSize = before;
//}
}
// bug 60128
[Test]
public void TestCorruptFile()
{
OPCPackage pkg = null;
FileInfo file = OpenXml4NetTestDataSamples.GetSampleFile("invalid.xlsx");
try
{
pkg = OPCPackage.Open(file, PackageAccess.READ);
}
catch (Exception e)
{
//System.out.println(e.GetClass().getName());
//System.out.println(e.GetMessage());
//e.printStackTrace();
}
finally
{
if (pkg != null)
{
pkg.Close();
}
}
}
}
}