Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[corlib] Fix ASCIIEncoding with custom DecoderFallback.

Only pass one single byte to DecoderFallback.Fallback(),
throw if there's not enough space in the char array.
  • Loading branch information...
commit cd8ca2f65858d1018ece7e1a82d14f8d05bbad2e 1 parent 5cc07f4
Martin Baulig authored
14 mcs/class/corlib/System.Text/ASCIIEncoding.cs
View
@@ -216,9 +216,17 @@ public override int GetChars (byte[] bytes, int byteIndex, int byteCount, char[]
else {
if (buffer == null)
buffer = DecoderFallback.CreateFallbackBuffer ();
- buffer.Fallback (bytes, byteIndex);
- while (buffer.Remaining > 0)
- chars [charIndex++] = buffer.GetNextChar ();
+ var thisByte = new byte[] { bytes [byteIndex-1] };
+ buffer.Fallback (thisByte, 0);
+ while (buffer.Remaining > 0) {
+ if (charIndex < chars.Length) {
+ chars [charIndex++] = buffer.GetNextChar ();
+ continue;
+ }
+ throw new ArgumentException (
+ "The output char buffer is too small to contain the " +
+ "decoded characters.");
+ }
}
}
return byteCount;
97 mcs/class/corlib/Test/System.Text/ASCIIEncodingTest.cs
View
@@ -8,6 +8,8 @@
using System.Text;
using NUnit.Framework;
+using NUnit.Framework.Constraints;
+using NUnit.Framework.SyntaxHelpers;
namespace MonoTests.System.Text
{
@@ -210,7 +212,6 @@ public void TestZero ()
Assert.AreEqual (string.Empty, encoding.GetString (new byte [0], 0, 0), "#2");
}
-#if NET_2_0
[Test]
[ExpectedException (typeof (DecoderFallbackException))]
public void DecoderFallback ()
@@ -219,6 +220,98 @@ public void DecoderFallback ()
e.DecoderFallback = new DecoderExceptionFallback ();
e.GetChars (new byte [] {0x80});
}
-#endif
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void DecoderFallback2 ()
+ {
+ var bytes = new byte[] {
+ 0x30, 0xa0, 0x31, 0xa8
+ };
+ var enc = (ASCIIEncoding)Encoding.ASCII.Clone ();
+ enc.DecoderFallback = new TestFallbackDecoder ();
+
+ var chars = new char [7];
+ var ret = enc.GetChars (bytes, 0, bytes.Length, chars, 0);
+ Console.WriteLine (ret);
+
+ for (int i = 0; i < chars.Length; i++) {
+ Console.Write ("{0:x2} ", (int)chars [i]);
+ }
+ Console.WriteLine ();
+ }
+
+ [Test]
+ public void DecoderFallback3 ()
+ {
+ var bytes = new byte[] {
+ 0x30, 0xa0, 0x31, 0xa8
+ };
+ var enc = (ASCIIEncoding)Encoding.ASCII.Clone ();
+ enc.DecoderFallback = new TestFallbackDecoder ();
+
+ var chars = new char [10];
+ var ret = enc.GetChars (bytes, 0, bytes.Length, chars, 0);
+
+ Assert.That (ret, Is.EqualTo (6), "ret");
+ Assert.That (chars [0], Is.EqualTo ((char)0x30), "chars[0]");
+ Assert.That (chars [1], Is.EqualTo ((char)0xa0), "chars[1]");
+ Assert.That (chars [2], Is.EqualTo ((char)0xa1), "chars[2]");
+ Assert.That (chars [3], Is.EqualTo ((char)0x31), "chars[3]");
+ Assert.That (chars [4], Is.EqualTo ((char)0xa8), "chars[4]");
+ Assert.That (chars [5], Is.EqualTo ((char)0xa9), "chars[5]");
+ }
+
+ class TestFallbackDecoder : DecoderFallback {
+ const int count = 2;
+
+ public override int MaxCharCount {
+ get { return count; }
+ }
+
+ public override DecoderFallbackBuffer CreateFallbackBuffer ()
+ {
+ return new Buffer ();
+ }
+
+ class Buffer : DecoderFallbackBuffer {
+ char[] queue;
+ int index;
+
+ public override int Remaining {
+ get {
+ return queue.Length - index;
+ }
+ }
+
+ public override char GetNextChar ()
+ {
+ return index < queue.Length ? queue [index++] : '\0';
+ }
+
+ public override bool Fallback (byte[] bytes, int unused)
+ {
+ queue = new char[bytes.Length * count];
+ index = 0;
+ for (int i = 0; i < bytes.Length; i++) {
+ for (int j = 0; j < count; j++)
+ queue [index++] = (char)(bytes [i]+j);
+ }
+ return true;
+ }
+
+ public override bool MovePrevious ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ public override void Reset ()
+ {
+ base.Reset ();
+ }
+ }
+ }
+
+
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.