Bug 1321512 - Fix serialization of font-feature-settings tags to properly escape quote and backslash characters. r=dholbert
authorJonathan Kew <jkew@mozilla.com>
Sat, 03 Dec 2016 10:58:44 +0000
changeset 325206 9ccafe6922c61dd962c4da4f3f1edc7e3ac8746e
parent 325205 523009ae06f6378061f2a9f4429884c33417bb7d
child 325207 612dfd756ef78a09827ad2287d4635b50368ce81
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersdholbert
bugs1321512
milestone53.0a1
Bug 1321512 - Fix serialization of font-feature-settings tags to properly escape quote and backslash characters. r=dholbert
layout/style/nsStyleUtil.cpp
layout/style/nsStyleUtil.h
--- a/layout/style/nsStyleUtil.cpp
+++ b/layout/style/nsStyleUtil.cpp
@@ -11,16 +11,17 @@
 #include "nsContentUtils.h"
 #include "nsRuleNode.h"
 #include "nsROCSSPrimitiveValue.h"
 #include "nsStyleStruct.h"
 #include "nsIContentPolicy.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIURI.h"
 #include "nsPrintfCString.h"
+#include <cctype>
 
 using namespace mozilla;
 
 //------------------------------------------------------------------------------
 // Font Algorithm Code
 //------------------------------------------------------------------------------
 
 // Compare two language strings
@@ -323,36 +324,45 @@ nsStyleUtil::AppendPaintOrderValue(uint8
       default:
         NS_NOTREACHED("unexpected paint-order component value");
     }
     aValue >>= NS_STYLE_PAINT_ORDER_BITWIDTH;
   }
 }
 
 /* static */ void
+nsStyleUtil::AppendFontTagAsString(uint32_t aTag, nsAString& aResult)
+{
+  // A font tag (for feature/variation settings) is a 4-char code interpreted
+  // as a bigendian 32-bit value and stored/processed as a uint32_t.
+  // To serialize it, we put the four bytes (which are all guaranteed to be
+  // printable ASCII values) into a string, starting from the high byte of the
+  // value, then append that to the result with CSS escaping and quotes.
+  nsAutoString tagStr;
+  for (int shiftAmount = 24; shiftAmount >= 0; shiftAmount -= 8) {
+    char c = (aTag >> shiftAmount) & 0xff;
+    MOZ_ASSERT(isascii(c) && isprint(c),
+               "parser should have restricted tag to printable ASCII chars");
+    tagStr.Append(c);
+  }
+  AppendEscapedCSSString(tagStr, aResult);
+}
+
+/* static */ void
 nsStyleUtil::AppendFontFeatureSettings(const nsTArray<gfxFontFeature>& aFeatures,
                                        nsAString& aResult)
 {
   for (uint32_t i = 0, numFeat = aFeatures.Length(); i < numFeat; i++) {
     const gfxFontFeature& feat = aFeatures[i];
 
     if (i != 0) {
         aResult.AppendLiteral(", ");
     }
 
-    // output tag
-    char tag[7];
-    tag[0] = '"';
-    tag[1] = (feat.mTag >> 24) & 0xff;
-    tag[2] = (feat.mTag >> 16) & 0xff;
-    tag[3] = (feat.mTag >> 8) & 0xff;
-    tag[4] = feat.mTag & 0xff;
-    tag[5] = '"';
-    tag[6] = 0;
-    aResult.AppendASCII(tag);
+    AppendFontTagAsString(feat.mTag, aResult);
 
     // output value, if necessary
     if (feat.mValue == 0) {
       // 0 ==> off
       aResult.AppendLiteral(" off");
     } else if (feat.mValue > 1) {
       aResult.Append(' ');
       aResult.AppendInt(feat.mValue);
--- a/layout/style/nsStyleUtil.h
+++ b/layout/style/nsStyleUtil.h
@@ -58,16 +58,18 @@ public:
                                     int32_t aFirstMask,
                                     int32_t aLastMask,
                                     nsAString& aResult);
 
   static void AppendAngleValue(const nsStyleCoord& aValue, nsAString& aResult);
 
   static void AppendPaintOrderValue(uint8_t aValue, nsAString& aResult);
 
+  static void AppendFontTagAsString(uint32_t aTag, nsAString& aResult);
+
   static void AppendFontFeatureSettings(const nsTArray<gfxFontFeature>& aFeatures,
                                         nsAString& aResult);
 
   static void AppendFontFeatureSettings(const nsCSSValue& src,
                                         nsAString& aResult);
 
   static void AppendUnicodeRange(const nsCSSValue& aValue, nsAString& aResult);