diff --git a/mozilla/htmlparser/src/nsParser.cpp b/mozilla/htmlparser/src/nsParser.cpp
index e595484d3af..2075731e705 100644
--- a/mozilla/htmlparser/src/nsParser.cpp
+++ b/mozilla/htmlparser/src/nsParser.cpp
@@ -1972,14 +1972,27 @@ nsresult nsParser::OnStartRequest(nsIRequest *request, nsISupports* aContext) {
}
-#define UCS2_BE "UTF-16BE"
-#define UCS2_LE "UTF-16LE"
+#define UTF16_BE "UTF-16BE"
+#define UTF16_LE "UTF-16LE"
#define UCS4_BE "UTF-32BE"
#define UCS4_LE "UTF-32LE"
#define UCS4_2143 "X-ISO-10646-UCS-4-2143"
#define UCS4_3412 "X-ISO-10646-UCS-4-3412"
#define UTF8 "UTF-8"
+static inline PRBool IsSecondMarker(unsigned char aChar)
+{
+ switch (aChar) {
+ case '!':
+ case '?':
+ case 'h':
+ case 'H':
+ return PR_TRUE;
+ default:
+ return PR_FALSE;
+ }
+}
+
static PRBool DetectByteOrderMark(const unsigned char* aBytes, PRInt32 aLen, nsString& oCharset, PRInt32& oCharsetSource) {
oCharsetSource= kCharsetFromAutoDetection;
oCharset.Truncate();
@@ -1993,34 +2006,45 @@ static PRBool DetectByteOrderMark(const unsigned char* aBytes, PRInt32 aLen, nsS
case 0x00:
if(0x00==aBytes[1]) {
// 00 00
- if((0x00==aBytes[2]) && (0x3C==aBytes[3])) {
+ if((0xFE==aBytes[2]) && (0xFF==aBytes[3])) {
+ // 00 00 FE FF UCS-4, big-endian machine (1234 order)
+ oCharset.AssignWithConversion(UCS4_BE);
+ } else if((0x00==aBytes[2]) && (0x3C==aBytes[3])) {
// 00 00 00 3C UCS-4, big-endian machine (1234 order)
oCharset.AssignWithConversion(UCS4_BE);
+ } else if((0xFF==aBytes[2]) && (0xFE==aBytes[3])) {
+ // 00 00 FF FE UCS-4, unusual octet order (2143)
+ oCharset.AssignWithConversion(UCS4_2143);
} else if((0x3C==aBytes[2]) && (0x00==aBytes[3])) {
// 00 00 3C 00 UCS-4, unusual octet order (2143)
oCharset.AssignWithConversion(UCS4_2143);
}
- } else if(0x3C==aBytes[1]) {
- // 00 3C
- if((0x00==aBytes[2]) && (0x00==aBytes[3])) {
+ oCharsetSource = kCharsetFromByteOrderMark;
+ } else if((0x3C==aBytes[1]) && (0x00==aBytes[2])) {
+ // 00 3C 00
+ if(IsSecondMarker(aBytes[3])) {
+ // 00 3C 00 SM UTF-16, big-endian, no Byte Order Mark
+ oCharset.AssignWithConversion(UTF16_BE);
+ } else if((0x00==aBytes[3])) {
// 00 3C 00 00 UCS-4, unusual octet order (3412)
oCharset.AssignWithConversion(UCS4_3412);
- } else if((0x00==aBytes[2]) && (0x3F==aBytes[3])) {
- // 00 3C 00 3F UTF-16, big-endian, no Byte Order Mark
- oCharset.AssignWithConversion(UCS2_BE); // should change to UTF-16BE
}
+ oCharsetSource = kCharsetFromByteOrderMark;
}
break;
case 0x3C:
- if(0x00==aBytes[1]) {
- // 3C 00
- if((0x00==aBytes[2]) && (0x00==aBytes[3])) {
+ if(0x00==aBytes[1] && (0x00==aBytes[3])) {
+ // 3C 00 XX 00
+ if(IsSecondMarker(aBytes[2])) {
+ // 3C 00 SM 00 UTF-16, little-endian, no Byte Order Mark
+ oCharset.AssignWithConversion(UTF16_LE);
+ } else if((0x00==aBytes[2])) {
// 3C 00 00 00 UCS-4, little-endian machine (4321 order)
- oCharset.AssignWithConversion(UCS4_LE);
- } else if((0x3F==aBytes[2]) && (0x00==aBytes[3])) {
- // 3C 00 3F 00 UTF-16, little-endian, no Byte Order Mark
- oCharset.AssignWithConversion(UCS2_LE); // should change to UTF-16LE
+ oCharset.AssignWithConversion(UCS4_LE);
}
+ oCharsetSource = kCharsetFromByteOrderMark;
+ // For html, meta tag detector is invoked before this so that we have
+ // to deal only with XML here.
} else if( (0x3F==aBytes[1]) &&
(0x78==aBytes[2]) && (0x6D==aBytes[3]) &&
(0 == PL_strncmp("