Bug 638379 - Part 3: Remove workaround for unreliable inputErrorBehavior. r=hsivonen
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Mon, 10 Dec 2012 09:11:15 -0500
changeset 115509 85211b40ba379c1e8c66d0d0c9a1bec30b943dfd
parent 115508 f2d8e0807127f1a4a8437de9d8180d74adb1051b
child 115510 dc2daca28d7fe7442d7bbe1c09f59c6e93214cb8
push id19375
push userryanvm@gmail.com
push dateMon, 10 Dec 2012 14:14:57 +0000
treeherdermozilla-inbound@a4c6ce2b95a1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershsivonen
bugs638379
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 638379 - Part 3: Remove workaround for unreliable inputErrorBehavior. r=hsivonen
content/base/src/nsContentUtils.cpp
content/base/src/nsEventSource.cpp
content/base/src/nsScriptLoader.cpp
content/base/src/nsXMLHttpRequest.cpp
dom/encoding/TextDecoder.cpp
intl/uconv/src/nsConverterInputStream.cpp
netwerk/base/src/nsUnicharStreamLoader.cpp
parser/html/nsHtml5StreamParser.cpp
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -3589,37 +3589,20 @@ nsContentUtils::ConvertStringFromCharset
 
   PRUnichar *ustr = (PRUnichar *)nsMemory::Alloc((outLen + 1) *
                                                  sizeof(PRUnichar));
   if (!ustr)
     return NS_ERROR_OUT_OF_MEMORY;
 
   const char* data = flatInput.get();
   aOutput.Truncate();
-  for (;;) {
-    int32_t srcLen = length;
-    int32_t dstLen = outLen;
-    rv = decoder->Convert(data, &srcLen, ustr, &dstLen);
-    // Convert will convert the input partially even if the status
-    // indicates a failure.
-    ustr[dstLen] = 0;
-    aOutput.Append(ustr, dstLen);
-    if (rv != NS_ERROR_ILLEGAL_INPUT) {
-      break;
-    }
-    // Emit a decode error manually because some decoders
-    // do not support kOnError_Recover (bug 638379)
-    if (srcLen == -1) {
-      decoder->Reset();
-    } else {
-      data += srcLen + 1;
-      length -= srcLen + 1;
-      aOutput.Append(static_cast<PRUnichar>(0xFFFD));
-    }
-  }
+  rv = decoder->Convert(data, &length, ustr, &outLen);
+  MOZ_ASSERT(rv != NS_ERROR_ILLEGAL_INPUT);
+  ustr[outLen] = 0;
+  aOutput.Append(ustr, outLen);
 
   nsMemory::Free(ustr);
   return rv;
 }
 
 /* static */
 bool
 nsContentUtils::CheckForBOM(const unsigned char* aBuffer, uint32_t aLength,
--- a/content/base/src/nsEventSource.cpp
+++ b/content/base/src/nsEventSource.cpp
@@ -296,17 +296,16 @@ nsEventSource::Init(nsIPrincipal* aPrinc
                         DEFAULT_RECONNECTION_TIME_VALUE);
 
   nsCOMPtr<nsICharsetConverterManager> convManager =
     do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = convManager->GetUnicodeDecoder("UTF-8", getter_AddRefs(mUnicodeDecoder));
   NS_ENSURE_SUCCESS(rv, rv);
-  mUnicodeDecoder->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Recover);
 
   // the constructor should throw a SYNTAX_ERROR only if it fails resolving the
   // url parameter, so we don't care about the InitChannelAndRequestEventSource
   // result.
   InitChannelAndRequestEventSource();
 
   return NS_OK;
 }
