From: Simon Montagu <smontagu@smontagu.org>
Date: Tue, 8 Mar 2011 09:10:15 +0200
Subject: Set correct output params in the UTF-16 decoder. Bug 634257, Bug
 638236, p=smontagu,dbaron, r=emk,smontagu, a1.9.1.18=clegnitto

---
 intl/uconv/ucvlatin/nsUCS2BEToUnicode.cpp |   35 +++++++++++++++++++----------
 1 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/intl/uconv/ucvlatin/nsUCS2BEToUnicode.cpp b/intl/uconv/ucvlatin/nsUCS2BEToUnicode.cpp
index 7093e1d..5d73277 100644
--- a/intl/uconv/ucvlatin/nsUCS2BEToUnicode.cpp
+++ b/intl/uconv/ucvlatin/nsUCS2BEToUnicode.cpp
@@ -63,16 +63,13 @@ UTF16ConvertToUnicode(PRUint8& aState, PRUint8& aOddByte,
 
   switch(aState) {
     case STATE_FOUND_BOM:
-      if (*aSrcLength < 2)
-        return NS_ERROR_ILLEGAL_INPUT;
+      NS_ASSERTION(*aSrcLength > 1, "buffer too short");
       src+=2;
       aState = STATE_NORMAL;
       break;
 
     case STATE_FIRST_CALL: // first time called
-      if (*aSrcLength < 2)
-        return NS_ERROR_ILLEGAL_INPUT;
-
+      NS_ASSERTION(*aSrcLength > 1, "buffer too short");
       // Eliminate BOM (0xFEFF). Note that different endian case is taken care
       // of in |Convert| of LE and BE converters. Here, we only have to
       // deal with the same endian case. That is, 0xFFFE (byte-swapped BOM) is
@@ -218,14 +215,19 @@ NS_IMETHODIMP
 nsUTF16BEToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
                             PRUnichar * aDest, PRInt32 * aDestLength)
 {
+    if(STATE_FIRST_CALL == mState && *aSrcLength < 2)
+    {
+      nsresult res = (*aSrcLength == 0) ? NS_OK : NS_ERROR_ILLEGAL_INPUT;
+      *aSrcLength=0;
+      *aDestLength=0;
+      return res;
+    }
 #ifdef IS_LITTLE_ENDIAN
     // Remove the BOM if we're little-endian. The 'same endian' case with the
     // leading BOM will be taken care of by |UTF16ConvertToUnicode|.
     if(STATE_FIRST_CALL == mState) // Called for the first time.
     {
       mState = STATE_NORMAL;
-      if (*aSrcLength < 2)
-        return NS_ERROR_ILLEGAL_INPUT;
       if(0xFFFE == *((PRUnichar*)aSrc)) {
         // eliminate BOM (on LE machines, BE BOM is 0xFFFE)
         mState = STATE_FOUND_BOM;
@@ -253,14 +255,19 @@ NS_IMETHODIMP
 nsUTF16LEToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
                             PRUnichar * aDest, PRInt32 * aDestLength)
 {
+    if(STATE_FIRST_CALL == mState && *aSrcLength < 2)
+    {
+      nsresult res = (*aSrcLength == 0) ? NS_OK : NS_ERROR_ILLEGAL_INPUT;
+      *aSrcLength=0;
+      *aDestLength=0;
+      return res;
+    }
 #ifdef IS_BIG_ENDIAN
     // Remove the BOM if we're big-endian. The 'same endian' case with the
     // leading BOM will be taken care of by |UTF16ConvertToUnicode|.
     if(STATE_FIRST_CALL == mState) // first time called
     {
       mState = STATE_NORMAL;
-      if (*aSrcLength < 2)
-        return NS_ERROR_ILLEGAL_INPUT;
       if(0xFFFE == *((PRUnichar*)aSrc)) {
         // eliminate BOM (on BE machines, LE BOM is 0xFFFE)
         mState = STATE_FOUND_BOM;
@@ -296,12 +303,16 @@ NS_IMETHODIMP
 nsUTF16ToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLength,
                           PRUnichar * aDest, PRInt32 * aDestLength)
 {
+    if(STATE_FIRST_CALL == mState && *aSrcLength < 2)
+    {
+      nsresult res = (*aSrcLength == 0) ? NS_OK : NS_ERROR_ILLEGAL_INPUT;
+      *aSrcLength=0;
+      *aDestLength=0;
+      return res;
+    }
     if(STATE_FIRST_CALL == mState) // first time called
     {
       mState = STATE_NORMAL;
-      if (*aSrcLength < 2)
-        return NS_ERROR_ILLEGAL_INPUT;
-
       // check if BOM (0xFEFF) is at the beginning, remove it if found, and
       // set mEndian accordingly.
       if(0xFF == PRUint8(aSrc[0]) && 0xFE == PRUint8(aSrc[1])) {
