Loading layout/style/ErrorReporter.cpp +5 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "nsIScriptError.h" #include "nsIServiceManager.h" #include "nsIStringBundle.h" #include "nsStyleUtil.h" #include "nsThreadUtils.h" #ifdef CSS_REPORT_PARSE_ERRORS Loading Loading @@ -252,7 +253,10 @@ ErrorReporter::ReportUnexpected(const char *aMessage, { if (!ShouldReportErrors()) return; const PRUnichar *params[1] = { aParam.get() }; nsAutoString qparam; nsStyleUtil::AppendEscapedCSSIdent(aParam, qparam); const PRUnichar *params[1] = { qparam.get() }; nsAutoString str; sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(), params, ArrayLength(params), Loading layout/style/nsCSSScanner.cpp +46 −27 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <math.h> // must be first due to symbol conflicts #include "nsCSSScanner.h" #include "nsStyleUtil.h" #include "mozilla/css/ErrorReporter.h" #include "mozilla/Likely.h" #include "mozilla/Util.h" Loading Loading @@ -144,64 +145,85 @@ void nsCSSToken::AppendToString(nsString& aBuffer) const { switch (mType) { case eCSSToken_AtKeyword: aBuffer.Append(PRUnichar('@')); // fall through intentional case eCSSToken_Ident: case eCSSToken_WhiteSpace: nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer); break; case eCSSToken_AtKeyword: aBuffer.Append('@'); nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer); break; case eCSSToken_ID: case eCSSToken_Ref: aBuffer.Append('#'); nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer); break; case eCSSToken_Function: case eCSSToken_HTMLComment: case eCSSToken_URange: aBuffer.Append(mIdent); if (mType == eCSSToken_Function) aBuffer.Append(PRUnichar('(')); nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer); aBuffer.Append('('); break; case eCSSToken_URL: case eCSSToken_Bad_URL: aBuffer.AppendLiteral("url("); if (mSymbol != PRUnichar(0)) { aBuffer.Append(mSymbol); } nsStyleUtil::AppendEscapedCSSString(mIdent, aBuffer, mSymbol); } else { aBuffer.Append(mIdent); if (mSymbol != PRUnichar(0)) { aBuffer.Append(mSymbol); } if (mType == eCSSToken_URL) { aBuffer.Append(PRUnichar(')')); } break; case eCSSToken_Number: if (mIntegerValid) { aBuffer.AppendInt(mInteger, 10); } else { } else { aBuffer.AppendFloat(mNumber); } break; case eCSSToken_Percentage: NS_ASSERTION(!mIntegerValid, "How did a percentage token get this set?"); aBuffer.AppendFloat(mNumber * 100.0f); aBuffer.Append(PRUnichar('%')); break; case eCSSToken_Dimension: if (mIntegerValid) { aBuffer.AppendInt(mInteger, 10); } else { } else { aBuffer.AppendFloat(mNumber); } aBuffer.Append(mIdent); nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer); break; case eCSSToken_Bad_String: nsStyleUtil::AppendEscapedCSSString(mIdent, aBuffer, mSymbol); // remove the trailing quote character aBuffer.Truncate(aBuffer.Length() - 1); break; case eCSSToken_String: aBuffer.Append(mSymbol); aBuffer.Append(mIdent); // fall through intentional nsStyleUtil::AppendEscapedCSSString(mIdent, aBuffer, mSymbol); break; case eCSSToken_Symbol: aBuffer.Append(mSymbol); break; case eCSSToken_ID: case eCSSToken_Ref: aBuffer.Append(PRUnichar('#')); case eCSSToken_WhiteSpace: aBuffer.Append(' '); break; case eCSSToken_HTMLComment: case eCSSToken_URange: aBuffer.Append(mIdent); break; case eCSSToken_Includes: aBuffer.AppendLiteral("~="); break; Loading @@ -217,10 +239,7 @@ nsCSSToken::AppendToString(nsString& aBuffer) const case eCSSToken_Containsmatch: aBuffer.AppendLiteral("*="); break; case eCSSToken_Bad_String: aBuffer.Append(mSymbol); aBuffer.Append(mIdent); break; default: NS_ERROR("invalid token type"); break; Loading layout/style/nsRuleNode.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -372,8 +372,9 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue, } switch (aValue.GetUnit()) { case eCSSUnit_EM: { // CSS2.1 specifies that this unit scales to the computed font // size, not the em-width in the font metrics, despite the name. return ScaleCoord(aValue, float(aFontSize)); // XXX scale against font metrics height instead? } case eCSSUnit_XHeight: { nsRefPtr<nsFontMetrics> fm = Loading layout/style/nsStyleUtil.cpp +59 −63 Original line number Diff line number Diff line Loading @@ -55,45 +55,37 @@ bool nsStyleUtil::DashMatchCompare(const nsAString& aAttributeValue, return result; } void nsStyleUtil::AppendEscapedCSSString(const nsString& aString, nsAString& aReturn) void nsStyleUtil::AppendEscapedCSSString(const nsAString& aString, nsAString& aReturn, PRUnichar quoteChar) { aReturn.Append(PRUnichar('"')); 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, ArrayLength(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 '\'': NS_PRECONDITION(quoteChar == '\'' || quoteChar == '"', "CSS strings must be quoted with ' or \""); aReturn.Append(quoteChar); const PRUnichar* in = aString.BeginReading(); const PRUnichar* const end = aString.EndReading(); for (; in != end; in++) { if (*in < 0x20 || (*in >= 0x7F && *in < 0xA0)) { // Escape U+0000 through U+001F and U+007F through U+009F numerically. aReturn.AppendPrintf("\\%hX ", *in); } else { if (*in == '"' || *in == '\'' || *in == '\\') { // Escape backslash and quote characters symbolically. // It's not technically necessary to escape the quote // character that isn't being used to delimit the string, // but we do it anyway because that makes testing simpler. aReturn.Append(PRUnichar('\\')); // And now, after the eventual escaping character, the actual one. default: aReturn.Append(PRUnichar(*in)); } aReturn.Append(*in); } } aReturn.Append(PRUnichar('"')); aReturn.Append(quoteChar); } /* static */ void nsStyleUtil::AppendEscapedCSSIdent(const nsString& aIdent, nsAString& aReturn) nsStyleUtil::AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aReturn) { // The relevant parts of the CSS grammar are: // ident [-]?{nmstart}{nmchar}* Loading @@ -104,44 +96,48 @@ nsStyleUtil::AppendEscapedCSSIdent(const nsString& aIdent, nsAString& aReturn) // unicode \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])? // from http://www.w3.org/TR/CSS21/syndata.html#tokenization const nsString::char_type* in = aIdent.get(); const nsString::char_type* const end = in + aIdent.Length(); const PRUnichar* in = aIdent.BeginReading(); const PRUnichar* const end = aIdent.EndReading(); // Deal with the leading dash separately so we don't need to // unnecessarily escape digits. if (in != end && *in == '-') { if (in == end) return; // A leading dash does not need to be escaped as long as it is not the // *only* character in the identifier. if (in + 1 != end && *in == '-') { aReturn.Append(PRUnichar('-')); ++in; } bool first = true; for (; in != end; ++in, first = false) { if (*in < 0x20 || (first && '0' <= *in && *in <= '9')) { // Escape all characters below 0x20, and digits at the start // (including after a dash), numerically. If we didn't escape // digits numerically, they'd get interpreted as a numeric escape // for the wrong character. /* This is the buffer into which snprintf should write. As the hex. value is, for numbers below 0x7F, max. 2 characters long, we don't need more than 5 characters ("\XX "+NUL). */ PRUnichar buf[5]; nsTextFormatter::snprintf(buf, ArrayLength(buf), NS_LITERAL_STRING("\\%hX ").get(), *in); aReturn.Append(buf); // Escape a digit at the start (including after a dash), // numerically. If we didn't escape it numerically, it would get // interpreted as a numeric escape for the wrong character. // A second dash immediately after a leading dash must also be // escaped, but this may be done symbolically. if (in != end && (*in == '-' || ('0' <= *in && *in <= '9'))) { if (*in == '-') { aReturn.Append(PRUnichar('\\')); aReturn.Append(PRUnichar('-')); } else { aReturn.AppendPrintf("\\%hX ", *in); } ++in; } for (; in != end; ++in) { PRUnichar ch = *in; if (!((ch == PRUnichar('_')) || (PRUnichar('A') <= ch && ch <= PRUnichar('Z')) || (PRUnichar('a') <= ch && ch <= PRUnichar('z')) || PRUnichar(0x80) <= ch || (!first && ch == PRUnichar('-')) || (PRUnichar('0') <= ch && ch <= PRUnichar('9')))) { // Character needs to be escaped if (ch < 0x20 || (0x7F <= ch && ch < 0xA0)) { // Escape U+0000 through U+001F and U+007F through U+009F numerically. aReturn.AppendPrintf("\\%hX ", *in); } else { // Escape ASCII non-identifier printables as a backslash plus // the character. if (ch < 0x7F && ch != '_' && ch != '-' && (ch < '0' || '9' < ch) && (ch < 'A' || 'Z' < ch) && (ch < 'a' || 'z' < ch)) { aReturn.Append(PRUnichar('\\')); } aReturn.Append(ch); Loading layout/style/nsStyleUtil.h +8 −5 Original line number Diff line number Diff line Loading @@ -26,13 +26,16 @@ public: const nsAString& aSelectorValue, const nsStringComparator& aComparator); // Append a quoted (with "") and escaped version of aString to aResult. static void AppendEscapedCSSString(const nsString& aString, nsAString& aResult); // Append a quoted (with 'quoteChar') and escaped version of aString // to aResult. 'quoteChar' must be ' or ". static void AppendEscapedCSSString(const nsAString& aString, nsAString& aResult, PRUnichar quoteChar = '"'); // Append the identifier given by |aIdent| to |aResult|, with // appropriate escaping so that it can be reparsed to the same // identifier. static void AppendEscapedCSSIdent(const nsString& aIdent, static void AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aResult); // Append a bitmask-valued property's value(s) (space-separated) to aResult. Loading Loading
layout/style/ErrorReporter.cpp +5 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "nsIScriptError.h" #include "nsIServiceManager.h" #include "nsIStringBundle.h" #include "nsStyleUtil.h" #include "nsThreadUtils.h" #ifdef CSS_REPORT_PARSE_ERRORS Loading Loading @@ -252,7 +253,10 @@ ErrorReporter::ReportUnexpected(const char *aMessage, { if (!ShouldReportErrors()) return; const PRUnichar *params[1] = { aParam.get() }; nsAutoString qparam; nsStyleUtil::AppendEscapedCSSIdent(aParam, qparam); const PRUnichar *params[1] = { qparam.get() }; nsAutoString str; sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(), params, ArrayLength(params), Loading
layout/style/nsCSSScanner.cpp +46 −27 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <math.h> // must be first due to symbol conflicts #include "nsCSSScanner.h" #include "nsStyleUtil.h" #include "mozilla/css/ErrorReporter.h" #include "mozilla/Likely.h" #include "mozilla/Util.h" Loading Loading @@ -144,64 +145,85 @@ void nsCSSToken::AppendToString(nsString& aBuffer) const { switch (mType) { case eCSSToken_AtKeyword: aBuffer.Append(PRUnichar('@')); // fall through intentional case eCSSToken_Ident: case eCSSToken_WhiteSpace: nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer); break; case eCSSToken_AtKeyword: aBuffer.Append('@'); nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer); break; case eCSSToken_ID: case eCSSToken_Ref: aBuffer.Append('#'); nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer); break; case eCSSToken_Function: case eCSSToken_HTMLComment: case eCSSToken_URange: aBuffer.Append(mIdent); if (mType == eCSSToken_Function) aBuffer.Append(PRUnichar('(')); nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer); aBuffer.Append('('); break; case eCSSToken_URL: case eCSSToken_Bad_URL: aBuffer.AppendLiteral("url("); if (mSymbol != PRUnichar(0)) { aBuffer.Append(mSymbol); } nsStyleUtil::AppendEscapedCSSString(mIdent, aBuffer, mSymbol); } else { aBuffer.Append(mIdent); if (mSymbol != PRUnichar(0)) { aBuffer.Append(mSymbol); } if (mType == eCSSToken_URL) { aBuffer.Append(PRUnichar(')')); } break; case eCSSToken_Number: if (mIntegerValid) { aBuffer.AppendInt(mInteger, 10); } else { } else { aBuffer.AppendFloat(mNumber); } break; case eCSSToken_Percentage: NS_ASSERTION(!mIntegerValid, "How did a percentage token get this set?"); aBuffer.AppendFloat(mNumber * 100.0f); aBuffer.Append(PRUnichar('%')); break; case eCSSToken_Dimension: if (mIntegerValid) { aBuffer.AppendInt(mInteger, 10); } else { } else { aBuffer.AppendFloat(mNumber); } aBuffer.Append(mIdent); nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer); break; case eCSSToken_Bad_String: nsStyleUtil::AppendEscapedCSSString(mIdent, aBuffer, mSymbol); // remove the trailing quote character aBuffer.Truncate(aBuffer.Length() - 1); break; case eCSSToken_String: aBuffer.Append(mSymbol); aBuffer.Append(mIdent); // fall through intentional nsStyleUtil::AppendEscapedCSSString(mIdent, aBuffer, mSymbol); break; case eCSSToken_Symbol: aBuffer.Append(mSymbol); break; case eCSSToken_ID: case eCSSToken_Ref: aBuffer.Append(PRUnichar('#')); case eCSSToken_WhiteSpace: aBuffer.Append(' '); break; case eCSSToken_HTMLComment: case eCSSToken_URange: aBuffer.Append(mIdent); break; case eCSSToken_Includes: aBuffer.AppendLiteral("~="); break; Loading @@ -217,10 +239,7 @@ nsCSSToken::AppendToString(nsString& aBuffer) const case eCSSToken_Containsmatch: aBuffer.AppendLiteral("*="); break; case eCSSToken_Bad_String: aBuffer.Append(mSymbol); aBuffer.Append(mIdent); break; default: NS_ERROR("invalid token type"); break; Loading
layout/style/nsRuleNode.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -372,8 +372,9 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue, } switch (aValue.GetUnit()) { case eCSSUnit_EM: { // CSS2.1 specifies that this unit scales to the computed font // size, not the em-width in the font metrics, despite the name. return ScaleCoord(aValue, float(aFontSize)); // XXX scale against font metrics height instead? } case eCSSUnit_XHeight: { nsRefPtr<nsFontMetrics> fm = Loading
layout/style/nsStyleUtil.cpp +59 −63 Original line number Diff line number Diff line Loading @@ -55,45 +55,37 @@ bool nsStyleUtil::DashMatchCompare(const nsAString& aAttributeValue, return result; } void nsStyleUtil::AppendEscapedCSSString(const nsString& aString, nsAString& aReturn) void nsStyleUtil::AppendEscapedCSSString(const nsAString& aString, nsAString& aReturn, PRUnichar quoteChar) { aReturn.Append(PRUnichar('"')); 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, ArrayLength(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 '\'': NS_PRECONDITION(quoteChar == '\'' || quoteChar == '"', "CSS strings must be quoted with ' or \""); aReturn.Append(quoteChar); const PRUnichar* in = aString.BeginReading(); const PRUnichar* const end = aString.EndReading(); for (; in != end; in++) { if (*in < 0x20 || (*in >= 0x7F && *in < 0xA0)) { // Escape U+0000 through U+001F and U+007F through U+009F numerically. aReturn.AppendPrintf("\\%hX ", *in); } else { if (*in == '"' || *in == '\'' || *in == '\\') { // Escape backslash and quote characters symbolically. // It's not technically necessary to escape the quote // character that isn't being used to delimit the string, // but we do it anyway because that makes testing simpler. aReturn.Append(PRUnichar('\\')); // And now, after the eventual escaping character, the actual one. default: aReturn.Append(PRUnichar(*in)); } aReturn.Append(*in); } } aReturn.Append(PRUnichar('"')); aReturn.Append(quoteChar); } /* static */ void nsStyleUtil::AppendEscapedCSSIdent(const nsString& aIdent, nsAString& aReturn) nsStyleUtil::AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aReturn) { // The relevant parts of the CSS grammar are: // ident [-]?{nmstart}{nmchar}* Loading @@ -104,44 +96,48 @@ nsStyleUtil::AppendEscapedCSSIdent(const nsString& aIdent, nsAString& aReturn) // unicode \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])? // from http://www.w3.org/TR/CSS21/syndata.html#tokenization const nsString::char_type* in = aIdent.get(); const nsString::char_type* const end = in + aIdent.Length(); const PRUnichar* in = aIdent.BeginReading(); const PRUnichar* const end = aIdent.EndReading(); // Deal with the leading dash separately so we don't need to // unnecessarily escape digits. if (in != end && *in == '-') { if (in == end) return; // A leading dash does not need to be escaped as long as it is not the // *only* character in the identifier. if (in + 1 != end && *in == '-') { aReturn.Append(PRUnichar('-')); ++in; } bool first = true; for (; in != end; ++in, first = false) { if (*in < 0x20 || (first && '0' <= *in && *in <= '9')) { // Escape all characters below 0x20, and digits at the start // (including after a dash), numerically. If we didn't escape // digits numerically, they'd get interpreted as a numeric escape // for the wrong character. /* This is the buffer into which snprintf should write. As the hex. value is, for numbers below 0x7F, max. 2 characters long, we don't need more than 5 characters ("\XX "+NUL). */ PRUnichar buf[5]; nsTextFormatter::snprintf(buf, ArrayLength(buf), NS_LITERAL_STRING("\\%hX ").get(), *in); aReturn.Append(buf); // Escape a digit at the start (including after a dash), // numerically. If we didn't escape it numerically, it would get // interpreted as a numeric escape for the wrong character. // A second dash immediately after a leading dash must also be // escaped, but this may be done symbolically. if (in != end && (*in == '-' || ('0' <= *in && *in <= '9'))) { if (*in == '-') { aReturn.Append(PRUnichar('\\')); aReturn.Append(PRUnichar('-')); } else { aReturn.AppendPrintf("\\%hX ", *in); } ++in; } for (; in != end; ++in) { PRUnichar ch = *in; if (!((ch == PRUnichar('_')) || (PRUnichar('A') <= ch && ch <= PRUnichar('Z')) || (PRUnichar('a') <= ch && ch <= PRUnichar('z')) || PRUnichar(0x80) <= ch || (!first && ch == PRUnichar('-')) || (PRUnichar('0') <= ch && ch <= PRUnichar('9')))) { // Character needs to be escaped if (ch < 0x20 || (0x7F <= ch && ch < 0xA0)) { // Escape U+0000 through U+001F and U+007F through U+009F numerically. aReturn.AppendPrintf("\\%hX ", *in); } else { // Escape ASCII non-identifier printables as a backslash plus // the character. if (ch < 0x7F && ch != '_' && ch != '-' && (ch < '0' || '9' < ch) && (ch < 'A' || 'Z' < ch) && (ch < 'a' || 'z' < ch)) { aReturn.Append(PRUnichar('\\')); } aReturn.Append(ch); Loading
layout/style/nsStyleUtil.h +8 −5 Original line number Diff line number Diff line Loading @@ -26,13 +26,16 @@ public: const nsAString& aSelectorValue, const nsStringComparator& aComparator); // Append a quoted (with "") and escaped version of aString to aResult. static void AppendEscapedCSSString(const nsString& aString, nsAString& aResult); // Append a quoted (with 'quoteChar') and escaped version of aString // to aResult. 'quoteChar' must be ' or ". static void AppendEscapedCSSString(const nsAString& aString, nsAString& aResult, PRUnichar quoteChar = '"'); // Append the identifier given by |aIdent| to |aResult|, with // appropriate escaping so that it can be reparsed to the same // identifier. static void AppendEscapedCSSIdent(const nsString& aIdent, static void AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aResult); // Append a bitmask-valued property's value(s) (space-separated) to aResult. Loading