diff --git a/OpenXmlFormats/Vml/Main.cs b/OpenXmlFormats/Vml/Main.cs
index 200143488..c4c8a2970 100644
--- a/OpenXmlFormats/Vml/Main.cs
+++ b/OpenXmlFormats/Vml/Main.cs
@@ -11,6 +11,7 @@
using System.Text;
using System.ComponentModel;
using NPOI.OpenXml4Net.Util;
+using NPOI.Util;
namespace NPOI.OpenXmlFormats.Vml
{
@@ -634,6 +635,7 @@ public class CT_Shape {
private ST_TrueFalse strokedField;
private string wrapcoordsField;
+ private string _xml;
public static CT_Shape Parse(XmlNode node, XmlNamespaceManager namespaceManager)
{
if (node == null)
@@ -693,11 +695,28 @@ public static CT_Shape Parse(XmlNode node, XmlNamespaceManager namespaceManager)
else if (childNode.LocalName == "ClientData")
ctObj.ClientData.Add(CT_ClientData.Parse(childNode, namespaceManager));
}
+ ctObj._xml = node.OuterXml;
return ctObj;
}
-
+ public override string ToString()
+ {
+ if(string.IsNullOrEmpty(this._xml))
+ {
+ using(MemoryStream out1 = new MemoryStream())
+ using(StreamWriter sw = new StreamWriter(out1))
+ {
+ Write(sw, "shape");
+ return Encoding.UTF8.GetString(out1.ToArray());
+ }
+ }
+ else
+ {
+ return this._xml;
+ }
+
+ }
public void Write(StreamWriter sw, string nodeName)
{
sw.Write(string.Format("
+ /// {@code new ReplacingInputStream(new ReplacingInputStream(is, "\n\r", "\n"), "\r", "\n")}
+ ///
","").Replace("", "")
+ data.Replace("
", "
").Replace("", "
")
);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
diff --git a/ooxml/XSSF/Util/EvilUnclosedBRFixingInputStream.cs b/ooxml/XSSF/Util/EvilUnclosedBRFixingInputStream.cs
index 0e0e514d8..80dbb41ab 100644
--- a/ooxml/XSSF/Util/EvilUnclosedBRFixingInputStream.cs
+++ b/ooxml/XSSF/Util/EvilUnclosedBRFixingInputStream.cs
@@ -17,6 +17,7 @@ limitations under the License.
using System.IO;
using System;
using System.Collections.Generic;
+using NPOI.Util;
namespace NPOI.XSSF.Util
{
@@ -36,272 +37,281 @@ namespace NPOI.XSSF.Util
* It should only be used where experience Shows the problem
* can occur...
*/
- public class EvilUnclosedBRFixingInputStream : Stream
+ [Obsolete("use ReplacingInputStream(source, \">br<\", \">br/<\")")]
+ public class EvilUnclosedBRFixingInputStream : ReplacingInputStream
{
- private Stream source;
- private byte[] spare;
-
- private static byte[] detect = new byte[] {
- (byte)'<', (byte)'b', (byte)'r', (byte)'>'
- };
-
- public EvilUnclosedBRFixingInputStream(Stream source)
- {
- this.source = source;
- }
-
- /**
- * Warning - doesn't fix!
- */
-
- public int Read()
- {
- return source.ReadByte();
- }
-
-
- public override int Read(byte[] b, int off, int len)
- {
- // Grab any data left from last time
- int readA = ReadFromSpare(b, off, len);
-
- // Now read from the stream
- int readB = source.Read(b, off + readA, len - readA);
-
- // Figure out how much we've done
- int read;
- if (readB == -1 || readB == 0)
- {
- if (readA == 0)
- {
- return readB;
- }
- read = readA;
- }
- else
- {
- read = readA + readB;
- }
-
- // Fix up our data
- if (read > 0)
- {
- read = fixUp(b, off, read);
- }
-
- // All done
- return read;
- }
-
-
- public int Read(byte[] b)
- {
- return this.Read(b, 0, b.Length);
- }
-
- /**
- * Reads into the buffer from the spare bytes
- */
- private int ReadFromSpare(byte[] b, int offset, int len)
- {
- if (spare == null) return 0;
- if (len == 0) throw new ArgumentException("Asked to read 0 bytes");
-
- if (spare.Length <= len)
- {
- // All fits, good
- Array.Copy(spare, 0, b, offset, spare.Length);
- int read = spare.Length;
- spare = null;
- return read;
- }
- else
- {
- // We have more spare than they can copy with...
- byte[] newspare = new byte[spare.Length - len];
- Array.Copy(spare, 0, b, offset, len);
- Array.Copy(spare, len, newspare, 0, newspare.Length);
- spare = newspare;
- return len;
- }
- }
- private void AddToSpare(byte[] b, int offset, int len, bool atTheEnd)
- {
- if (spare == null)
- {
- spare = new byte[len];
- Array.Copy(b, offset, spare, 0, len);
- }
- else
- {
- byte[] newspare = new byte[spare.Length + len];
- if (atTheEnd)
- {
- Array.Copy(spare, 0, newspare, 0, spare.Length);
- Array.Copy(b, offset, newspare, spare.Length, len);
- }
- else
- {
- Array.Copy(b, offset, newspare, 0, len);
- Array.Copy(spare, 0, newspare, len, spare.Length);
- }
- spare = newspare;
- }
- }
-
- private int fixUp(byte[] b, int offset, int read)
- {
- // Do we have any potential overhanging ones?
- for (int i = 0; i < detect.Length - 1; i++)
- {
- int base1 = offset + read - 1 - i;
- if (base1 < 0) continue;
-
- bool going = true;
- for (int j = 0; j <= i && going; j++)
- {
- if (b[base1 + j] == detect[j])
- {
- // Matches
- }
- else
- {
- going = false;
- }
- }
- if (going)
- {
- // There could be a
handing over the end, eg
fixAt = new List
!
- int fixes = 0;
- foreach (int at in fixAt)
- {
- if (at > offset + read - detect.Length - overshoot - fixes)
- {
- overshoot = needed - at - 1 - fixes;
- break;
- }
- fixes++;
- }
-
- AddToSpare(b, offset + read - overshoot, overshoot, false);
- read -= overshoot;
- }
-
- // Fix them, in reverse order so the
- // positions are valid
- for (int j = fixAt.Count - 1; j >= 0; j--)
- {
- int i = fixAt[j];
- if (i >= read + offset)
- {
- // This one has Moved into the overshoot
- continue;
- }
- if (i > read - 3)
- {
- // This one has Moved into the overshoot
- continue;
- }
-
- byte[] tmp = new byte[read - i - 3];
- Array.Copy(b, i + 3, tmp, 0, tmp.Length);
- b[i + 3] = (byte)'/';
- Array.Copy(tmp, 0, b, i + 4, tmp.Length);
- // It got one longer
- read++;
- }
- return read;
- }
-
- public override bool CanRead
+ public EvilUnclosedBRFixingInputStream(InputStream source)
+ : base(source, "
", "
")
{
- get { return true; }
- }
- public override bool CanSeek
- {
- get { return true; }
- }
-
- public override bool CanWrite
- {
- get { return false; }
- }
-
- public override void Flush()
- {
-
- }
-
- public override long Length
- {
- get { return source.Length; }
- }
-
- public override long Position
- {
- get
- {
- return source.Position;
- }
- set
- {
- source.Position = value;
- }
- }
-
- public override long Seek(long offset, SeekOrigin origin)
- {
- return source.Seek(offset, origin);
- }
-
- public override void SetLength(long value)
- {
- throw new InvalidOperationException();
- }
-
- public override void Write(byte[] buffer, int offset, int count)
- {
- throw new InvalidOperationException();
}
}
+ //public class EvilUnclosedBRFixingInputStream : Stream
+ //{
+ // private Stream source;
+ // private byte[] spare;
+
+ // private static byte[] detect = new byte[] {
+ // (byte)'<', (byte)'b', (byte)'r', (byte)'>'
+ // };
+
+ // public EvilUnclosedBRFixingInputStream(Stream source)
+ // {
+ // this.source = source;
+ // }
+
+ // /**
+ // * Warning - doesn't fix!
+ // */
+
+ // public int Read()
+ // {
+ // return source.ReadByte();
+ // }
+
+
+ // public override int Read(byte[] b, int off, int len)
+ // {
+ // // Grab any data left from last time
+ // int readA = ReadFromSpare(b, off, len);
+
+ // // Now read from the stream
+ // int readB = source.Read(b, off + readA, len - readA);
+
+ // // Figure out how much we've done
+ // int read;
+ // if (readB == -1 || readB == 0)
+ // {
+ // if (readA == 0)
+ // {
+ // return readB;
+ // }
+ // read = readA;
+ // }
+ // else
+ // {
+ // read = readA + readB;
+ // }
+
+ // // Fix up our data
+ // if (read > 0)
+ // {
+ // read = fixUp(b, off, read);
+ // }
+
+ // // All done
+ // return read;
+ // }
+
+
+ // public int Read(byte[] b)
+ // {
+ // return this.Read(b, 0, b.Length);
+ // }
+
+ // /**
+ // * Reads into the buffer from the spare bytes
+ // */
+ // private int ReadFromSpare(byte[] b, int offset, int len)
+ // {
+ // if (spare == null) return 0;
+ // if (len == 0) throw new ArgumentException("Asked to read 0 bytes");
+
+ // if (spare.Length <= len)
+ // {
+ // // All fits, good
+ // Array.Copy(spare, 0, b, offset, spare.Length);
+ // int read = spare.Length;
+ // spare = null;
+ // return read;
+ // }
+ // else
+ // {
+ // // We have more spare than they can copy with...
+ // byte[] newspare = new byte[spare.Length - len];
+ // Array.Copy(spare, 0, b, offset, len);
+ // Array.Copy(spare, len, newspare, 0, newspare.Length);
+ // spare = newspare;
+ // return len;
+ // }
+ // }
+ // private void AddToSpare(byte[] b, int offset, int len, bool atTheEnd)
+ // {
+ // if (spare == null)
+ // {
+ // spare = new byte[len];
+ // Array.Copy(b, offset, spare, 0, len);
+ // }
+ // else
+ // {
+ // byte[] newspare = new byte[spare.Length + len];
+ // if (atTheEnd)
+ // {
+ // Array.Copy(spare, 0, newspare, 0, spare.Length);
+ // Array.Copy(b, offset, newspare, spare.Length, len);
+ // }
+ // else
+ // {
+ // Array.Copy(b, offset, newspare, 0, len);
+ // Array.Copy(spare, 0, newspare, len, spare.Length);
+ // }
+ // spare = newspare;
+ // }
+ // }
+
+ // private int fixUp(byte[] b, int offset, int read)
+ // {
+ // // Do we have any potential overhanging ones?
+ // for (int i = 0; i < detect.Length - 1; i++)
+ // {
+ // int base1 = offset + read - 1 - i;
+ // if (base1 < 0) continue;
+
+ // bool going = true;
+ // for (int j = 0; j <= i && going; j++)
+ // {
+ // if (b[base1 + j] == detect[j])
+ // {
+ // // Matches
+ // }
+ // else
+ // {
+ // going = false;
+ // }
+ // }
+ // if (going)
+ // {
+ // // There could be a
handing over the end, eg
fixAt = new List
!
+ // int fixes = 0;
+ // foreach (int at in fixAt)
+ // {
+ // if (at > offset + read - detect.Length - overshoot - fixes)
+ // {
+ // overshoot = needed - at - 1 - fixes;
+ // break;
+ // }
+ // fixes++;
+ // }
+
+ // AddToSpare(b, offset + read - overshoot, overshoot, false);
+ // read -= overshoot;
+ // }
+
+ // // Fix them, in reverse order so the
+ // // positions are valid
+ // for (int j = fixAt.Count - 1; j >= 0; j--)
+ // {
+ // int i = fixAt[j];
+ // if (i >= read + offset)
+ // {
+ // // This one has Moved into the overshoot
+ // continue;
+ // }
+ // if (i > read - 3)
+ // {
+ // // This one has Moved into the overshoot
+ // continue;
+ // }
+
+ // byte[] tmp = new byte[read - i - 3];
+ // Array.Copy(b, i + 3, tmp, 0, tmp.Length);
+ // b[i + 3] = (byte)'/';
+ // Array.Copy(tmp, 0, b, i + 4, tmp.Length);
+ // // It got one longer
+ // read++;
+ // }
+ // return read;
+ // }
+
+ // public override bool CanRead
+ // {
+ // get { return true; }
+ // }
+
+ // public override bool CanSeek
+ // {
+ // get { return true; }
+ // }
+
+ // public override bool CanWrite
+ // {
+ // get { return false; }
+ // }
+
+ // public override void Flush()
+ // {
+
+ // }
+
+ // public override long Length
+ // {
+ // get { return source.Length; }
+ // }
+
+ // public override long Position
+ // {
+ // get
+ // {
+ // return source.Position;
+ // }
+ // set
+ // {
+ // source.Position = value;
+ // }
+ // }
+
+ // public override long Seek(long offset, SeekOrigin origin)
+ // {
+ // return source.Seek(offset, origin);
+ // }
+
+ // public override void SetLength(long value)
+ // {
+ // throw new InvalidOperationException();
+ // }
+
+ // public override void Write(byte[] buffer, int offset, int count)
+ // {
+ // throw new InvalidOperationException();
+ // }
+ //}
}
diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFVMLDrawing.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFVMLDrawing.cs
index 98d825f06..96c16fa7d 100644
--- a/testcases/ooxml/XSSF/UserModel/TestXSSFVMLDrawing.cs
+++ b/testcases/ooxml/XSSF/UserModel/TestXSSFVMLDrawing.cs
@@ -22,6 +22,7 @@ limitations under the License.
using System;
using System.Collections;
using System.IO;
+using System.Text.RegularExpressions;
namespace TestCases.XSSF.UserModel
{
@@ -47,7 +48,7 @@ public void TestNew()
Assert.IsTrue(items[1] is CT_Shapetype);
CT_Shapetype type = (CT_Shapetype)items[1];
Assert.AreEqual("21600,21600", type.coordsize);
- Assert.AreEqual(202.0f, type.spt);
+ Assert.AreEqual(202.0f, type.spt, 0);
Assert.AreEqual("m,l,21600r21600,l21600,xe", type.path2);
Assert.AreEqual("_x0000_t202", type.id);
Assert.AreEqual(NPOI.OpenXmlFormats.Vml.ST_TrueFalse.t, type.path.gradientshapeok);
@@ -79,7 +80,7 @@ public void TestNew()
//each of the properties of CT_ClientData should occurs 0 or 1 times, and CT_ClientData has multiple properties.
//Assert.AreEqual("[]", cldata.GetVisibleList().ToString());
Assert.AreEqual(ST_TrueFalseBlank.NONE, cldata.visible);
- cldata.visible = (ST_TrueFalseBlank)Enum.Parse(typeof(ST_TrueFalseBlank), "true");
+ cldata.visible = (ST_TrueFalseBlank) Enum.Parse(typeof(ST_TrueFalseBlank), "true");
Assert.AreEqual(ST_TrueFalseBlank.@true, cldata.visible);
//serialize and read again
MemoryStream out1 = new MemoryStream();
@@ -173,27 +174,27 @@ public void TestCommentShowsBox()
XSSFVMLDrawing vml = sheet.GetVMLDrawing(false);
CT_Shapetype shapetype = null;
ArrayList items = vml.GetItems();
- foreach (object o in items)
- if (o is CT_Shapetype)
- shapetype = (CT_Shapetype)o;
+ foreach(object o in items)
+ if(o is CT_Shapetype)
+ shapetype = (CT_Shapetype) o;
Assert.AreEqual(NPOI.OpenXmlFormats.Vml.ST_TrueFalse.t, shapetype.stroked);
Assert.AreEqual(NPOI.OpenXmlFormats.Vml.ST_TrueFalse.t, shapetype.filled);
- using (MemoryStream ws = new MemoryStream())
+ using(MemoryStream ws = new MemoryStream())
{
wb.Write(ws);
- using (MemoryStream rs = new MemoryStream(ws.GetBuffer()))
+ using(MemoryStream rs = new MemoryStream(ws.GetBuffer()))
{
wb = new XSSFWorkbook(rs);
- sheet = (XSSFSheet)wb.GetSheetAt(0);
+ sheet = (XSSFSheet) wb.GetSheetAt(0);
vml = sheet.GetVMLDrawing(false);
shapetype = null;
items = vml.GetItems();
- foreach (object o in items)
- if (o is CT_Shapetype)
- shapetype = (CT_Shapetype)o;
+ foreach(object o in items)
+ if(o is CT_Shapetype)
+ shapetype = (CT_Shapetype) o;
//wb.Write(new FileStream("comments.xlsx", FileMode.Create));
//using (MemoryStream ws2 = new MemoryStream())
@@ -207,5 +208,26 @@ public void TestCommentShowsBox()
}
}
}
+
+ [Test]
+ public void TestEvilUnclosedBRFixing() {
+ XSSFVMLDrawing vml = new XSSFVMLDrawing();
+ Stream stream = POIDataSamples.GetOpenXML4JInstance().OpenResourceAsStream("bug-60626.vml");
+ try {
+ vml.Read(stream);
+ } finally {
+ stream.Close();
+ }
+ Regex p = new Regex("
", RegexOptions.Compiled);
+ int count = 0;
+ foreach(Object xo in vml.GetItems())
+ {
+ var t = xo.ToString();
+ String[] split = p.Split(t);
+ count += split.Length-1;
+ }
+
+ Assert.AreEqual(16, count);
+ }
}
}
diff --git a/testcases/ooxml/XSSF/Util/TestEvilUnclosedBRFixingInputStream.cs b/testcases/ooxml/XSSF/Util/TestEvilUnclosedBRFixingInputStream.cs
index a48e28c8d..e533c0352 100644
--- a/testcases/ooxml/XSSF/Util/TestEvilUnclosedBRFixingInputStream.cs
+++ b/testcases/ooxml/XSSF/Util/TestEvilUnclosedBRFixingInputStream.cs
@@ -20,10 +20,12 @@ limitations under the License.
using System.Text;
using NPOI.Util;
using NPOI.XSSF.Util;
+using System;
namespace TestCases.XSSF.Util
{
[TestFixture]
+ [Obsolete]
public class TestEvilUnclosedBRFixingInputStream
{
[Test]
@@ -32,27 +34,11 @@ public void TestOK()
byte[] ok = Encoding.UTF8.GetBytes("