зеркало из https://github.com/mozilla/pjs.git
Fix for bug 286132 (xml-stylesheet PI doesn't handle href attribute as in specification). r=sicking, sr=bz.
This commit is contained in:
Родитель
b8f105828d
Коммит
344498aa4e
|
@ -85,6 +85,7 @@ GK_ATOM(allowevents, "allowevents")
|
|||
GK_ATOM(allownegativeassertions, "allownegativeassertions")
|
||||
GK_ATOM(allowuntrusted, "allowuntrusted")
|
||||
GK_ATOM(alt, "alt")
|
||||
GK_ATOM(alternate, "alternate")
|
||||
GK_ATOM(always, "always")
|
||||
GK_ATOM(ancestor, "ancestor")
|
||||
GK_ATOM(ancestorOrSelf, "ancestor-or-self")
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include "jsapi.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIParserService.h"
|
||||
|
||||
#define SKIP_WHITESPACE(iter, end_iter) \
|
||||
while ((iter) != (end_iter) && nsCRT::IsAsciiSpace(*(iter))) { \
|
||||
|
@ -57,16 +59,14 @@
|
|||
break
|
||||
|
||||
PRBool
|
||||
nsParserUtils::GetQuotedAttributeValue(const nsAString& aSource,
|
||||
const nsAString& aAttribute,
|
||||
nsParserUtils::GetQuotedAttributeValue(const nsString& aSource, nsIAtom *aName,
|
||||
nsAString& aValue)
|
||||
{
|
||||
NS_ASSERTION(!aAttribute.IsEmpty(), "Empty attribute name cannot be searched for usefully");
|
||||
aValue.Truncate();
|
||||
nsAString::const_iterator start, end;
|
||||
aSource.BeginReading(start);
|
||||
aSource.EndReading(end);
|
||||
nsAString::const_iterator iter;
|
||||
|
||||
const PRUnichar *start = aSource.get();
|
||||
const PRUnichar *end = start + aSource.Length();
|
||||
const PRUnichar *iter;
|
||||
|
||||
while (start != end) {
|
||||
SKIP_WHITESPACE(start, end);
|
||||
|
@ -74,7 +74,7 @@ nsParserUtils::GetQuotedAttributeValue(const nsAString& aSource,
|
|||
SKIP_ATTR_NAME(iter, end);
|
||||
|
||||
// Remember the attr name.
|
||||
const nsAString & attrName = Substring(start, iter);
|
||||
const nsDependentSubstring & attrName = Substring(start, iter);
|
||||
|
||||
// Now check whether this is a valid name="value" pair.
|
||||
start = iter;
|
||||
|
@ -96,23 +96,60 @@ nsParserUtils::GetQuotedAttributeValue(const nsAString& aSource,
|
|||
|
||||
++start; // Point to the first char of the value.
|
||||
iter = start;
|
||||
if (!FindCharInReadable(q, iter, end)) {
|
||||
|
||||
while (iter != end && *iter != q) {
|
||||
++iter;
|
||||
}
|
||||
|
||||
if (iter == end) {
|
||||
// Oops, unterminated quoted string.
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// At this point attrName holds the name of the "attribute" and
|
||||
// the value is between start and iter.
|
||||
|
||||
if (!attrName.Equals(aAttribute)) {
|
||||
// Resume scanning after the end of the attribute value.
|
||||
start = iter;
|
||||
++start; // To move past the quote char.
|
||||
continue;
|
||||
if (aName->Equals(attrName)) {
|
||||
nsAString::iterator dest;
|
||||
aValue.BeginWriting(dest);
|
||||
|
||||
while (start != iter) {
|
||||
if (*start == kLessThan) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (*start == kAmpersand) {
|
||||
nsIParserService* parserService = nsContentUtils::GetParserService();
|
||||
NS_ENSURE_TRUE(parserService, PR_FALSE);
|
||||
|
||||
const PRUnichar *pos = start;
|
||||
|
||||
// Point to first character after the ampersand.
|
||||
++start;
|
||||
|
||||
// We rely on the fact that if this is a valid character reference,
|
||||
// dest will be a buffer with at least two PRUnichars (starting with
|
||||
// &#), so enough to contain any UTF-16 character.
|
||||
PRUint32 count =
|
||||
parserService->DecodeEntity(start, iter, &pos, dest.get());
|
||||
NS_ENSURE_TRUE(count > 0, PR_FALSE);
|
||||
|
||||
start = pos;
|
||||
dest.advance(count);
|
||||
}
|
||||
else {
|
||||
*dest = *start;
|
||||
++start;
|
||||
++dest;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
aValue = Substring(start, iter);
|
||||
return PR_TRUE;
|
||||
// Resume scanning after the end of the attribute value.
|
||||
start = iter;
|
||||
++start; // To move past the quote char.
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
|
|
|
@ -39,12 +39,23 @@
|
|||
#define nsParserUtils_h__
|
||||
|
||||
#include "nsString.h"
|
||||
class nsIAtom;
|
||||
|
||||
class nsParserUtils {
|
||||
public:
|
||||
/**
|
||||
* This will parse aSource, to extract the value of the pseudo attribute
|
||||
* with the name specified in aName. See
|
||||
* http://www.w3.org/TR/xml-stylesheet/#NT-StyleSheetPI for the specification
|
||||
* which is used to parse aSource.
|
||||
*
|
||||
* @param aSource the string to parse
|
||||
* @param aName the name of the attribute to get the value for
|
||||
* @param aValue [out] the value for the attribute with name specified in
|
||||
* aAttribute. Empty if the attribute isn't present.
|
||||
*/
|
||||
static PRBool
|
||||
GetQuotedAttributeValue(const nsAString& aSource,
|
||||
const nsAString& aAttribute,
|
||||
GetQuotedAttributeValue(const nsString& aSource, nsIAtom *aName,
|
||||
nsAString& aValue);
|
||||
|
||||
static PRBool
|
||||
|
|
|
@ -122,13 +122,12 @@ nsXMLProcessingInstruction::GetData(nsAString& aData)
|
|||
}
|
||||
|
||||
PRBool
|
||||
nsXMLProcessingInstruction::GetAttrValue(const nsAString& aAttr,
|
||||
nsAString& aValue)
|
||||
nsXMLProcessingInstruction::GetAttrValue(nsIAtom *aName, nsAString& aValue)
|
||||
{
|
||||
nsAutoString data;
|
||||
|
||||
GetData(data);
|
||||
return nsParserUtils::GetQuotedAttributeValue(data, aAttr, aValue);
|
||||
return nsParserUtils::GetQuotedAttributeValue(data, aName, aValue);
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
|
|
@ -73,7 +73,17 @@ public:
|
|||
#endif
|
||||
|
||||
protected:
|
||||
PRBool GetAttrValue(const nsAString& aAttr, nsAString& aValue);
|
||||
/**
|
||||
* This will parse the content of the PI, to extract the value of the pseudo
|
||||
* attribute with the name specified in aName. See
|
||||
* http://www.w3.org/TR/xml-stylesheet/#NT-StyleSheetPI for the specification
|
||||
* which is used to parse the content of the PI.
|
||||
*
|
||||
* @param aName the name of the attribute to get the value for
|
||||
* @param aValue [out] the value for the attribute with name specified in
|
||||
* aAttribute. Empty if the attribute isn't present.
|
||||
*/
|
||||
PRBool GetAttrValue(nsIAtom *aName, nsAString& aValue);
|
||||
|
||||
nsAutoString mTarget;
|
||||
};
|
||||
|
|
|
@ -148,11 +148,7 @@ nsXMLStylesheetPI::SetNodeValue(const nsAString& aNodeValue)
|
|||
NS_IMETHODIMP
|
||||
nsXMLStylesheetPI::GetCharset(nsAString& aCharset)
|
||||
{
|
||||
if (!GetAttrValue(NS_LITERAL_STRING("charset"), aCharset)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return GetAttrValue(nsGkAtoms::charset, aCharset) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -163,7 +159,7 @@ nsXMLStylesheetPI::GetStyleSheetURL(PRBool* aIsInline,
|
|||
*aURI = nsnull;
|
||||
|
||||
nsAutoString href;
|
||||
GetAttrValue(NS_LITERAL_STRING("href"), href);
|
||||
GetAttrValue(nsGkAtoms::href, href);
|
||||
if (href.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -197,31 +193,29 @@ nsXMLStylesheetPI::GetStyleSheetInfo(nsAString& aTitle,
|
|||
return;
|
||||
}
|
||||
|
||||
nsAutoString title, type, media, alternate;
|
||||
nsAutoString data;
|
||||
GetData(data);
|
||||
|
||||
GetAttrValue(NS_LITERAL_STRING("title"), title);
|
||||
title.CompressWhitespace();
|
||||
aTitle.Assign(title);
|
||||
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::title, aTitle);
|
||||
|
||||
GetAttrValue(NS_LITERAL_STRING("alternate"), alternate);
|
||||
nsAutoString alternate;
|
||||
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::alternate, alternate);
|
||||
|
||||
// if alternate, does it have title?
|
||||
if (alternate.EqualsLiteral("yes")) {
|
||||
if (aTitle.IsEmpty()) { // alternates must have title
|
||||
return;
|
||||
} else {
|
||||
*aIsAlternate = PR_TRUE;
|
||||
}
|
||||
|
||||
*aIsAlternate = PR_TRUE;
|
||||
}
|
||||
|
||||
GetAttrValue(NS_LITERAL_STRING("media"), media);
|
||||
aMedia.Assign(media);
|
||||
ToLowerCase(aMedia); // case sensitivity?
|
||||
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::media, aMedia);
|
||||
|
||||
GetAttrValue(NS_LITERAL_STRING("type"), type);
|
||||
nsAutoString type;
|
||||
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::type, type);
|
||||
|
||||
nsAutoString mimeType;
|
||||
nsAutoString notUsed;
|
||||
nsAutoString mimeType, notUsed;
|
||||
nsParserUtils::SplitMimeType(type, mimeType, notUsed);
|
||||
if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
|
||||
aType.Assign(type);
|
||||
|
|
|
@ -1133,64 +1133,80 @@ nsXMLContentSink::HandleProcessingInstruction(const PRUnichar *aTarget,
|
|||
{
|
||||
FlushText();
|
||||
|
||||
nsresult result = NS_OK;
|
||||
const nsDependentString target(aTarget);
|
||||
const nsDependentString data(aData);
|
||||
|
||||
nsCOMPtr<nsIContent> node;
|
||||
|
||||
result = NS_NewXMLProcessingInstruction(getter_AddRefs(node),
|
||||
mNodeInfoManager, target, data);
|
||||
if (NS_OK == result) {
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(node));
|
||||
nsresult rv = NS_NewXMLProcessingInstruction(getter_AddRefs(node),
|
||||
mNodeInfoManager, target, data);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (ssle) {
|
||||
ssle->InitStyleLinkElement(mParser, PR_FALSE);
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
mPrettyPrintXML = PR_FALSE;
|
||||
}
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(node));
|
||||
if (ssle) {
|
||||
ssle->InitStyleLinkElement(mParser, PR_FALSE);
|
||||
ssle->SetEnableUpdates(PR_FALSE);
|
||||
mPrettyPrintXML = PR_FALSE;
|
||||
}
|
||||
|
||||
result = AddContentAsLeaf(node);
|
||||
rv = AddContentAsLeaf(node);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (ssle) {
|
||||
ssle->SetEnableUpdates(PR_TRUE);
|
||||
result = ssle->UpdateStyleSheet(nsnull, nsnull);
|
||||
if (ssle) {
|
||||
ssle->SetEnableUpdates(PR_TRUE);
|
||||
rv = ssle->UpdateStyleSheet(nsnull, nsnull);
|
||||
|
||||
if (NS_FAILED(result)) {
|
||||
if (result == NS_ERROR_HTMLPARSER_BLOCK && mParser) {
|
||||
mParser->BlockParser();
|
||||
}
|
||||
return result;
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv == NS_ERROR_HTMLPARSER_BLOCK && mParser) {
|
||||
mParser->BlockParser();
|
||||
}
|
||||
}
|
||||
|
||||
// If it's not a CSS stylesheet PI...
|
||||
nsAutoString type;
|
||||
nsParserUtils::GetQuotedAttributeValue(data, NS_LITERAL_STRING("type"), type);
|
||||
if (mState == eXMLContentSinkState_InProlog &&
|
||||
target.EqualsLiteral("xml-stylesheet") &&
|
||||
!type.LowerCaseEqualsLiteral("text/css")) {
|
||||
nsAutoString href, title, media, alternate;
|
||||
|
||||
nsParserUtils::GetQuotedAttributeValue(data, NS_LITERAL_STRING("href"), href);
|
||||
// If there was no href, we can't do anything with this PI
|
||||
if (href.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsParserUtils::GetQuotedAttributeValue(data, NS_LITERAL_STRING("title"), title);
|
||||
title.CompressWhitespace();
|
||||
|
||||
nsParserUtils::GetQuotedAttributeValue(data, NS_LITERAL_STRING("media"), media);
|
||||
ToLowerCase(media);
|
||||
|
||||
nsParserUtils::GetQuotedAttributeValue(data, NS_LITERAL_STRING("alternate"), alternate);
|
||||
|
||||
result = ProcessStyleLink(node, href, alternate.EqualsLiteral("yes"),
|
||||
title, type, media);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
// If it's not a CSS stylesheet PI...
|
||||
nsAutoString type;
|
||||
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::type, type);
|
||||
|
||||
if (mState != eXMLContentSinkState_InProlog ||
|
||||
!target.EqualsLiteral("xml-stylesheet") ||
|
||||
type.LowerCaseEqualsLiteral("text/css")) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString href, title, media;
|
||||
PRBool isAlternate = PR_FALSE;
|
||||
ParsePIData(data, href, title, media, isAlternate);
|
||||
|
||||
// If there was no href, we can't do anything with this PI
|
||||
if (href.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return ProcessStyleLink(node, href, isAlternate, title, type, media);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsXMLContentSink::ParsePIData(const nsString &aData, nsString &aHref,
|
||||
nsString &aTitle, nsString &aMedia,
|
||||
PRBool &aIsAlternate)
|
||||
{
|
||||
nsParserUtils::GetQuotedAttributeValue(aData, nsGkAtoms::href, aHref);
|
||||
|
||||
// If there was no href, we can't do anything with this PI
|
||||
if (aHref.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsParserUtils::GetQuotedAttributeValue(aData, nsGkAtoms::title, aTitle);
|
||||
|
||||
nsParserUtils::GetQuotedAttributeValue(aData, nsGkAtoms::media, aMedia);
|
||||
|
||||
nsAutoString alternate;
|
||||
nsParserUtils::GetQuotedAttributeValue(aData, nsGkAtoms::alternate, alternate);
|
||||
|
||||
aIsAlternate = alternate.EqualsLiteral("yes");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -92,6 +92,10 @@ public:
|
|||
NS_IMETHOD OnDocumentCreated(nsIDOMDocument *aResultDocument);
|
||||
NS_IMETHOD OnTransformDone(nsresult aResult, nsIDOMDocument *aResultDocument);
|
||||
|
||||
static void ParsePIData(const nsString &aData, nsString &aHref,
|
||||
nsString &aTitle, nsString &aMedia,
|
||||
PRBool &aIsAlternate);
|
||||
|
||||
protected:
|
||||
void StartLayout();
|
||||
|
||||
|
|
|
@ -903,10 +903,11 @@ XULContentSinkImpl::HandleProcessingInstruction(const PRUnichar *aTarget,
|
|||
|
||||
tmp = targetStart;
|
||||
|
||||
nsresult rv;
|
||||
if (FindInReadable(NS_LITERAL_STRING("xul-overlay"), targetStart, targetEnd)) {
|
||||
// Load a XUL overlay.
|
||||
nsAutoString href;
|
||||
nsParserUtils::GetQuotedAttributeValue(data, NS_LITERAL_STRING("href"), href);
|
||||
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::href, href);
|
||||
|
||||
// If there was no href, we can't do
|
||||
// anything with this PI
|
||||
|
@ -916,7 +917,7 @@ XULContentSinkImpl::HandleProcessingInstruction(const PRUnichar *aTarget,
|
|||
|
||||
// Add the overlay to our list of overlays that need to be processed.
|
||||
nsCOMPtr<nsIURI> url;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(url), href, nsnull, mDocumentURL);
|
||||
rv = NS_NewURI(getter_AddRefs(url), href, nsnull, mDocumentURL);
|
||||
if (NS_FAILED(rv)) {
|
||||
// XXX This is wrong, the error message could be out of memory
|
||||
// or something else equally bad, which we should propagate.
|
||||
|
@ -924,50 +925,35 @@ XULContentSinkImpl::HandleProcessingInstruction(const PRUnichar *aTarget,
|
|||
return NS_OK; // The URL is bad, move along. Don't propagate for now.
|
||||
}
|
||||
|
||||
rv = mPrototype->AddOverlayReference(url);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
// If it's a stylesheet PI...
|
||||
else {
|
||||
targetStart = tmp;
|
||||
if (FindInReadable(NS_LITERAL_STRING("xml-stylesheet"), targetStart, targetEnd)) {
|
||||
nsAutoString href;
|
||||
nsParserUtils::GetQuotedAttributeValue(data, NS_LITERAL_STRING("href"), href);
|
||||
|
||||
// If there was no href, we can't do
|
||||
// anything with this PI
|
||||
if (href.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString type;
|
||||
nsParserUtils::GetQuotedAttributeValue(data, NS_LITERAL_STRING("type"), type);
|
||||
|
||||
nsAutoString title;
|
||||
nsParserUtils::GetQuotedAttributeValue(data, NS_LITERAL_STRING("title"), title);
|
||||
|
||||
title.CompressWhitespace();
|
||||
|
||||
nsAutoString media;
|
||||
nsParserUtils::GetQuotedAttributeValue(data, NS_LITERAL_STRING("media"), media);
|
||||
|
||||
ToLowerCase(media);
|
||||
|
||||
nsAutoString alternate;
|
||||
nsParserUtils::GetQuotedAttributeValue(data, NS_LITERAL_STRING("alternate"), alternate);
|
||||
|
||||
nsresult result = ProcessStyleLink(nsnull /* XXX need a node here */,
|
||||
href, alternate.EqualsLiteral("yes"), /* XXX ignore case? */
|
||||
title, type, media);
|
||||
if (NS_FAILED(result)) {
|
||||
if (result == NS_ERROR_HTMLPARSER_BLOCK && mParser) {
|
||||
mParser->BlockParser();
|
||||
}
|
||||
return result; // Important! A failure can indicate that the parser should block!
|
||||
}
|
||||
}
|
||||
return mPrototype->AddOverlayReference(url);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
targetStart = tmp;
|
||||
if (!FindInReadable(NS_LITERAL_STRING("xml-stylesheet"), targetStart,
|
||||
targetEnd)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// It's a stylesheet PI...
|
||||
nsAutoString type;
|
||||
nsParserUtils::GetQuotedAttributeValue(data, nsGkAtoms::type, type);
|
||||
|
||||
nsAutoString href, title, media;
|
||||
PRBool isAlternate = PR_FALSE;
|
||||
nsXMLContentSink::ParsePIData(data, href, title, media, isAlternate);
|
||||
|
||||
// If there was no href, we can't do anything with this PI
|
||||
if (href.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX need a node here
|
||||
rv = ProcessStyleLink(nsnull , href, isAlternate, title, type, media);
|
||||
if (rv == NS_ERROR_HTMLPARSER_BLOCK && mParser) {
|
||||
mParser->BlockParser();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -39,13 +39,15 @@
|
|||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
|
||||
#define BYTE_TYPE(p) LITTLE2_BYTE_TYPE(&little2_encoding_ns, p)
|
||||
#define PREFIX(ident) little2_ ## ident
|
||||
#define BYTE_TYPE(p) LITTLE2_BYTE_TYPE(XmlGetUtf16InternalEncodingNS(), p)
|
||||
#define IS_NAME_CHAR_MINBPC(p) LITTLE2_IS_NAME_CHAR_MINBPC(0, p)
|
||||
#define IS_NMSTRT_CHAR_MINBPC(p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(0, p)
|
||||
|
||||
#else
|
||||
|
||||
#define BYTE_TYPE(p) BIG2_BYTE_TYPE(&big2_encoding_ns, p)
|
||||
#define PREFIX(ident) big2_ ## ident
|
||||
#define BYTE_TYPE(p) BIG2_BYTE_TYPE(XmlGetUtf16InternalEncodingNS(), p)
|
||||
#define IS_NAME_CHAR_MINBPC(p) BIG2_IS_NAME_CHAR_MINBPC(0, p)
|
||||
#define IS_NMSTRT_CHAR_MINBPC(p) BIG2_IS_NMSTRT_CHAR_MINBPC(0, p)
|
||||
|
||||
|
@ -151,8 +153,43 @@ int MOZ_XMLIsNCNameChar(const char* ptr)
|
|||
}
|
||||
}
|
||||
|
||||
int MOZ_XMLTranslateEntity(const char* ptr, const char* end, const char** next,
|
||||
XML_Char* result)
|
||||
{
|
||||
const ENCODING* enc = XmlGetUtf16InternalEncodingNS();
|
||||
int tok = PREFIX(scanRef)(enc, ptr, end, next);
|
||||
if (tok <= XML_TOK_INVALID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tok == XML_TOK_CHAR_REF) {
|
||||
int n = XmlCharRefNumber(enc, ptr);
|
||||
|
||||
// We could get away with just < 0, but better safe than sorry.
|
||||
if (n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return XmlUtf16Encode(n, (unsigned short*)result);
|
||||
}
|
||||
|
||||
if (tok == XML_TOK_ENTITY_REF) {
|
||||
// *next points to after the semicolon, so the entity ends at
|
||||
// *next - enc->minBytesPerChar.
|
||||
XML_Char ch =
|
||||
(XML_Char)XmlPredefinedEntityName(enc, ptr, *next - enc->minBytesPerChar);
|
||||
if (!ch) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*result = ch;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef PREFIX
|
||||
#undef BYTE_TYPE
|
||||
#undef IS_NAME_CHAR_MINBPC
|
||||
#undef IS_NMSTRT_CHAR_MINBPC
|
||||
#undef CHECK_NAME_CASES
|
||||
#undef CHECK_NMSTRT_CASES
|
||||
|
|
|
@ -160,6 +160,25 @@ class nsIParserService : public nsISupports {
|
|||
const PRUnichar** aColon) = 0;
|
||||
virtual PRBool IsXMLLetter(PRUnichar aChar) = 0;
|
||||
virtual PRBool IsXMLNCNameChar(PRUnichar aChar) = 0;
|
||||
|
||||
/**
|
||||
* Decodes an entity into a UTF-16 character. If a ; is found between aStart
|
||||
* and aEnd it will try to decode the entity and set aNext to point to the
|
||||
* character after the ;. The resulting UTF-16 character will be written in
|
||||
* aResult, so if the entity is a valid numeric entity there needs to be
|
||||
* space for at least two PRUnichars.
|
||||
*
|
||||
* @param aStart pointer to the character after the ampersand.
|
||||
* @param aEnd pointer to the position after the last character of the
|
||||
* string.
|
||||
* @param aNext [out] will be set to the character after the ; or null if
|
||||
* the decoding was unsuccessful.
|
||||
* @param aResult the buffer to write the resulting UTF-16 character in.
|
||||
* @return the number of PRUnichars written to aResult.
|
||||
*/
|
||||
virtual PRUint32 DecodeEntity(const PRUnichar* aStart, const PRUnichar* aEnd,
|
||||
const PRUnichar** aNext,
|
||||
PRUnichar* aResult) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIParserService, NS_IPARSERSERVICE_IID)
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
|
||||
extern "C" int MOZ_XMLIsLetter(const char* ptr);
|
||||
extern "C" int MOZ_XMLIsNCNameChar(const char* ptr);
|
||||
extern "C" PRBool MOZ_XMLTranslateEntity(const char* ptr, const char* end,
|
||||
const char** next, PRUnichar* result);
|
||||
|
||||
class nsParserService : public nsIParserService {
|
||||
public:
|
||||
|
@ -90,6 +92,15 @@ public:
|
|||
{
|
||||
return MOZ_XMLIsNCNameChar(NS_REINTERPRET_CAST(const char*, &aChar));
|
||||
}
|
||||
PRUint32 DecodeEntity(const PRUnichar* aStart, const PRUnichar* aEnd,
|
||||
const PRUnichar** aNext, PRUnichar* aResult)
|
||||
{
|
||||
*aNext = nsnull;
|
||||
return MOZ_XMLTranslateEntity(NS_REINTERPRET_CAST(const char*, aStart),
|
||||
NS_REINTERPRET_CAST(const char*, aEnd),
|
||||
NS_REINTERPRET_CAST(const char**, aNext),
|
||||
aResult);
|
||||
}
|
||||
|
||||
protected:
|
||||
nsObserverEntry* GetEntry(const nsAString& aTopic);
|
||||
|
|
Загрузка…
Ссылка в новой задаче