mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 05:15:45 +00:00
Fixing rtm++ bug 56212. The new serializers were a bit too eager about what characters to encode as entities, this caused bad things when sending email that contained double quotes and also when writing a message containing quotes in AIM. sr=vidur, r=nisheeth.
This commit is contained in:
parent
589e7d964c
commit
bf199577e4
@ -390,22 +390,45 @@ ConvertAndWrite(nsAReadableString& aString,
|
||||
NS_ENSURE_ARG_POINTER(aStream);
|
||||
NS_ENSURE_ARG_POINTER(aEncoder);
|
||||
nsresult rv;
|
||||
PRInt32 charLength;
|
||||
PRInt32 charLength, startCharLength;
|
||||
const PRUnichar* unicodeBuf = (const PRUnichar*)nsPromiseFlatString(aString);
|
||||
PRInt32 unicodeLength = aString.Length();
|
||||
PRInt32 startLength = unicodeLength;
|
||||
|
||||
rv = aEncoder->GetMaxLength(unicodeBuf, unicodeLength, &charLength);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString charXferString;
|
||||
charXferString.SetCapacity(charLength);
|
||||
char* charXferBuf = (char*)charXferString.GetBuffer();
|
||||
startCharLength = charLength;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aEncoder->Convert(unicodeBuf, &unicodeLength, charXferBuf, &charLength);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRUint32 written;
|
||||
rv = aStream->Write(charXferBuf, charLength, &written);
|
||||
nsCAutoString charXferString;
|
||||
charXferString.SetCapacity(charLength);
|
||||
char* charXferBuf = (char*)charXferString.GetBuffer();
|
||||
nsresult convert_rv = NS_OK;
|
||||
|
||||
do {
|
||||
unicodeLength = startLength;
|
||||
charLength = startCharLength;
|
||||
|
||||
convert_rv = aEncoder->Convert(unicodeBuf, &unicodeLength, charXferBuf, &charLength);
|
||||
NS_ENSURE_SUCCESS(convert_rv, convert_rv);
|
||||
|
||||
PRUint32 written;
|
||||
rv = aStream->Write(charXferBuf, charLength, &written);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If the converter couldn't convert a chraacer we replace the
|
||||
// character with a characre entity.
|
||||
if (convert_rv == NS_ERROR_UENC_NOMAPPING) {
|
||||
nsCAutoString entString("&#");
|
||||
entString.AppendInt(unicodeBuf[unicodeLength - 1]);
|
||||
entString.Append(';');
|
||||
|
||||
rv = aStream->Write(entString.GetBuffer(), entString.Length(), &written);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
unicodeBuf += unicodeLength;
|
||||
startLength -= unicodeLength;
|
||||
}
|
||||
}
|
||||
} while (convert_rv == NS_ERROR_UENC_NOMAPPING);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "nsEscape.h"
|
||||
|
||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
|
||||
static NS_DEFINE_CID(kEntityConverterCID, NS_ENTITYCONVERTER_CID);
|
||||
|
||||
#define kIndentStr NS_LITERAL_STRING(" ")
|
||||
#define kMozStr "_moz"
|
||||
@ -63,6 +62,7 @@ nsHTMLContentSerializer::nsHTMLContentSerializer()
|
||||
mColPos = 0;
|
||||
mIndent = 0;
|
||||
mInBody = PR_FALSE;
|
||||
mInScriptOrStyle = PR_FALSE;
|
||||
}
|
||||
|
||||
nsHTMLContentSerializer::~nsHTMLContentSerializer()
|
||||
@ -267,7 +267,12 @@ nsHTMLContentSerializer::AppendElementStart(nsIDOMElement *aElement,
|
||||
AppendToString(mLineBreak, aStr);
|
||||
mColPos = 0;
|
||||
}
|
||||
|
||||
|
||||
if ((name.get() == nsHTMLAtoms::script) ||
|
||||
(name.get() == nsHTMLAtoms::style)) {
|
||||
mInScriptOrStyle = PR_TRUE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -296,7 +301,11 @@ nsHTMLContentSerializer::AppendElementEnd(nsIDOMElement *aElement,
|
||||
|
||||
nsCOMPtr<nsIParserService> parserService;
|
||||
GetParserService(getter_AddRefs(parserService));
|
||||
if (parserService) {
|
||||
|
||||
if ((name.get() == nsHTMLAtoms::script) ||
|
||||
(name.get() == nsHTMLAtoms::style)) {
|
||||
mInScriptOrStyle = PR_FALSE;
|
||||
} else if (parserService) {
|
||||
nsAutoString nameStr(sharedName);
|
||||
PRBool isContainer;
|
||||
PRInt32 id;
|
||||
@ -444,6 +453,27 @@ nsHTMLContentSerializer::AppendToStringWrapped(const nsAReadableString& aStr,
|
||||
}
|
||||
}
|
||||
|
||||
static PRUint16 kGTVal = 62;
|
||||
static const char* kEntities[] = {
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "amp", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"lt", "", "gt"
|
||||
};
|
||||
|
||||
static const char* kAttrEntities[] = {
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "quot", "", "", "", "amp", "apos",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"lt", "", "gt"
|
||||
};
|
||||
|
||||
void
|
||||
nsHTMLContentSerializer::AppendToString(const nsAReadableString& aStr,
|
||||
nsAWritableString& aOutputStr,
|
||||
@ -457,17 +487,69 @@ nsHTMLContentSerializer::AppendToString(const nsAReadableString& aStr,
|
||||
if (aIncrColumn) {
|
||||
mColPos += aStr.Length();
|
||||
}
|
||||
|
||||
if (aTranslateEntities) {
|
||||
PRUnichar *encodedBuffer;
|
||||
encodedBuffer = nsEscapeHTML2(nsPromiseFlatString(aStr), aStr.Length());
|
||||
if (encodedBuffer) {
|
||||
aOutputStr.Append(encodedBuffer);
|
||||
nsCRT::free(encodedBuffer);
|
||||
return;
|
||||
|
||||
if (aTranslateEntities && !mInScriptOrStyle) {
|
||||
if (mFlags & nsIDocumentEncoder::OutputEncodeEntities) {
|
||||
nsCOMPtr<nsIParserService> parserService;
|
||||
GetParserService(getter_AddRefs(parserService));
|
||||
|
||||
if (!parserService) {
|
||||
NS_ERROR("Can't get parser service");
|
||||
return;
|
||||
}
|
||||
|
||||
nsReadingIterator<PRUnichar> done_reading;
|
||||
aStr.EndReading(done_reading);
|
||||
|
||||
// for each chunk of |aString|...
|
||||
PRUint32 advanceLength = 0;
|
||||
nsReadingIterator<PRUnichar> iter;
|
||||
|
||||
const char **entityTable = mInAttribute ? kAttrEntities : kEntities;
|
||||
|
||||
for (aStr.BeginReading(iter);
|
||||
iter != done_reading;
|
||||
iter.advance(PRInt32(advanceLength))) {
|
||||
PRUint32 fragmentLength = iter.size_forward();
|
||||
const PRUnichar* c = iter.get();
|
||||
const PRUnichar* fragmentStart = c;
|
||||
const PRUnichar* fragmentEnd = c + fragmentLength;
|
||||
const char* entityText = nsnull;
|
||||
nsCAutoString entityReplacement;
|
||||
|
||||
advanceLength = 0;
|
||||
// for each character in this chunk, check if it
|
||||
// needs to be replaced
|
||||
for (; c < fragmentEnd; c++, advanceLength++) {
|
||||
PRUnichar val = *c;
|
||||
if ((val <= kGTVal) && (entityTable[val][0] != 0)) {
|
||||
entityText = entityTable[val];
|
||||
break;
|
||||
} else if (val > 127) {
|
||||
parserService->HTMLConvertUnicodeToEntity(val, entityReplacement);
|
||||
|
||||
if (entityReplacement.Length() > 0) {
|
||||
entityText = entityReplacement.GetBuffer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aOutputStr.Append(fragmentStart, advanceLength);
|
||||
if (entityText) {
|
||||
aOutputStr.Append(PRUnichar('&'));
|
||||
aOutputStr.Append(NS_ConvertASCIItoUCS2(entityText));
|
||||
aOutputStr.Append(PRUnichar(';'));
|
||||
advanceLength++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nsXMLContentSerializer::AppendToString(aStr, aOutputStr, aTranslateEntities, aIncrColumn);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
aOutputStr.Append(aStr);
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,7 @@ class nsHTMLContentSerializer : public nsXMLContentSerializer {
|
||||
PRBool mDoHeader;
|
||||
PRBool mBodyOnly;
|
||||
PRInt32 mPreLevel;
|
||||
PRBool mInScriptOrStyle;
|
||||
|
||||
PRInt32 mMaxColumn;
|
||||
|
||||
|
@ -56,6 +56,7 @@ nsXMLContentSerializer::nsXMLContentSerializer()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mPrefixIndex = 0;
|
||||
mInAttribute = PR_FALSE;
|
||||
}
|
||||
|
||||
nsXMLContentSerializer::~nsXMLContentSerializer()
|
||||
@ -219,16 +220,19 @@ nsXMLContentSerializer::AppendDoctype(nsIDOMDocumentType *aDoctype,
|
||||
AppendToString(quote, aStr);
|
||||
AppendToString(publicId, aStr);
|
||||
AppendToString(quote, aStr);
|
||||
AppendToString(PRUnichar(' '), aStr);
|
||||
if (systemId.FindChar(PRUnichar('"')) == -1) {
|
||||
quote = PRUnichar('"');
|
||||
|
||||
if (systemId.Length()) {
|
||||
AppendToString(PRUnichar(' '), aStr);
|
||||
if (systemId.FindChar(PRUnichar('"')) == -1) {
|
||||
quote = PRUnichar('"');
|
||||
}
|
||||
else {
|
||||
quote = PRUnichar('\'');
|
||||
}
|
||||
AppendToString(quote, aStr);
|
||||
AppendToString(systemId, aStr);
|
||||
AppendToString(quote, aStr);
|
||||
}
|
||||
else {
|
||||
quote = PRUnichar('\'');
|
||||
}
|
||||
AppendToString(quote, aStr);
|
||||
AppendToString(systemId, aStr);
|
||||
AppendToString(quote, aStr);
|
||||
}
|
||||
else if (systemId.Length() > 0) {
|
||||
if (systemId.FindChar(PRUnichar('"')) == -1) {
|
||||
@ -363,7 +367,11 @@ nsXMLContentSerializer::SerializeAttr(const nsAReadableString& aPrefix,
|
||||
AppendToString(aName, aStr);
|
||||
|
||||
AppendToString(NS_LITERAL_STRING("=\""), aStr);
|
||||
|
||||
mInAttribute = PR_TRUE;
|
||||
AppendToString(aValue, aStr, PR_TRUE);
|
||||
mInAttribute = PR_FALSE;
|
||||
|
||||
AppendToString(NS_LITERAL_STRING("\""), aStr);
|
||||
}
|
||||
|
||||
@ -528,6 +536,16 @@ nsXMLContentSerializer::AppendToString(const PRUnichar aChar,
|
||||
|
||||
static PRUint16 kGTVal = 62;
|
||||
static const char* kEntities[] = {
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "&", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"<", "", ">"
|
||||
};
|
||||
|
||||
static const char* kAttrEntities[] = {
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
@ -550,7 +568,9 @@ nsXMLContentSerializer::AppendToString(const nsAReadableString& aStr,
|
||||
// for each chunk of |aString|...
|
||||
PRUint32 advanceLength = 0;
|
||||
nsReadingIterator<PRUnichar> iter;
|
||||
|
||||
|
||||
const char **entityTable = mInAttribute ? kAttrEntities : kEntities;
|
||||
|
||||
for (aStr.BeginReading(iter);
|
||||
iter != done_reading;
|
||||
iter.advance(PRInt32(advanceLength))) {
|
||||
@ -560,12 +580,13 @@ nsXMLContentSerializer::AppendToString(const nsAReadableString& aStr,
|
||||
const PRUnichar* fragmentEnd = c + fragmentLength;
|
||||
const char* entityText = nsnull;
|
||||
|
||||
advanceLength = 0;
|
||||
// for each character in this chunk, check if it
|
||||
// needs to be replaced
|
||||
for (; c < fragmentEnd; c++, advanceLength++) {
|
||||
PRUnichar val = *c;
|
||||
if ((val <= kGTVal) && (kEntities[val][0] != 0)) {
|
||||
entityText = kEntities[val];
|
||||
if ((val <= kGTVal) && (entityTable[val][0] != 0)) {
|
||||
entityText = entityTable[val];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -576,6 +597,8 @@ nsXMLContentSerializer::AppendToString(const nsAReadableString& aStr,
|
||||
advanceLength++;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
aOutputStr.Append(aStr);
|
||||
|
@ -94,6 +94,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
||||
|
||||
PRInt32 mPrefixIndex;
|
||||
nsVoidArray mNameSpaceStack;
|
||||
PRBool mInAttribute;
|
||||
};
|
||||
|
||||
extern nsresult NS_NewXMLContentSerializer(nsIContentSerializer** aSerializer);
|
||||
|
@ -1604,7 +1604,7 @@ nsEditor::SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting,
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
|
||||
// Should we prettyprint?
|
||||
PRUint32 flags = 0;
|
||||
PRUint32 flags = nsIDocumentEncoder::OutputEncodeEntities;
|
||||
NS_WITH_SERVICE(nsIPref, prefService, kPrefServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && prefService)
|
||||
{
|
||||
|
@ -1604,7 +1604,7 @@ nsEditor::SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting,
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
|
||||
// Should we prettyprint?
|
||||
PRUint32 flags = 0;
|
||||
PRUint32 flags = nsIDocumentEncoder::OutputEncodeEntities;
|
||||
NS_WITH_SERVICE(nsIPref, prefService, kPrefServiceCID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && prefService)
|
||||
{
|
||||
|
@ -390,22 +390,45 @@ ConvertAndWrite(nsAReadableString& aString,
|
||||
NS_ENSURE_ARG_POINTER(aStream);
|
||||
NS_ENSURE_ARG_POINTER(aEncoder);
|
||||
nsresult rv;
|
||||
PRInt32 charLength;
|
||||
PRInt32 charLength, startCharLength;
|
||||
const PRUnichar* unicodeBuf = (const PRUnichar*)nsPromiseFlatString(aString);
|
||||
PRInt32 unicodeLength = aString.Length();
|
||||
PRInt32 startLength = unicodeLength;
|
||||
|
||||
rv = aEncoder->GetMaxLength(unicodeBuf, unicodeLength, &charLength);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString charXferString;
|
||||
charXferString.SetCapacity(charLength);
|
||||
char* charXferBuf = (char*)charXferString.GetBuffer();
|
||||
startCharLength = charLength;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aEncoder->Convert(unicodeBuf, &unicodeLength, charXferBuf, &charLength);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRUint32 written;
|
||||
rv = aStream->Write(charXferBuf, charLength, &written);
|
||||
nsCAutoString charXferString;
|
||||
charXferString.SetCapacity(charLength);
|
||||
char* charXferBuf = (char*)charXferString.GetBuffer();
|
||||
nsresult convert_rv = NS_OK;
|
||||
|
||||
do {
|
||||
unicodeLength = startLength;
|
||||
charLength = startCharLength;
|
||||
|
||||
convert_rv = aEncoder->Convert(unicodeBuf, &unicodeLength, charXferBuf, &charLength);
|
||||
NS_ENSURE_SUCCESS(convert_rv, convert_rv);
|
||||
|
||||
PRUint32 written;
|
||||
rv = aStream->Write(charXferBuf, charLength, &written);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If the converter couldn't convert a chraacer we replace the
|
||||
// character with a characre entity.
|
||||
if (convert_rv == NS_ERROR_UENC_NOMAPPING) {
|
||||
nsCAutoString entString("&#");
|
||||
entString.AppendInt(unicodeBuf[unicodeLength - 1]);
|
||||
entString.Append(';');
|
||||
|
||||
rv = aStream->Write(entString.GetBuffer(), entString.Length(), &written);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
unicodeBuf += unicodeLength;
|
||||
startLength -= unicodeLength;
|
||||
}
|
||||
}
|
||||
} while (convert_rv == NS_ERROR_UENC_NOMAPPING);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "nsEscape.h"
|
||||
|
||||
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
|
||||
static NS_DEFINE_CID(kEntityConverterCID, NS_ENTITYCONVERTER_CID);
|
||||
|
||||
#define kIndentStr NS_LITERAL_STRING(" ")
|
||||
#define kMozStr "_moz"
|
||||
@ -63,6 +62,7 @@ nsHTMLContentSerializer::nsHTMLContentSerializer()
|
||||
mColPos = 0;
|
||||
mIndent = 0;
|
||||
mInBody = PR_FALSE;
|
||||
mInScriptOrStyle = PR_FALSE;
|
||||
}
|
||||
|
||||
nsHTMLContentSerializer::~nsHTMLContentSerializer()
|
||||
@ -267,7 +267,12 @@ nsHTMLContentSerializer::AppendElementStart(nsIDOMElement *aElement,
|
||||
AppendToString(mLineBreak, aStr);
|
||||
mColPos = 0;
|
||||
}
|
||||
|
||||
|
||||
if ((name.get() == nsHTMLAtoms::script) ||
|
||||
(name.get() == nsHTMLAtoms::style)) {
|
||||
mInScriptOrStyle = PR_TRUE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -296,7 +301,11 @@ nsHTMLContentSerializer::AppendElementEnd(nsIDOMElement *aElement,
|
||||
|
||||
nsCOMPtr<nsIParserService> parserService;
|
||||
GetParserService(getter_AddRefs(parserService));
|
||||
if (parserService) {
|
||||
|
||||
if ((name.get() == nsHTMLAtoms::script) ||
|
||||
(name.get() == nsHTMLAtoms::style)) {
|
||||
mInScriptOrStyle = PR_FALSE;
|
||||
} else if (parserService) {
|
||||
nsAutoString nameStr(sharedName);
|
||||
PRBool isContainer;
|
||||
PRInt32 id;
|
||||
@ -444,6 +453,27 @@ nsHTMLContentSerializer::AppendToStringWrapped(const nsAReadableString& aStr,
|
||||
}
|
||||
}
|
||||
|
||||
static PRUint16 kGTVal = 62;
|
||||
static const char* kEntities[] = {
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "amp", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"lt", "", "gt"
|
||||
};
|
||||
|
||||
static const char* kAttrEntities[] = {
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "quot", "", "", "", "amp", "apos",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"lt", "", "gt"
|
||||
};
|
||||
|
||||
void
|
||||
nsHTMLContentSerializer::AppendToString(const nsAReadableString& aStr,
|
||||
nsAWritableString& aOutputStr,
|
||||
@ -457,17 +487,69 @@ nsHTMLContentSerializer::AppendToString(const nsAReadableString& aStr,
|
||||
if (aIncrColumn) {
|
||||
mColPos += aStr.Length();
|
||||
}
|
||||
|
||||
if (aTranslateEntities) {
|
||||
PRUnichar *encodedBuffer;
|
||||
encodedBuffer = nsEscapeHTML2(nsPromiseFlatString(aStr), aStr.Length());
|
||||
if (encodedBuffer) {
|
||||
aOutputStr.Append(encodedBuffer);
|
||||
nsCRT::free(encodedBuffer);
|
||||
return;
|
||||
|
||||
if (aTranslateEntities && !mInScriptOrStyle) {
|
||||
if (mFlags & nsIDocumentEncoder::OutputEncodeEntities) {
|
||||
nsCOMPtr<nsIParserService> parserService;
|
||||
GetParserService(getter_AddRefs(parserService));
|
||||
|
||||
if (!parserService) {
|
||||
NS_ERROR("Can't get parser service");
|
||||
return;
|
||||
}
|
||||
|
||||
nsReadingIterator<PRUnichar> done_reading;
|
||||
aStr.EndReading(done_reading);
|
||||
|
||||
// for each chunk of |aString|...
|
||||
PRUint32 advanceLength = 0;
|
||||
nsReadingIterator<PRUnichar> iter;
|
||||
|
||||
const char **entityTable = mInAttribute ? kAttrEntities : kEntities;
|
||||
|
||||
for (aStr.BeginReading(iter);
|
||||
iter != done_reading;
|
||||
iter.advance(PRInt32(advanceLength))) {
|
||||
PRUint32 fragmentLength = iter.size_forward();
|
||||
const PRUnichar* c = iter.get();
|
||||
const PRUnichar* fragmentStart = c;
|
||||
const PRUnichar* fragmentEnd = c + fragmentLength;
|
||||
const char* entityText = nsnull;
|
||||
nsCAutoString entityReplacement;
|
||||
|
||||
advanceLength = 0;
|
||||
// for each character in this chunk, check if it
|
||||
// needs to be replaced
|
||||
for (; c < fragmentEnd; c++, advanceLength++) {
|
||||
PRUnichar val = *c;
|
||||
if ((val <= kGTVal) && (entityTable[val][0] != 0)) {
|
||||
entityText = entityTable[val];
|
||||
break;
|
||||
} else if (val > 127) {
|
||||
parserService->HTMLConvertUnicodeToEntity(val, entityReplacement);
|
||||
|
||||
if (entityReplacement.Length() > 0) {
|
||||
entityText = entityReplacement.GetBuffer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aOutputStr.Append(fragmentStart, advanceLength);
|
||||
if (entityText) {
|
||||
aOutputStr.Append(PRUnichar('&'));
|
||||
aOutputStr.Append(NS_ConvertASCIItoUCS2(entityText));
|
||||
aOutputStr.Append(PRUnichar(';'));
|
||||
advanceLength++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
nsXMLContentSerializer::AppendToString(aStr, aOutputStr, aTranslateEntities, aIncrColumn);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
aOutputStr.Append(aStr);
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,7 @@ class nsHTMLContentSerializer : public nsXMLContentSerializer {
|
||||
PRBool mDoHeader;
|
||||
PRBool mBodyOnly;
|
||||
PRInt32 mPreLevel;
|
||||
PRBool mInScriptOrStyle;
|
||||
|
||||
PRInt32 mMaxColumn;
|
||||
|
||||
|
@ -56,6 +56,7 @@ nsXMLContentSerializer::nsXMLContentSerializer()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
mPrefixIndex = 0;
|
||||
mInAttribute = PR_FALSE;
|
||||
}
|
||||
|
||||
nsXMLContentSerializer::~nsXMLContentSerializer()
|
||||
@ -219,16 +220,19 @@ nsXMLContentSerializer::AppendDoctype(nsIDOMDocumentType *aDoctype,
|
||||
AppendToString(quote, aStr);
|
||||
AppendToString(publicId, aStr);
|
||||
AppendToString(quote, aStr);
|
||||
AppendToString(PRUnichar(' '), aStr);
|
||||
if (systemId.FindChar(PRUnichar('"')) == -1) {
|
||||
quote = PRUnichar('"');
|
||||
|
||||
if (systemId.Length()) {
|
||||
AppendToString(PRUnichar(' '), aStr);
|
||||
if (systemId.FindChar(PRUnichar('"')) == -1) {
|
||||
quote = PRUnichar('"');
|
||||
}
|
||||
else {
|
||||
quote = PRUnichar('\'');
|
||||
}
|
||||
AppendToString(quote, aStr);
|
||||
AppendToString(systemId, aStr);
|
||||
AppendToString(quote, aStr);
|
||||
}
|
||||
else {
|
||||
quote = PRUnichar('\'');
|
||||
}
|
||||
AppendToString(quote, aStr);
|
||||
AppendToString(systemId, aStr);
|
||||
AppendToString(quote, aStr);
|
||||
}
|
||||
else if (systemId.Length() > 0) {
|
||||
if (systemId.FindChar(PRUnichar('"')) == -1) {
|
||||
@ -363,7 +367,11 @@ nsXMLContentSerializer::SerializeAttr(const nsAReadableString& aPrefix,
|
||||
AppendToString(aName, aStr);
|
||||
|
||||
AppendToString(NS_LITERAL_STRING("=\""), aStr);
|
||||
|
||||
mInAttribute = PR_TRUE;
|
||||
AppendToString(aValue, aStr, PR_TRUE);
|
||||
mInAttribute = PR_FALSE;
|
||||
|
||||
AppendToString(NS_LITERAL_STRING("\""), aStr);
|
||||
}
|
||||
|
||||
@ -528,6 +536,16 @@ nsXMLContentSerializer::AppendToString(const PRUnichar aChar,
|
||||
|
||||
static PRUint16 kGTVal = 62;
|
||||
static const char* kEntities[] = {
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "&", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"<", "", ">"
|
||||
};
|
||||
|
||||
static const char* kAttrEntities[] = {
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
@ -550,7 +568,9 @@ nsXMLContentSerializer::AppendToString(const nsAReadableString& aStr,
|
||||
// for each chunk of |aString|...
|
||||
PRUint32 advanceLength = 0;
|
||||
nsReadingIterator<PRUnichar> iter;
|
||||
|
||||
|
||||
const char **entityTable = mInAttribute ? kAttrEntities : kEntities;
|
||||
|
||||
for (aStr.BeginReading(iter);
|
||||
iter != done_reading;
|
||||
iter.advance(PRInt32(advanceLength))) {
|
||||
@ -560,12 +580,13 @@ nsXMLContentSerializer::AppendToString(const nsAReadableString& aStr,
|
||||
const PRUnichar* fragmentEnd = c + fragmentLength;
|
||||
const char* entityText = nsnull;
|
||||
|
||||
advanceLength = 0;
|
||||
// for each character in this chunk, check if it
|
||||
// needs to be replaced
|
||||
for (; c < fragmentEnd; c++, advanceLength++) {
|
||||
PRUnichar val = *c;
|
||||
if ((val <= kGTVal) && (kEntities[val][0] != 0)) {
|
||||
entityText = kEntities[val];
|
||||
if ((val <= kGTVal) && (entityTable[val][0] != 0)) {
|
||||
entityText = entityTable[val];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -576,6 +597,8 @@ nsXMLContentSerializer::AppendToString(const nsAReadableString& aStr,
|
||||
advanceLength++;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
aOutputStr.Append(aStr);
|
||||
|
@ -94,6 +94,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
||||
|
||||
PRInt32 mPrefixIndex;
|
||||
nsVoidArray mNameSpaceStack;
|
||||
PRBool mInAttribute;
|
||||
};
|
||||
|
||||
extern nsresult NS_NewXMLContentSerializer(nsIContentSerializer** aSerializer);
|
||||
|
Loading…
Reference in New Issue
Block a user