Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[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
@@ -216,9 +216,17 @@ public override int GetChars (byte[] bytes, int byteIndex, int byteCount, char[]
216 216 else {
217 217 if (buffer == null)
218 218 buffer = DecoderFallback.CreateFallbackBuffer ();
219   - buffer.Fallback (bytes, byteIndex);
220   - while (buffer.Remaining > 0)
221   - chars [charIndex++] = buffer.GetNextChar ();
  219 + var thisByte = new byte[] { bytes [byteIndex-1] };
  220 + buffer.Fallback (thisByte, 0);
  221 + while (buffer.Remaining > 0) {
  222 + if (charIndex < chars.Length) {
  223 + chars [charIndex++] = buffer.GetNextChar ();
  224 + continue;
  225 + }
  226 + throw new ArgumentException (
  227 + "The output char buffer is too small to contain the " +
  228 + "decoded characters.");
  229 + }
222 230 }
223 231 }
224 232 return byteCount;
97 mcs/class/corlib/Test/System.Text/ASCIIEncodingTest.cs
@@ -8,6 +8,8 @@
8 8 using System.Text;
9 9
10 10 using NUnit.Framework;
  11 +using NUnit.Framework.Constraints;
  12 +using NUnit.Framework.SyntaxHelpers;
11 13
12 14 namespace MonoTests.System.Text
13 15 {
@@ -210,7 +212,6 @@ public void TestZero ()
210 212 Assert.AreEqual (string.Empty, encoding.GetString (new byte [0], 0, 0), "#2");
211 213 }
212 214
213   -#if NET_2_0
214 215 [Test]
215 216 [ExpectedException (typeof (DecoderFallbackException))]
216 217 public void DecoderFallback ()
@@ -219,6 +220,98 @@ public void DecoderFallback ()
219 220 e.DecoderFallback = new DecoderExceptionFallback ();
220 221 e.GetChars (new byte [] {0x80});
221 222 }
222   -#endif
  223 +
  224 + [Test]
  225 + [ExpectedException (typeof (ArgumentException))]
  226 + public void DecoderFallback2 ()
  227 + {
  228 + var bytes = new byte[] {
  229 + 0x30, 0xa0, 0x31, 0xa8
  230 + };
  231 + var enc = (ASCIIEncoding)Encoding.ASCII.Clone ();
  232 + enc.DecoderFallback = new TestFallbackDecoder ();
  233 +
  234 + var chars = new char [7];
  235 + var ret = enc.GetChars (bytes, 0, bytes.Length, chars, 0);
  236 + Console.WriteLine (ret);
  237 +
  238 + for (int i = 0; i < chars.Length; i++) {
  239 + Console.Write ("{0:x2} ", (int)chars [i]);
  240 + }
  241 + Console.WriteLine ();
  242 + }
  243 +
  244 + [Test]
  245 + public void DecoderFallback3 ()
  246 + {
  247 + var bytes = new byte[] {
  248 + 0x30, 0xa0, 0x31, 0xa8
  249 + };
  250 + var enc = (ASCIIEncoding)Encoding.ASCII.Clone ();
  251 + enc.DecoderFallback = new TestFallbackDecoder ();
  252 +
  253 + var chars = new char [10];
  254 + var ret = enc.GetChars (bytes, 0, bytes.Length, chars, 0);
  255 +
  256 + Assert.That (ret, Is.EqualTo (6), "ret");
  257 + Assert.That (chars [0], Is.EqualTo ((char)0x30), "chars[0]");
  258 + Assert.That (chars [1], Is.EqualTo ((char)0xa0), "chars[1]");
  259 + Assert.That (chars [2], Is.EqualTo ((char)0xa1), "chars[2]");
  260 + Assert.That (chars [3], Is.EqualTo ((char)0x31), "chars[3]");
  261 + Assert.That (chars [4], Is.EqualTo ((char)0xa8), "chars[4]");
  262 + Assert.That (chars [5], Is.EqualTo ((char)0xa9), "chars[5]");
  263 + }
  264 +
  265 + class TestFallbackDecoder : DecoderFallback {
  266 + const int count = 2;
  267 +
  268 + public override int MaxCharCount {
  269 + get { return count; }
  270 + }
  271 +
  272 + public override DecoderFallbackBuffer CreateFallbackBuffer ()
  273 + {
  274 + return new Buffer ();
  275 + }
  276 +
  277 + class Buffer : DecoderFallbackBuffer {
  278 + char[] queue;
  279 + int index;
  280 +
  281 + public override int Remaining {
  282 + get {
  283 + return queue.Length - index;
  284 + }
  285 + }
  286 +
  287 + public override char GetNextChar ()
  288 + {
  289 + return index < queue.Length ? queue [index++] : '\0';
  290 + }
  291 +
  292 + public override bool Fallback (byte[] bytes, int unused)
  293 + {
  294 + queue = new char[bytes.Length * count];
  295 + index = 0;
  296 + for (int i = 0; i < bytes.Length; i++) {
  297 + for (int j = 0; j < count; j++)
  298 + queue [index++] = (char)(bytes [i]+j);
  299 + }
  300 + return true;
  301 + }
  302 +
  303 + public override bool MovePrevious ()
  304 + {
  305 + throw new NotImplementedException ();
  306 + }
  307 +
  308 + public override void Reset ()
  309 + {
  310 + base.Reset ();
  311 + }
  312 + }
  313 + }
  314 +
  315 +
223 316 }
224 317 }

0 comments on commit cd8ca2f

Please sign in to comment.
Something went wrong with that request. Please try again.