diff --git a/main/HSSF/UserModel/HSSFPicture.cs b/main/HSSF/UserModel/HSSFPicture.cs
index a1c0672cd..ff9210f86 100644
--- a/main/HSSF/UserModel/HSSFPicture.cs
+++ b/main/HSSF/UserModel/HSSFPicture.cs
@@ -91,23 +91,22 @@ public void Resize(double scale)
Resize(scale, scale);
}
- /**
- * Resize the image
- *
- * Please note, that this method works correctly only for workbooks
- * with default font size (Arial 10pt for .xls).
- * If the default font is changed the resized image can be streched vertically or horizontally.
- *
- *
- * resize(1.0,1.0)
keeps the original size,
- * resize(0.5,0.5)
resize to 50% of the original,
- * resize(2.0,2.0)
resizes to 200% of the original.
- * resize({@link Double#MAX_VALUE},{@link Double#MAX_VALUE})
resizes to the dimension of the embedded image.
- *
- *
- * @param scaleX the amount by which the image width is multiplied relative to the original width.
- * @param scaleY the amount by which the image height is multiplied relative to the original height.
- */
+ ///
+ /// Resize the image
+ ///
+ /// Please note, that this method works correctly only for workbooks
+ /// with default font size (Arial 10pt for .xls).
+ /// If the default font is changed the resized image can be streched vertically or horizontally.
+ ///
+ /// - resize(1.0,1.0) keeps the original size,
+ /// - resize(0.5,0.5) resize to 50% of the original,
+ /// - resize(2.0,2.0) resizes to 200% of the original.
+ /// - resize(,) resizes to the dimension of the embedded image.
+ ///
+ ///
+ ///
+ /// the amount by which the image width is multiplied relative to the original width.
+ /// the amount by which the image height is multiplied relative to the original height.
public void Resize(double scaleX, double scaleY)
{
HSSFClientAnchor anchor = (HSSFClientAnchor)ClientAnchor;
@@ -118,7 +117,7 @@ public void Resize(double scaleX, double scaleY)
int row2 = anchor.Row1 + (pref.Row2 - pref.Row1);
int col2 = anchor.Col1 + (pref.Col2 - pref.Col1);
- anchor.Col2=((short)col2);
+ anchor.Col2=((short) col2);
// anchor.setDx1(0);
anchor.Dx2=(pref.Dx2);
@@ -135,7 +134,7 @@ public int PictureIndex
get
{
EscherSimpleProperty property = (EscherSimpleProperty)GetOptRecord().Lookup(EscherProperties.BLIP__BLIPTODISPLAY);
- if (null == property)
+ if(null == property)
{
return -1;
}
@@ -146,17 +145,17 @@ public int PictureIndex
SetPropertyValue(new EscherSimpleProperty(EscherProperties.BLIP__BLIPTODISPLAY, false, true, value));
}
}
- /**
- * Calculate the preferred size for this picture.
- *
- * @param scale the amount by which image dimensions are multiplied relative to the original size.
- * @return HSSFClientAnchor with the preferred size for this image
- * @since POI 3.0.2
- */
+
+ ///
+ /// Calculate the preferred size for this picture.
+ ///
+ /// the amount by which image dimensions are multiplied relative to the original size.
+ /// HSSFClientAnchor with the preferred size for this image
public IClientAnchor GetPreferredSize(double scale)
{
return GetPreferredSize(scale, scale);
}
+
///
/// Calculate the preferred size for this picture.
///
@@ -167,7 +166,7 @@ public IClientAnchor GetPreferredSize(double scaleX, double scaleY)
{
ImageUtils.SetPreferredSize(this, scaleX, scaleY);
return ClientAnchor;
-
+
}
///
@@ -194,7 +193,7 @@ protected Size GetResolution(Image r)
{
//int hdpi = 96, vdpi = 96;
//double mm2inch = 25.4;
- return new Size((int)r.Metadata.HorizontalResolution, (int)r.Metadata.VerticalResolution);
+ return new Size((int) r.Metadata.HorizontalResolution, (int) r.Metadata.VerticalResolution);
}
///
@@ -208,24 +207,35 @@ public Size GetImageDimension()
byte[] data = bse.BlipRecord.PictureData;
//int type = bse.BlipTypeWin32;
- using (MemoryStream ms = RecyclableMemory.GetStream(data))
+ using(MemoryStream ms = RecyclableMemory.GetStream(data))
{
- using (Image img = Image.Load(ms))
+ using(Image img = Image.Load(ms))
{
return img.Size();
}
}
}
- /**
- * Return picture data for this shape
- *
- * @return picture data for this shape
- */
+
+ ///
+ /// Return picture data for this shape
+ ///
public IPictureData PictureData
{
get
{
- InternalWorkbook iwb = ((_patriarch.Sheet.Workbook) as HSSFWorkbook).Workbook;
+ HSSFPatriarch patriarch = Patriarch;
+ HSSFShape parent = Parent as HSSFShape;
+ while(patriarch == null && parent != null)
+ {
+ patriarch = parent.Patriarch;
+ parent = parent.Parent as HSSFShape;
+ }
+ if(patriarch == null)
+ {
+ throw new InvalidOperationException("Could not find a patriarch for a HSSPicture");
+ }
+
+ InternalWorkbook iwb = (patriarch.Sheet.Workbook as HSSFWorkbook).Workbook;
EscherBSERecord bse = iwb.GetBSERecord(PictureIndex);
EscherBlipRecord blipRecord = bse.BlipRecord;
return new HSSFPictureData(blipRecord);
@@ -237,7 +247,7 @@ internal override void AfterInsert(HSSFPatriarch patriarch)
{
EscherAggregate agg = patriarch.GetBoundAggregate();
agg.AssociateShapeToObjRecord(GetEscherContainer().GetChildById(EscherClientDataRecord.RECORD_ID), GetObjRecord());
- if (PictureIndex != -1)
+ if(PictureIndex != -1)
{
EscherBSERecord bse =
(patriarch.Sheet.Workbook as HSSFWorkbook).Workbook.GetBSERecord(PictureIndex);
@@ -245,9 +255,9 @@ internal override void AfterInsert(HSSFPatriarch patriarch)
}
}
- /**
- * The color applied to the lines of this shape.
- */
+ ///
+ /// The color applied to the lines of this shape.
+ ///
public String FileName
{
get
@@ -271,11 +281,11 @@ private String Trim(string value)
//int off = offset; /* avoid getfield opcode */
char[] val = value.ToCharArray(); /* avoid getfield opcode */
- while ((st < end) && (val[st] <= ' '))
+ while((st < end) && (val[st] <= ' '))
{
st++;
}
- while ((st < end) && (val[end - 1] <= ' '))
+ while((st < end) && (val[end - 1] <= ' '))
{
end--;
}
@@ -302,22 +312,22 @@ internal override HSSFShape CloneShape()
}
- /**
- * @return the anchor that is used by this picture.
- */
+ ///
+ /// the anchor that is used by this picture.
+ ///
public IClientAnchor ClientAnchor
{
get
{
HSSFAnchor a = Anchor as HSSFAnchor;
- return (a is HSSFClientAnchor) ? (HSSFClientAnchor)a : null;
+ return (a is HSSFClientAnchor) ? (HSSFClientAnchor) a : null;
}
}
- /**
- * @return the sheet which contains the picture shape
- */
+ ///
+ /// the sheet which contains the picture shape
+ ///
public ISheet Sheet
{
get
diff --git a/testcases/main/POITestCase.cs b/testcases/main/POITestCase.cs
index a68aefc78..7f207beca 100644
--- a/testcases/main/POITestCase.cs
+++ b/testcases/main/POITestCase.cs
@@ -32,31 +32,58 @@ namespace TestCases
*/
public class POITestCase
{
- public static void AssertContains(String haystack, String needle)
+ public static void AssertStartsWith(String actual, String prefix)
{
- Assert.IsTrue(
- haystack.Contains(needle),
- "Unable to find expected text '" + needle + "' in text:\n" + haystack
- );
+ Assert.IsNotNull(actual);
+ Assert.IsNotNull(prefix);
+ StringAssert.StartsWith(prefix, actual);
}
- public static void AssertContainsIgnoreCase(String haystack, String needle, CultureInfo locale)
+
+ public static void AssertStartsWith(String message, String actual, String prefix)
+ {
+ Assert.IsNotNull(message, actual);
+ Assert.IsNotNull(message, prefix);
+ StringAssert.StartsWith(prefix, actual, message);
+ }
+
+ public static void AssertEndsWith(String actual, String suffix)
+ {
+ Assert.IsNotNull(actual);
+ Assert.IsNotNull(suffix);
+ StringAssert.EndsWith(suffix, actual);
+ }
+
+ public static void AssertContains(String actual, String expected)
+ {
+ Assert.IsNotNull(actual);
+ Assert.IsNotNull(expected);
+ StringAssert.Contains(expected, actual);
+ }
+ public static void AssertContains(String message, String actual, String expected)
+ {
+ Assert.IsNotNull(actual, message);
+ Assert.IsNotNull(expected, message);
+ StringAssert.Contains(expected, actual, message);
+ }
+
+ public static void AssertContainsIgnoreCase(String actual, String expected, CultureInfo locale)
{
- Assert.IsNotNull(haystack);
- Assert.IsNotNull(needle);
- String hay = haystack.ToLower(locale);
- String n = needle.ToLower(locale);
- Assert.IsTrue(hay.Contains(n), "Unable to find expected text '" + needle + "' in1 text:\n" + haystack);
+ Assert.IsNotNull(actual);
+ Assert.IsNotNull(expected);
+ string hay = actual.ToLower(locale);
+ string n = expected.ToLower(locale);
+ StringAssert.Contains(n, hay, "Unable to find expected text '" + expected + "' in1 text:\n" + actual);
}
- public static void AssertContainsIgnoreCase(String haystack, String needle)
+ public static void AssertContainsIgnoreCase(String actual, String expected)
{
- AssertContainsIgnoreCase(haystack, needle, CultureInfo.CurrentCulture);
+ AssertContainsIgnoreCase(actual, expected, CultureInfo.CurrentCulture);
}
- public static void AssertNotContained(String haystack, String needle)
+ public static void AssertNotContained(String actual, String expected)
{
- Assert.IsFalse(haystack.Contains(needle),
- "Unexpectedly found text '" + needle + "' in text:\n" + haystack
- );
+ Assert.IsNotNull(actual);
+ Assert.IsNotNull(expected);
+ StringAssert.DoesNotContain(expected, actual, "Unexpectedly found text '" + expected + "' in text:\n" + actual);
}
/**
@@ -65,7 +92,7 @@ public static void AssertNotContained(String haystack, String needle)
*/
public static void AssertContains(Dictionary map, TKey key)
{
- if (map.ContainsKey(key))
+ if(map.ContainsKey(key))
{
return;
}
@@ -74,7 +101,7 @@ public static void AssertContains(Dictionary map, TK
public static void AssertEquals(T[] expected, T[] actual)
{
Assert.AreEqual(expected.Length, actual.Length, "Non-matching lengths");
- for (int i = 0; i < expected.Length; i++)
+ for(int i = 0; i < expected.Length; i++)
{
Assert.AreEqual(expected[i], actual[i], "Mis-match at offset " + i);
}
@@ -82,7 +109,7 @@ public static void AssertEquals(T[] expected, T[] actual)
public static void AssertEquals(byte[] expected, byte[] actual)
{
Assert.AreEqual(expected.Length, actual.Length, "Non-matching lengths");
- for (int i = 0; i < expected.Length; i++)
+ for(int i = 0; i < expected.Length; i++)
{
Assert.AreEqual(expected[i], actual[i], "Mis-match at offset " + i);
}
@@ -90,9 +117,9 @@ public static void AssertEquals(byte[] expected, byte[] actual)
public static void AssertContains(T needle, T[] haystack)
{
// Check
- foreach (T thing in haystack)
+ foreach(T thing in haystack)
{
- if (thing.Equals(needle))
+ if(thing.Equals(needle))
{
return;
}
@@ -101,7 +128,7 @@ public static void AssertContains(T needle, T[] haystack)
// Failed, try to build a nice error
StringBuilder sb = new StringBuilder();
sb.Append("Unable to find ").Append(needle).Append(" in [");
- foreach (T thing in haystack)
+ foreach(T thing in haystack)
{
sb.Append(" ").Append(thing.ToString()).Append(" ,");
}
@@ -112,7 +139,7 @@ public static void AssertContains(T needle, T[] haystack)
public static void AssertContains(T needle, IList haystack)
{
- if (haystack.Contains(needle))
+ if(haystack.Contains(needle))
{
return;
}
@@ -125,10 +152,10 @@ public static R GetFieldValue(Type clazz, T instance, Type fieldType, Stri
try
{
FieldInfo fieldInfo = clazz.GetField(fieldName, BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
- return (R)fieldInfo.GetValue(instance);
+ return (R) fieldInfo.GetValue(instance);
}
- catch (Exception pae)
+ catch(Exception pae)
{
throw new RuntimeException("Cannot access field '" + fieldName + "' of class " + clazz, pae.InnerException);
}
diff --git a/testcases/main/TestPOITestCase.cs b/testcases/main/TestPOITestCase.cs
index d81a99c54..bd3236786 100644
--- a/testcases/main/TestPOITestCase.cs
+++ b/testcases/main/TestPOITestCase.cs
@@ -28,6 +28,22 @@ namespace TestCases
[TestFixture]
public class TestPOITestCase
{
+ [Test]
+ public void AssertStartsWith()
+ {
+ POITestCase.AssertStartsWith("Apache POI", "");
+ POITestCase.AssertStartsWith("Apache POI", "Apache");
+ POITestCase.AssertStartsWith("Apache POI", "Apache POI");
+ }
+
+ [Test]
+ public void AssertEndsWith()
+ {
+ POITestCase.AssertEndsWith("Apache POI", "");
+ POITestCase.AssertEndsWith("Apache POI", "POI");
+ POITestCase.AssertEndsWith("Apache POI", "Apache POI");
+ }
+
[Test]
public void AssertContains()
{
diff --git a/testcases/openxml4net/TestPackage.cs b/testcases/openxml4net/TestPackage.cs
index 5bd3d73c1..8caa26f3e 100644
--- a/testcases/openxml4net/TestPackage.cs
+++ b/testcases/openxml4net/TestPackage.cs
@@ -20,15 +20,12 @@ limitations under the License.
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;
@@ -842,7 +839,7 @@ public void NonOOXMLFileTypes()
// {
// ZipEntry e2 = (ZipEntry)entries.Current;
// ZipEntry e = new ZipEntry(e2.Name);
-
+
// e.DateTime = (e2.DateTime);
// e.Comment = (e2.Comment);
// e.Size = (e2.Size);
@@ -889,6 +886,47 @@ public void NonOOXMLFileTypes()
// zipFile.Close();
//}
+ [Test, Ignore("need ExtractorFactory class")]
+ public void ZipBombSampleFiles() {
+
+ openZipBombFile("poc-shared-strings.xlsx");
+ openZipBombFile("poc-xmlbomb.xlsx");
+ openZipBombFile("poc-xmlbomb-empty.xlsx");
+ }
+
+ private void openZipBombFile(String file)
+ {
+ try
+ {
+ IWorkbook wb = NPOI.XSSF.XSSFTestDataSamples.OpenSampleWorkbook(file);
+ wb.Close();
+
+ //POITextExtractor extractor = ExtractorFactory.CreateExtractor(TestCases.HSSF.HSSFTestDataSamples.GetSampleFile("poc-shared-strings.xlsx"));
+ //try
+ //{
+ // Assert.IsNotNull(extractor);
+ // var _ = extractor.Text;
+ //}
+ //finally
+ //{
+ // extractor.Close();
+ //}
+
+ Assert.Fail("Should catch an exception because of a ZipBomb");
+ }
+ catch (InvalidOperationException e)
+ {
+ if (!e.Message.Contains("The text would exceed the max allowed overall size of extracted text."))
+ {
+ throw e;
+ }
+ }
+ catch (POIXMLException e)
+ {
+ checkForZipBombException(e);
+ }
+ }
+
[Test, Ignore("need ZipSecureFile class")]
public void ZipBombCheckSizes()
{
@@ -964,16 +1002,15 @@ public void ZipBombCheckSizes()
private void checkForZipBombException(Exception e)
{
+ // unwrap InvocationTargetException as they usually contain the nested exception in the "target" member
//if (e is InvocationTargetException) {
- // InvocationTargetException t = (InvocationTargetException)e;
- // IOException t2 = (IOException)t.getTargetException();
- // if (t2.Message.StartsWith("Zip bomb detected!"))
- // {
- // return;
- // }
+ // e = ((InvocationTargetException)e).getTargetException();
//}
- if (e.Message.StartsWith("Zip bomb detected! Exiting."))
+ String msg = e.Message;
+ if (msg != null && (msg.StartsWith("Zip bomb detected!") ||
+ msg.Contains("The parser has encountered more than \"4,096\" entity expansions in this document;") ||
+ msg.Contains("The parser has encountered more than \"4096\" entity expansions in this document;")))
{
return;
}
diff --git a/testcases/test-data/spreadsheet/poc-xmlbomb-empty.xlsx b/testcases/test-data/spreadsheet/poc-xmlbomb-empty.xlsx
new file mode 100644
index 000000000..e69de29bb