@@ -498,42 +497,27 @@ nsEventSource::StreamReaderFunc(nsIInput
              *end = aFromRawSegment + aCount;
 
   do {
     srcCount = aCount - (p - aFromRawSegment);
     outCount = 2;
 
     thisObject->mLastConvertionResult =
       thisObject->mUnicodeDecoder->Convert(p, &srcCount, out, &outCount);
+    MOZ_ASSERT(thisObject->mLastConvertionResult != NS_ERROR_ILLEGAL_INPUT);
 
-    if (thisObject->mLastConvertionResult == NS_ERROR_ILLEGAL_INPUT) {
-      // There's an illegal byte in the input. It's now the responsibility
-      // of this calling code to output a U+FFFD REPLACEMENT CHARACTER, advance
-      // over the bad byte and reset the decoder.
-      rv = thisObject->ParseCharacter(REPLACEMENT_CHAR);
+    for (int32_t i = 0; i < outCount; ++i) {
+      rv = thisObject->ParseCharacter(out[i]);
       NS_ENSURE_SUCCESS(rv, rv);
-      p = p + srcCount + 1;
-      thisObject->mUnicodeDecoder->Reset();
-    } else {
-      for (int32_t i = 0; i < outCount; ++i) {
-        rv = thisObject->ParseCharacter(out[i]);
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-      p = p + srcCount;
     }
+    p = p + srcCount;
   } while (p < end &&
            thisObject->mLastConvertionResult != NS_PARTIAL_MORE_INPUT &&
            thisObject->mLastConvertionResult != NS_OK);
 
-  // check if the last byte was a bad one and
-  // clear the state since it was handled above.
-  if (thisObject->mLastConvertionResult == NS_ERROR_ILLEGAL_INPUT) {
-    thisObject->mLastConvertionResult = NS_OK;
-  }
-
   *aWriteCount = aCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsEventSource::OnDataAvailable(nsIRequest *aRequest,
                                nsISupports *aContext,
                                nsIInputStream *aInputStream,
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -1068,41 +1068,21 @@ nsScriptLoader::ConvertToUTF16(nsIChanne
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!EnsureStringLength(aString, unicodeLength)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   PRUnichar *ustr = aString.BeginWriting();
 
-  int32_t consumedLength = 0;
-  int32_t originalLength = aLength;
-  int32_t convertedLength = 0;
-  int32_t bufferLength = unicodeLength;
-  do {
-    rv = unicodeDecoder->Convert(reinterpret_cast<const char*>(aData),
-                                 (int32_t *) &aLength, ustr,
-                                 &unicodeLength);
-    if (NS_FAILED(rv)) {
-      // if we failed, we consume one byte, replace it with U+FFFD
-      // and try the conversion again.
-      ustr[unicodeLength++] = (PRUnichar)0xFFFD;
-      ustr += unicodeLength;
-
-      unicodeDecoder->Reset();
-    }
-    aData += ++aLength;
-    consumedLength += aLength;
-    aLength = originalLength - consumedLength;
-    convertedLength += unicodeLength;
-    unicodeLength = bufferLength - convertedLength;
-  } while (NS_FAILED(rv) &&
-           (originalLength > consumedLength) &&
-           (bufferLength > convertedLength));
-  aString.SetLength(convertedLength);
+  rv = unicodeDecoder->Convert(reinterpret_cast<const char*>(aData),
+                               (int32_t *) &aLength, ustr,
+                               &unicodeLength);
+  MOZ_ASSERT(NS_SUCCEEDED(rv));
+  aString.SetLength(unicodeLength);
   return rv;
 }
 
 NS_IMETHODIMP
 nsScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader,
                                  nsISupports* aContext,
                                  nsresult aStatus,
                                  uint32_t aStringLen,
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -783,46 +783,25 @@ nsXMLHttpRequest::AppendToResponseText(c
   }
 
   PRUnichar* destBuffer = mResponseText.BeginWriting() + mResponseText.Length();
 
   int32_t totalChars = mResponseText.Length();
 
   // This code here is basically a copy of a similar thing in
   // nsScanner::Append(const char* aBuffer, uint32_t aLen).
-  // If we get illegal characters in the input we replace
-  // them and don't just fail.
-  do {
-    int32_t srclen = (int32_t)aSrcBufferLen;
-    int32_t destlen = (int32_t)destBufferLen;
-    rv = mDecoder->Convert(aSrcBuffer,
-                           &srclen,
-                           destBuffer,
-                           &destlen);
-    if (NS_FAILED(rv)) {
-      // We consume one byte, replace it with U+FFFD
-      // and try the conversion again.
-
-      destBuffer[destlen] = (PRUnichar)0xFFFD; // add replacement character
-      destlen++; // skip written replacement character
-      destBuffer += destlen;
-      destBufferLen -= destlen;
-
-      if (srclen < (int32_t)aSrcBufferLen) {
-        srclen++; // Consume the invalid character
-      }
-      aSrcBuffer += srclen;
-      aSrcBufferLen -= srclen;
-
-      mDecoder->Reset();
-    }
-
-    totalChars += destlen;
-
-  } while (NS_FAILED(rv) && aSrcBufferLen > 0);
+  int32_t srclen = (int32_t)aSrcBufferLen;
+  int32_t destlen = (int32_t)destBufferLen;
+  rv = mDecoder->Convert(aSrcBuffer,
+                         &srclen,
+                         destBuffer,
+                         &destlen);
+  MOZ_ASSERT(NS_SUCCEEDED(rv));
+
+  totalChars += destlen;
 
   mResponseText.SetLength(totalChars);
 
   return NS_OK;
 }
 
 /* readonly attribute AString responseText; */
 NS_IMETHODIMP
--- a/dom/encoding/TextDecoder.cpp
+++ b/dom/encoding/TextDecoder.cpp
@@ -54,17 +54,17 @@ TextDecoder::Init(const nsAString& aEnco
 
 void
 TextDecoder::Decode(const ArrayBufferView* aView,
                     const TextDecodeOptions& aOptions,
                     nsAString& aOutDecodedString,
                     ErrorResult& aRv)
 {
   const char* data;
-  uint32_t length;
+  int32_t length;
   // If view is not specified, let view be a Uint8Array of length 0.
   if (!aView) {
     data = EmptyCString().BeginReading();
     length = EmptyCString().Length();
   } else {
     data = reinterpret_cast<const char*>(aView->Data());
     length = aView->Length();
   }
@@ -82,37 +82,20 @@ TextDecoder::Decode(const ArrayBufferVie
   // and the content can specify the length of the string.
   static const fallible_t fallible = fallible_t();
   nsAutoArrayPtr<PRUnichar> buf(new (fallible) PRUnichar[outLen + 1]);
   if (!buf) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
-  for (;;) {
-    int32_t srcLen = length;
-    int32_t dstLen = outLen;
-    rv = mDecoder->Convert(data, &srcLen, buf, &dstLen);
-    // Convert will convert the input partially even if the status
-    // indicates a failure.
-    buf[dstLen] = 0;
-    aOutDecodedString.Append(buf, dstLen);
-    if (mFatal || rv != NS_ERROR_ILLEGAL_INPUT) {
-      break;
-    }
-    // Emit a decode error manually because some decoders
-    // do not support kOnError_Recover (bug 638379)
-    if (srcLen == -1) {
-      mDecoder->Reset();
-    } else {
-      data += srcLen + 1;
-      length -= srcLen + 1;
-      aOutDecodedString.Append(kReplacementChar);
-    }
-  }
+  rv = mDecoder->Convert(data, &length, buf, &outLen);
+  MOZ_ASSERT(mFatal || rv != NS_ERROR_ILLEGAL_INPUT);
+  buf[outLen] = 0;
+  aOutDecodedString.Append(buf, outLen);
 
   // If the internal streaming flag of the decoder object is not set,
   // then reset the encoding algorithm state to the default values
   if (!aOptions.stream) {
     mDecoder->Reset();
     if (rv == NS_OK_UDEC_MOREINPUT) {
       if (mFatal) {
         aRv.Throw(NS_ERROR_DOM_ENCODING_DECODE_ERR);
--- a/intl/uconv/src/nsConverterInputStream.cpp
+++ b/intl/uconv/src/nsConverterInputStream.cpp
@@ -41,17 +41,21 @@ nsConverterInputStream::Init(nsIInputStr
     rv = NS_NewByteBuffer(getter_AddRefs(mByteData), nullptr, aBufferSize);
     if (NS_FAILED(rv)) return rv;
 
     rv = NS_NewUnicharBuffer(getter_AddRefs(mUnicharData), nullptr, aBufferSize);
     if (NS_FAILED(rv)) return rv;
 
     mInput = aStream;
     mReplacementChar = aReplacementChar;
-    
+    if (!aReplacementChar ||
+        aReplacementChar != mConverter->GetCharacterForUnMapped()) {
+        mConverter->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Signal);
+    }
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsConverterInputStream::Close()
 {
     nsresult rv = mInput ? mInput->Close() : NS_OK;
     mLineBuffer = nullptr;
--- a/netwerk/base/src/nsUnicharStreamLoader.cpp
+++ b/netwerk/base/src/nsUnicharStreamLoader.cpp
@@ -193,49 +193,30 @@ nsUnicharStreamLoader::WriteSegmentFun(n
                                        const char *aSegment,
                                        uint32_t,
                                        uint32_t aCount,
                                        uint32_t *aWriteCount)
 {
   nsUnicharStreamLoader* self = static_cast<nsUnicharStreamLoader*>(aClosure);
 
   uint32_t haveRead = self->mBuffer.Length();
-  uint32_t consumed = 0;
   nsresult rv;
-  do {
-    int32_t srcLen = aCount - consumed;
-    int32_t dstLen;
-    self->mDecoder->GetMaxLength(aSegment + consumed, srcLen, &dstLen);
-
-    uint32_t capacity = haveRead + dstLen;
-    if (!self->mBuffer.SetCapacity(capacity, fallible_t())) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
+  int32_t srcLen = aCount;
+  int32_t dstLen;
+  self->mDecoder->GetMaxLength(aSegment, srcLen, &dstLen);
 
-    rv = self->mDecoder->Convert(aSegment + consumed,
-                                 &srcLen,
-                                 self->mBuffer.BeginWriting() + haveRead,
-                                 &dstLen);
-    haveRead += dstLen;
-    // XXX if srcLen is negative, we want to drop the _first_ byte in
-    // the erroneous byte sequence and try again.  This is not quite
-    // possible right now -- see bug 160784
-    consumed += srcLen;
-    if (NS_FAILED(rv)) {
-      if (haveRead >= capacity) {
-        // Make room for writing the 0xFFFD below (bug 785753).
-        if (!self->mBuffer.SetCapacity(haveRead + 1, fallible_t())) {
-          return NS_ERROR_OUT_OF_MEMORY;
-        }
-      }
-      self->mBuffer.BeginWriting()[haveRead++] = 0xFFFD;
-      ++consumed;
-      // XXX this is needed to make sure we don't underrun our buffer;
-      // bug 160784 again
-      consumed = NS_MAX<uint32_t>(consumed, 0);
-      self->mDecoder->Reset();
-    }
-  } while (consumed < aCount);
+  uint32_t capacity = haveRead + dstLen;
+  if (!self->mBuffer.SetCapacity(capacity, fallible_t())) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  rv = self->mDecoder->Convert(aSegment,
+                               &srcLen,
+                               self->mBuffer.BeginWriting() + haveRead,
+                               &dstLen);
+  MOZ_ASSERT(NS_SUCCEEDED(rv));
+  MOZ_ASSERT(srcLen == static_cast<int32_t>(aCount));
+  haveRead += dstLen;
 
   self->mBuffer.SetLength(haveRead);
   *aWriteCount = aCount;
   return NS_OK;
 }
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -297,17 +297,16 @@ nsHtml5StreamParser::SetupDecodingAndWri
   rv = convManager->GetUnicodeDecoder(mCharset.get(), getter_AddRefs(mUnicodeDecoder));
   if (rv == NS_ERROR_UCONV_NOCONV) {
     mCharset.AssignLiteral("windows-1252"); // lower case is the raw form
     mCharsetSource = kCharsetFromWeakDocTypeDefault;
     rv = convManager->GetUnicodeDecoderRaw(mCharset.get(), getter_AddRefs(mUnicodeDecoder));
     mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
   }
   NS_ENSURE_SUCCESS(rv, rv);
-  mUnicodeDecoder->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Recover);
   return WriteSniffingBufferAndCurrentSegment(aFromSegment, aCount, aWriteCount);
 }
 
 nsresult
 nsHtml5StreamParser::WriteSniffingBufferAndCurrentSegment(const uint8_t* aFromSegment, // can be null
                                                           uint32_t aCount,
                                                           uint32_t* aWriteCount)
 {
@@ -330,17 +329,16 @@ nsresult
 nsHtml5StreamParser::SetupDecodingFromBom(const char* aCharsetName, const char* aDecoderCharsetName)
 {
   NS_ASSERTION(IsParserThread(), "Wrong thread!");
   nsresult rv = NS_OK;
   nsCOMPtr<nsICharsetConverterManager> convManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = convManager->GetUnicodeDecoderRaw(aDecoderCharsetName, getter_AddRefs(mUnicodeDecoder));
   NS_ENSURE_SUCCESS(rv, rv);
-  mUnicodeDecoder->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Recover);
   mCharset.Assign(aCharsetName);
   mCharsetSource = kCharsetFromByteOrderMark;
   mFeedChardet = false;
   mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
   mSniffingBuffer = nullptr;
   mMetaScanner = nullptr;
   mBomState = BOM_SNIFFING_OVER;
   return rv;
@@ -713,18 +711,16 @@ nsHtml5StreamParser::SniffStreamBytes(co
     // still contains the charset from the channel or higher as set by an
     // earlier call to SetDocumentCharset(), since we didn't find a BOM and
     // overwrite mCharset.
     nsCOMPtr<nsICharsetConverterManager> convManager =
       do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID);
     convManager->GetUnicodeDecoder(mCharset.get(),
                                    getter_AddRefs(mUnicodeDecoder));
     if (mUnicodeDecoder) {
-      mUnicodeDecoder->SetInputErrorBehavior(
-          nsIUnicodeDecoder::kOnError_Recover);
       mFeedChardet = false;
       mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
       mMetaScanner = nullptr;
       return WriteSniffingBufferAndCurrentSegment(aFromSegment,
                                                   aCount,
                                                   aWriteCount);
     } else {
       // nsHTMLDocument is supposed to make sure this does not happen. Let's
@@ -744,18 +740,16 @@ nsHtml5StreamParser::SniffStreamBytes(co
     // this is the last buffer
     uint32_t countToSniffingLimit =
         NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE - mSniffingLength;
     if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML || mMode == LOAD_AS_DATA) {
       nsHtml5ByteReadable readable(aFromSegment, aFromSegment +
           countToSniffingLimit);
       mMetaScanner->sniff(&readable, getter_AddRefs(mUnicodeDecoder), mCharset);
       if (mUnicodeDecoder) {
-        mUnicodeDecoder->SetInputErrorBehavior(
-            nsIUnicodeDecoder::kOnError_Recover);
         // meta scan successful
         mCharsetSource = kCharsetFromMetaPrescan;
         mFeedChardet = false;
         mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
         mMetaScanner = nullptr;
         return WriteSniffingBufferAndCurrentSegment(aFromSegment, aCount,
             aWriteCount);
       }
@@ -765,18 +759,16 @@ nsHtml5StreamParser::SniffStreamBytes(co
   }
 
   // not the last buffer
   if (mMode == NORMAL || mMode == VIEW_SOURCE_HTML || mMode == LOAD_AS_DATA) {
     nsHtml5ByteReadable readable(aFromSegment, aFromSegment + aCount);
     mMetaScanner->sniff(&readable, getter_AddRefs(mUnicodeDecoder), mCharset);
     if (mUnicodeDecoder) {
       // meta scan successful
-      mUnicodeDecoder->SetInputErrorBehavior(
-          nsIUnicodeDecoder::kOnError_Recover);
       mCharsetSource = kCharsetFromMetaPrescan;
       mFeedChardet = false;
       mTreeBuilder->SetDocumentCharset(mCharset, mCharsetSource);
       mMetaScanner = nullptr;
       return WriteSniffingBufferAndCurrentSegment(aFromSegment, 
                                                   aCount,
                                                   aWriteCount);
     }
@@ -819,77 +811,28 @@ nsHtml5StreamParser::WriteStreamBytes(co
     int32_t byteCount = aCount - totalByteCount;
     int32_t utf16Count = NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE - end;
 
     NS_ASSERTION(utf16Count, "Trying to convert into a buffer with no free space!");
     // byteCount may be zero to force the decoder to output a pending surrogate
     // pair.
 
     nsresult convResult = mUnicodeDecoder->Convert((const char*)aFromSegment, &byteCount, mLastBuffer->getBuffer() + end, &utf16Count);
+    MOZ_ASSERT(NS_SUCCEEDED(convResult));
 
     end += utf16Count;
     mLastBuffer->setEnd(end);
     totalByteCount += byteCount;
     aFromSegment += byteCount;
 
     NS_ASSERTION(end <= NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE,
         "The Unicode decoder wrote too much data.");
     NS_ASSERTION(byteCount >= -1, "The decoder consumed fewer than -1 bytes.");
 
-    if (NS_FAILED(convResult)) {
-      // Using the more generic NS_FAILED test above in case there are still
-      // decoders around that don't use NS_ERROR_ILLEGAL_INPUT properly.
-      NS_ASSERTION(convResult == NS_ERROR_ILLEGAL_INPUT,
-          "The decoder signaled an error other than NS_ERROR_ILLEGAL_INPUT.");
-
-      // There's an illegal byte in the input. It's now the responsibility
-      // of this calling code to output a U+FFFD REPLACEMENT CHARACTER and
-      // reset the decoder.
-
-      if (totalByteCount < (int32_t)aCount) {
-        // advance over the bad byte
-        ++totalByteCount;
-        ++aFromSegment;
-      } else {
-        NS_NOTREACHED("The decoder signaled an error but consumed all input.");
-        // Recovering from this situation in case there are still broken
-        // decoders, since nsScanner had recovery code, too.
-        totalByteCount = (int32_t)aCount;
-      }
-
-      // Emit the REPLACEMENT CHARACTER
-      if (end >= NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE) {
-        nsRefPtr<nsHtml5OwningUTF16Buffer> newBuf =
-          nsHtml5OwningUTF16Buffer::FalliblyCreate(
-            NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE);
-        if (!newBuf) {
-          return NS_ERROR_OUT_OF_MEMORY;
-        }
-        mLastBuffer = (mLastBuffer->next = newBuf.forget());
-        end = 0;
-      }
-      mLastBuffer->getBuffer()[end] = 0xFFFD;
-      ++end;
-      mLastBuffer->setEnd(end);
-      if (end >= NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE) {
-        nsRefPtr<nsHtml5OwningUTF16Buffer> newBuf =
-          nsHtml5OwningUTF16Buffer::FalliblyCreate(
-            NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE);
-        if (!newBuf) {
-          return NS_ERROR_OUT_OF_MEMORY;
-        }
-        mLastBuffer = (mLastBuffer->next = newBuf.forget());
-      }
-
-      mUnicodeDecoder->Reset();
-      if (totalByteCount == (int32_t)aCount) {
-        *aWriteCount = (uint32_t)totalByteCount;
-        return NS_OK;
-      }
-    } else if (convResult == NS_PARTIAL_MORE_OUTPUT) {
+    if (convResult == NS_PARTIAL_MORE_OUTPUT) {
       nsRefPtr<nsHtml5OwningUTF16Buffer> newBuf =
         nsHtml5OwningUTF16Buffer::FalliblyCreate(
           NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE);
       if (!newBuf) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
       mLastBuffer = (mLastBuffer->next = newBuf.forget());
       // All input may have been consumed if there is a pending surrogate pair
@@ -1006,19 +949,17 @@ nsHtml5StreamParser::OnStartRequest(nsIR
     return NS_OK;
   }
   
   nsCOMPtr<nsICharsetConverterManager> convManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = convManager->GetUnicodeDecoder(mCharset.get(), getter_AddRefs(mUnicodeDecoder));
   // if we failed to get a decoder, there will be fallback, so don't propagate
   //  the error.
-  if (NS_SUCCEEDED(rv)) {
-    mUnicodeDecoder->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Recover);
-  } else {
+  if (NS_FAILED(rv)) {
     mCharsetSource = kCharsetFromWeakDocTypeDefault;
   }
   return NS_OK;
 }
 
 void
 nsHtml5StreamParser::DoStopRequest()
 {