Getting the selector text should properly escape and quote attribute value

strings.  Bug 142648, patch by Daniel Kraft <domob@daniel-kraft.net>, r=dbaron,
sr=bzbarsky.
This commit is contained in:
bzbarsky%mit.edu 2005-01-30 18:01:57 +00:00
Родитель a5149009a6
Коммит 5a9c36b43a
4 изменённых файлов: 64 добавлений и 22 удалений

Просмотреть файл

@ -56,6 +56,7 @@
#include "nsContentCID.h" #include "nsContentCID.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsStyleSet.h" #include "nsStyleSet.h"
#include "nsStyleUtil.h"
static NS_DEFINE_CID(kCSSStyleSheetCID, NS_CSS_STYLESHEET_CID); static NS_DEFINE_CID(kCSSStyleSheetCID, NS_CSS_STYLESHEET_CID);
@ -612,6 +613,8 @@ nsMathMLFrame::MapAttributesIntoCSS(nsPresContext* aPresContext,
aContent->GetAttr(nameSpaceID, attrAtom, attrValue); aContent->GetAttr(nameSpaceID, attrAtom, attrValue);
if (attrValue.IsEmpty()) if (attrValue.IsEmpty())
continue; continue;
nsAutoString escapedAttrValue;
nsStyleUtil::EscapeCSSString(attrValue, escapedAttrValue);
// don't add rules that are already in mathml.css // don't add rules that are already in mathml.css
// (this will also clean up whitespace before units - see bug 125303) // (this will also clean up whitespace before units - see bug 125303)
@ -633,7 +636,7 @@ nsMathMLFrame::MapAttributesIntoCSS(nsPresContext* aPresContext,
// make a style rule that maps to the equivalent CSS property // make a style rule that maps to the equivalent CSS property
nsAutoString cssRule; nsAutoString cssRule;
cssRule.Assign(NS_LITERAL_STRING("[") + attrName + cssRule.Assign(NS_LITERAL_STRING("[") + attrName +
NS_LITERAL_STRING("='") + attrValue + NS_LITERAL_STRING("='") + escapedAttrValue +
NS_LITERAL_STRING("']{") + cssProperty + NS_LITERAL_STRING("}")); NS_LITERAL_STRING("']{") + cssProperty + NS_LITERAL_STRING("}"));
if (!sheet) { if (!sheet) {
@ -657,12 +660,10 @@ nsMathMLFrame::MapAttributesIntoCSS(nsPresContext* aPresContext,
} }
// check for duplicate, if a similar rule is already there, don't bother to add another one // check for duplicate, if a similar rule is already there, don't bother to add another one
// XXX bug 142648 - GetSourceSelectorText is in the format *[color=blue] (i.e., no quotes...)
// XXXrbs need to keep this in sync with the fix for bug 142648
nsAutoString selector; nsAutoString selector;
selector.Assign(NS_LITERAL_STRING("*[") + attrName + selector.Assign(NS_LITERAL_STRING("*[") + attrName +
NS_LITERAL_STRING("=") + attrValue + NS_LITERAL_STRING("=\"") + escapedAttrValue +
NS_LITERAL_STRING("]")); NS_LITERAL_STRING("\"]"));
PRInt32 k, count; PRInt32 k, count;
cssSheet->StyleRuleCount(count); cssSheet->StyleRuleCount(count);
for (k = 0; k < count; ++k) { for (k = 0; k < count; ++k) {

Просмотреть файл

@ -52,6 +52,7 @@
#include "nsCRT.h" #include "nsCRT.h"
#include "nsString.h" #include "nsString.h"
#include "nsStyleConsts.h" #include "nsStyleConsts.h"
#include "nsStyleUtil.h"
#include "nsHTMLAtoms.h" #include "nsHTMLAtoms.h"
#include "nsUnitConversion.h" #include "nsUnitConversion.h"
#include "nsIFontMetrics.h" #include "nsIFontMetrics.h"
@ -69,13 +70,15 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsContentErrors.h" #include "nsContentErrors.h"
/* ************************************************************************** */
// -- nsCSSSelector ------------------------------- // -- nsCSSSelector -------------------------------
#define NS_IF_COPY(dest,source,type) \ #define NS_IF_COPY(dest,source,type) \
if (nsnull != source) dest = new type(*(source)) if (source) dest = new type(*(source))
#define NS_IF_DELETE(ptr) \ #define NS_IF_DELETE(ptr) \
if (nsnull != ptr) { delete ptr; ptr = nsnull; } if (ptr) { delete ptr; ptr = nsnull; }
#define NS_IF_NEGATED_START(bool,str) \ #define NS_IF_NEGATED_START(bool,str) \
if (bool) { str.AppendLiteral(":not("); } if (bool) { str.AppendLiteral(":not("); }
@ -681,27 +684,27 @@ void nsCSSSelector::ToStringInternal(nsAString& aString,
list->mAttr->ToString(temp); list->mAttr->ToString(temp);
aString.Append(temp); aString.Append(temp);
// Append the function // Append the function
if (list->mFunction == NS_ATTR_FUNC_EQUALS) { if (list->mFunction == NS_ATTR_FUNC_INCLUDES)
aString.Append(PRUnichar('='));
} else if (list->mFunction == NS_ATTR_FUNC_INCLUDES) {
aString.Append(PRUnichar('~')); aString.Append(PRUnichar('~'));
aString.Append(PRUnichar('=')); else if (list->mFunction == NS_ATTR_FUNC_DASHMATCH)
} else if (list->mFunction == NS_ATTR_FUNC_DASHMATCH) {
aString.Append(PRUnichar('|')); aString.Append(PRUnichar('|'));
aString.Append(PRUnichar('=')); else if (list->mFunction == NS_ATTR_FUNC_BEGINSMATCH)
} else if (list->mFunction == NS_ATTR_FUNC_BEGINSMATCH) {
aString.Append(PRUnichar('^')); aString.Append(PRUnichar('^'));
aString.Append(PRUnichar('=')); else if (list->mFunction == NS_ATTR_FUNC_ENDSMATCH)
} else if (list->mFunction == NS_ATTR_FUNC_ENDSMATCH) {
aString.Append(PRUnichar('$')); aString.Append(PRUnichar('$'));
aString.Append(PRUnichar('=')); else if (list->mFunction == NS_ATTR_FUNC_CONTAINSMATCH)
} else if (list->mFunction == NS_ATTR_FUNC_CONTAINSMATCH) {
aString.Append(PRUnichar('*')); aString.Append(PRUnichar('*'));
aString.Append(PRUnichar('='));
} aString.Append(PRUnichar('='));
// Append the value // Append the value
aString.Append(list->mValue); nsAutoString escaped;
aString.Append(PRUnichar(']')); nsStyleUtil::EscapeCSSString(list->mValue, escaped);
aString.Append(PRUnichar('\"'));
aString.Append(escaped);
aString.AppendLiteral("\"]");
NS_IF_NEGATED_END(aIsNegated, aString) NS_IF_NEGATED_END(aIsNegated, aString)
list = list->mNext; list = list->mNext;
} }

Просмотреть файл

@ -51,6 +51,7 @@
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsReadableUtils.h" #include "nsReadableUtils.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsTextFormatter.h"
// XXX This is here because nsCachedStyleData is accessed outside of // XXX This is here because nsCachedStyleData is accessed outside of
// the content module; e.g., by nsCSSFrameConstructor. // the content module; e.g., by nsCSSFrameConstructor.
@ -529,3 +530,37 @@ PRBool nsStyleUtil::DashMatchCompare(const nsAString& aAttributeValue,
} }
return result; return result;
} }
void nsStyleUtil::EscapeCSSString(const nsString& aString, nsAString& aReturn)
{
aReturn.Truncate();
const nsString::char_type* in = aString.get();
const nsString::char_type* const end = in + aString.Length();
for (; in != end; in++)
{
if (*in < 0x20)
{
// Escape all characters below 0x20 numerically.
/*
This is the buffer into which snprintf should write. As the hex. value is,
for numbers below 0x20, max. 2 characters long, we don't need more than 5
characters ("\XX "+NUL).
*/
PRUnichar buf[5];
nsTextFormatter::snprintf(buf, NS_ARRAY_LENGTH(buf), NS_LITERAL_STRING("\\%hX ").get(), *in);
aReturn.Append(buf);
} else switch (*in) {
// Special characters which should be escaped: Quotes and backslash
case '\\':
case '\"':
case '\'':
aReturn.Append(PRUnichar('\\'));
// And now, after the eventual escaping character, the actual one.
default:
aReturn.Append(PRUnichar(*in));
}
}
}

Просмотреть файл

@ -75,6 +75,9 @@ public:
static PRBool DashMatchCompare(const nsAString& aAttributeValue, static PRBool DashMatchCompare(const nsAString& aAttributeValue,
const nsAString& aSelectorValue, const nsAString& aSelectorValue,
const nsStringComparator& aComparator); const nsStringComparator& aComparator);
static void EscapeCSSString(const nsString& aString, nsAString& aReturn);
}; };