Backed out changeset 8fc810b6e528 (bug 1509102) for xpcshell failures from test_serializers_entities.js. CLOSED TREE
authorBrindusan Cristian <cbrindusan@mozilla.com>
Wed, 28 Nov 2018 12:16:26 +0200
changeset 448502 7e8744eac2cae3d8d944a3c103cb63b104fb27ed
parent 448501 834ac503d67e50f15dc1ca15e43cd700c571ba81
child 448503 e375e10f670a4deb1a8971df66633819d2ec14a6
push id35118
push userccoroiu@mozilla.com
push dateWed, 28 Nov 2018 21:49:40 +0000
treeherdermozilla-central@f2915d3ee5f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1509102
milestone65.0a1
backs out8fc810b6e52834f8e87aa1118b56ade43e26d7ba
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 8fc810b6e528 (bug 1509102) for xpcshell failures from test_serializers_entities.js. CLOSED TREE
dom/base/nsHTMLContentSerializer.cpp
dom/base/nsHTMLContentSerializer.h
dom/base/nsXMLContentSerializer.cpp
dom/base/nsXMLContentSerializer.h
dom/base/test/unit/test_serializers_entities.js
dom/base/test/unit/test_serializers_entities_in_attr.js
dom/base/test/unit/xpcshell.ini
--- a/dom/base/nsHTMLContentSerializer.cpp
+++ b/dom/base/nsHTMLContentSerializer.cpp
@@ -444,43 +444,62 @@ static const char* const kEntityStrings[
   /* 0 */ nullptr,
   /* 1 */ "&quot;",
   /* 2 */ "&amp;",
   /* 3 */ "&lt;",
   /* 4 */ "&gt;",
   /* 5 */ "&nbsp;"
 };
 
+uint32_t FindNextBasicEntity(const nsAString& aStr,
+                             const uint32_t aLen,
+                             uint32_t aIndex,
+                             const uint8_t* aEntityTable,
+                             const char** aEntity)
+{
+  for (; aIndex < aLen; ++aIndex) {
+    // for each character in this chunk, check if it
+    // needs to be replaced
+    char16_t val = aStr[aIndex];
+    if (val <= kValNBSP && aEntityTable[val]) {
+      *aEntity = kEntityStrings[aEntityTable[val]];
+      return aIndex;
+    }
+  }
+  return aIndex;
+}
+
 bool
 nsHTMLContentSerializer::AppendAndTranslateEntities(const nsAString& aStr,
-                                                    nsAString& aOutputStr)
+                                                     nsAString& aOutputStr)
 {
   if (mBodyOnly && !mInBody) {
     return true;
   }
 
   if (mDisableEntityEncoding) {
     return aOutputStr.Append(aStr, mozilla::fallible);
   }
 
   if (mFlags & (nsIDocumentEncoder::OutputEncodeBasicEntities)) {
-    // Per the API documentation, encode &nbsp;, &amp;, &lt;, &gt;, and &quot;
-    if (mInAttribute) {
-      return nsXMLContentSerializer::AppendAndTranslateEntities<kValNBSP>(
-        aStr, aOutputStr, kAttrEntities, kEntityStrings);
+    const uint8_t* entityTable = mInAttribute ? kAttrEntities : kEntities;
+    uint32_t start = 0;
+    const uint32_t len = aStr.Length();
+    for (uint32_t i = 0; i < len; ++i) {
+      const char* entity = nullptr;
+      i = FindNextBasicEntity(aStr, len, i, entityTable, &entity);
+      uint32_t normalTextLen = i - start;
+      if (normalTextLen) {
+        NS_ENSURE_TRUE(aOutputStr.Append(Substring(aStr, start, normalTextLen),
+                                         mozilla::fallible), false);
+      }
+      if (entity) {
+        NS_ENSURE_TRUE(aOutputStr.AppendASCII(entity, mozilla::fallible), false);
+        start = i + 1;
+      }
     }
-
-    return nsXMLContentSerializer::AppendAndTranslateEntities<kValNBSP>(
-      aStr, aOutputStr, kEntities, kEntityStrings);
+    return true;
+  } else {
+    NS_ENSURE_TRUE(nsXMLContentSerializer::AppendAndTranslateEntities(aStr, aOutputStr), false);
   }
 
-  // We don't want to call into our superclass 2-arg version of
-  // AppendAndTranslateEntities, because it wants to encode more characters
-  // than we do.  Use our tables, but avoid encoding &nbsp; by passing in a
-  // smaller max index.  This will only encode &amp;, &lt;, &gt;, and &quot;.
-  if (mInAttribute) {
-    return nsXMLContentSerializer::AppendAndTranslateEntities<kGTVal>(
-      aStr, aOutputStr, kAttrEntities, kEntityStrings);
-  }
-
-  return nsXMLContentSerializer::AppendAndTranslateEntities<kGTVal>(
-    aStr, aOutputStr, kEntities, kEntityStrings);
+  return true;
 }
--- a/dom/base/nsHTMLContentSerializer.h
+++ b/dom/base/nsHTMLContentSerializer.h
@@ -42,14 +42,15 @@ class nsHTMLContentSerializer final : pu
                                        const nsAString& aTagNamespaceURI,
                                        nsAtom* aTagName,
                                        int32_t aNamespace,
                                        nsAString& aStr);
 
   MOZ_MUST_USE
   virtual bool AppendAndTranslateEntities(const nsAString& aStr,
                                           nsAString& aOutputStr) override;
+
 };
 
 nsresult
 NS_NewHTMLContentSerializer(nsIContentSerializer** aSerializer);
 
 #endif
--- a/dom/base/nsXMLContentSerializer.cpp
+++ b/dom/base/nsXMLContentSerializer.cpp
@@ -1170,16 +1170,18 @@ nsXMLContentSerializer::AppendToString(c
   if (mBodyOnly && !mInBody) {
     return true;
   }
   mColPos += aStr.Length();
   return aOutputStr.Append(aStr, mozilla::fallible);
 }
 
 
+static const uint16_t kGTVal = 62;
+
 #define _ 0
 
 // This table indexes into kEntityStrings[].
 static const uint8_t kEntities[] = {
   // clang-format off
   _, _, _, _, _, _, _, _, _, _,
   _, _, _, _, _, _, _, _, _, _,
   _, _, _, _, _, _, _, _, _, _,
@@ -1215,55 +1217,41 @@ static const char* const kEntityStrings[
   /* 6 */ "&#xA;",
   /* 7 */ "&#xD;",
 };
 
 bool
 nsXMLContentSerializer::AppendAndTranslateEntities(const nsAString& aStr,
                                                    nsAString& aOutputStr)
 {
-  if (mInAttribute) {
-    return AppendAndTranslateEntities<kGTVal>(aStr, aOutputStr, kAttrEntities,
-                                              kEntityStrings);
-  }
-
-  return AppendAndTranslateEntities<kGTVal>(aStr, aOutputStr, kEntities, kEntityStrings);
-}
-
-/* static */
-bool
-nsXMLContentSerializer::AppendAndTranslateEntities(const nsAString& aStr,
-                                                   nsAString& aOutputStr,
-                                                   const uint8_t aEntityTable[],
-                                                   uint16_t aMaxTableIndex,
-                                                   const char* const aStringTable[])
-{
   nsReadingIterator<char16_t> done_reading;
   aStr.EndReading(done_reading);
 
   // for each chunk of |aString|...
   uint32_t advanceLength = 0;
   nsReadingIterator<char16_t> iter;
 
+  const uint8_t* entityTable = mInAttribute ? kAttrEntities : kEntities;
+
   for (aStr.BeginReading(iter);
        iter != done_reading;
        iter.advance(int32_t(advanceLength))) {
     uint32_t fragmentLength = done_reading - iter;
     const char16_t* c = iter.get();
     const char16_t* fragmentStart = c;
     const char16_t* fragmentEnd = c + fragmentLength;
     const char* entityText = nullptr;
 
     advanceLength = 0;
     // for each character in this chunk, check if it
     // needs to be replaced
     for (; c < fragmentEnd; c++, advanceLength++) {
       char16_t val = *c;
-      if ((val <= aMaxTableIndex) && aEntityTable[val]) {
-        entityText = aStringTable[aEntityTable[val]];
+      if ((val <= kGTVal) && entityTable[val]) {
+        entityText = kEntityStrings[entityTable[val]];
         break;
       }
     }
 
     NS_ENSURE_TRUE(aOutputStr.Append(fragmentStart, advanceLength, mozilla::fallible), false);
     if (entityText) {
       NS_ENSURE_TRUE(AppendASCIItoUTF16(mozilla::MakeStringSpan(entityText),
                                         aOutputStr,
--- a/dom/base/nsXMLContentSerializer.h
+++ b/dom/base/nsXMLContentSerializer.h
@@ -164,65 +164,16 @@ class nsXMLContentSerializer : public ns
    * Appends a string by translating entities
    * It doesn't increment the column position
    */
   MOZ_MUST_USE
   virtual bool AppendAndTranslateEntities(const nsAString& aStr,
                                           nsAString& aOutputStr);
 
   /**
-   * Helper for virtual AppendAndTranslateEntities that does the actualy work.
-   *
-   * Do not call this directly.  Call it via the template helper below.
-   */
-private:
-  MOZ_MUST_USE
-  static bool AppendAndTranslateEntities(const nsAString& aStr,
-                                         nsAString& aOutputStr,
-                                         const uint8_t aEntityTable[],
-                                         uint16_t aMaxTableIndex,
-                                         const char* const aStringTable[]);
-
-protected:
-  /**
-   * Helper for calling AppendAndTranslateEntities in a way that guarantees we
-   * don't mess up our aEntityTable sizing.  This is a bit more complicated than
-   * it could be, becaue sometimes we don't want to use all of aEntityTable, so
-   * we have to allow passing the amount to use independently.  But we can
-   * statically ensure it's not too big.
-   *
-   * The first integer template argument, which callers need to specify
-   * explicitly, is the index of the last entry in aEntityTable that should be
-   * considered for encoding as an entity reference.  The second integer
-   * argument will be deduced from the actual table passed in.
-   *
-   * aEntityTable contains as values indices into aStringTable.  Those represent
-   * the strings that should be used to replace the characters that are used to
-   * index into aEntityTable.  aStringTable[0] should be nullptr, and characters
-   * that do not need replacement should map to 0 in aEntityTable.
-   */
-  template<uint16_t LargestIndex, uint16_t TableLength>
-  MOZ_MUST_USE
-  bool AppendAndTranslateEntities(const nsAString& aStr,
-                                  nsAString& aOutputStr,
-                                  const uint8_t (&aEntityTable)[TableLength],
-                                  const char* const aStringTable[])
-  {
-    static_assert(LargestIndex < TableLength,
-                  "Largest allowed index must be smaller than table length");
-    return AppendAndTranslateEntities(aStr, aOutputStr, aEntityTable,
-                                      LargestIndex, aStringTable);
-  }
-
-  /**
-   * Max index that can be used with some of our entity tables.
-   */
-  static const uint16_t kGTVal = 62;
-
-  /**
    * retrieve the text content of the node and append it to the given string
    * It doesn't increment the column position
    */
   nsresult AppendTextData(nsIContent* aNode,
                           int32_t aStartOffset,
                           int32_t aEndOffset,
                           nsAString& aStr,
                           bool aTranslateEntities);
deleted file mode 100644
--- a/dom/base/test/unit/test_serializers_entities.js
+++ /dev/null
@@ -1,82 +0,0 @@
-const encoders = {
-    xml: (doc) => {
-	let enc = Cu.createDocumentEncoder("text/xml");
-	enc.init(doc, "text/xml", 0);
-	return enc;
-    },
-    html: (doc) => {
-	let enc = Cu.createDocumentEncoder("text/html");
-	enc.init(doc, "text/html", 0);
-	return enc;
-    },
-    htmlBasic: (doc) => {
-	let enc = Cu.createDocumentEncoder("text/html");
-	enc.init(doc, "text/html", Ci.nsIDocumentEncoder.OutputEncodeBasicEntities);
-	return enc;
-    },
-    xhtml: (doc) => {
-	let enc = Cu.createDocumentEncoder("application/xhtml+xml");
-	enc.init(doc, "application/xhtml+xml", 0);
-	return enc;
-    },
-};
-
-// Which characters should we encode as entities?  It depends on the serializer.
-const encodeAll = { html: true, htmlBasic: true, xhtml: true, xml: true };
-const encodeHTMLBasic = { html: false, htmlBasic: true, xhtml: false, xml: false };
-const encodeXML = { html: false, htmlBasic: false, xhtml: true, xml: true };
-const encodeNone = { html: false, htmlBasic: false, xhtml: false, xml: false };
-const encodingInfoMap = new Map([
-    // Basic sanity chars '<', '>', '"', '&' get encoded in all cases.
-    [ '<',  encodeAll ],
-    [ '>',  encodeAll ],
-    [ '&',  encodeAll ],
-    // nbsp is only encoded with the HTML encoder when encoding basic entities.
-    [ '\xA0', encodeHTMLBasic ],
-]);
-
-const encodingMap = new Map([
-    [ '<', '&lt;' ],
-    [ '>', '&gt;' ],
-    [ '&', '&amp;' ],
-    // nbsp is only encoded with the HTML encoder when encoding basic entities.
-    [ '\xA0', '&nbsp;' ],
-]);
-
-function encodingInfoForChar(c) {
-    var info = encodingInfoMap.get(c);
-    if (info) {
-	return info;
-    }
-    return encodeNone;
-}
-
-function encodingForChar(c, type) {
-    var info = encodingInfoForChar(c);
-    if (!info[type]) {
-	return c;
-    }
-    return encodingMap.get(c);
-}
-
-const doc = new DOMParser().parseFromString("<root></root>", "text/xml")
-const root = doc.documentElement;
-for (let i = 0; i < 255; ++i) {
-    let el = doc.createElement("span");
-    el.textContent = String.fromCharCode(i);
-    root.appendChild(el);
-}
-for (let type of ["xml", "xhtml", "htmlBasic", "html"]) {
-    let str = encoders[type](doc).encodeToString();
-    const prefix = "<root><span>";
-    const suffix = "</span></root>";
-    Assert.ok(str.startsWith(prefix), `${type} serialization starts correctly`);
-    Assert.ok(str.endsWith(suffix), `${type} serialization ends correctly`);
-    str = str.substring(prefix.length, str.length - suffix.length);
-    let encodings = str.split("</span><span>");
-    for (let i = 0; i < 255; ++i) {
-	let c = String.fromCharCode(i);
-	Assert.equal(encodingForChar(c, type), encodings[i],
-		     `${type} encoding of char ${i} is correct`);
-    }
-}
deleted file mode 100644
--- a/dom/base/test/unit/test_serializers_entities_in_attr.js
+++ /dev/null
@@ -1,91 +0,0 @@
-const encoders = {
-    xml: (doc) => {
-	let enc = Cu.createDocumentEncoder("text/xml");
-	enc.init(doc, "text/xml", 0);
-	return enc;
-    },
-    html: (doc) => {
-	let enc = Cu.createDocumentEncoder("text/html");
-	enc.init(doc, "text/html", 0);
-	return enc;
-    },
-    htmlBasic: (doc) => {
-	let enc = Cu.createDocumentEncoder("text/html");
-	enc.init(doc, "text/html", Ci.nsIDocumentEncoder.OutputEncodeBasicEntities);
-	return enc;
-    },
-    xhtml: (doc) => {
-	let enc = Cu.createDocumentEncoder("application/xhtml+xml");
-	enc.init(doc, "application/xhtml+xml", 0);
-	return enc;
-    },
-};
-
-// Which characters should we encode as entities?  It depends on the serializer.
-const encodeAll = { html: true, htmlBasic: true, xhtml: true, xml: true };
-const encodeHTMLBasic = { html: false, htmlBasic: true, xhtml: false, xml: false };
-const encodeXML = { html: false, htmlBasic: false, xhtml: true, xml: true };
-const encodeNone = { html: false, htmlBasic: false, xhtml: false, xml: false };
-const encodingInfoMap = new Map([
-    // Basic sanity chars '<', '>', '"', '&' get encoded in all cases.
-    [ '<',  encodeAll ],
-    [ '>',  encodeAll ],
-    [ '"',  encodeAll ],
-    [ '&',  encodeAll ],
-    // nbsp is only encoded with the HTML encoder when encoding basic entities.
-    [ '\xA0', encodeHTMLBasic ],
-    // Whitespace bits are only encoded in XML.
-    [ '\n', encodeXML ],
-    [ '\r', encodeXML ],
-    [ '\t', encodeXML ],
-]);
-
-const encodingMap = new Map([
-    [ '<', '&lt;' ],
-    [ '>', '&gt;' ],
-    [ '"', '&quot;' ],
-    [ '&', '&amp;' ],
-    [ '\xA0', '&nbsp;' ],
-    [ '\n', '&#xA;' ],
-    [ '\r', '&#xD;' ],
-    [ '\t', '&#9;' ],
-]);
-
-function encodingInfoForChar(c) {
-    var info = encodingInfoMap.get(c);
-    if (info) {
-	return info;
-    }
-    return encodeNone;
-}
-
-function encodingForChar(c, type) {
-    var info = encodingInfoForChar(c);
-    if (!info[type]) {
-	return c;
-    }
-    return encodingMap.get(c);
-}
-
-const doc = new DOMParser().parseFromString("<root></root>", "text/xml")
-const root = doc.documentElement;
-for (let i = 0; i < 255; ++i) {
-    let el = doc.createElement("span");
-    el.setAttribute("x", String.fromCharCode(i));
-    el.textContent = " ";
-    root.appendChild(el);
-}
-for (let type of ["xml", "xhtml", "htmlBasic", "html"]) {
-    let str = encoders[type](doc).encodeToString();
-    const prefix = '<root><span x="';
-    const suffix = '"> </span></root>';
-    Assert.ok(str.startsWith(prefix), `${type} serialization starts correctly`);
-    Assert.ok(str.endsWith(suffix), `${type} serialization ends correctly`);
-    str = str.substring(prefix.length, str.length - suffix.length);
-    let encodings = str.split('"> </span><span x="');
-    for (let i = 0; i < 255; ++i) {
-	let c = String.fromCharCode(i);
-	Assert.equal(encodingForChar(c, type), encodings[i],
-		     `${type} encoding of char ${i} is correct`);
-    }
-}
--- a/dom/base/test/unit/xpcshell.ini
+++ b/dom/base/test/unit/xpcshell.ini
@@ -33,18 +33,16 @@ skip-if = os == 'mac'
 [test_isequalnode.js]
 head = head_xml.js
 [test_nodelist.js]
 head = head_xml.js
 [test_normalize.js]
 head = head_xml.js
 [test_range.js]
 head = head_xml.js
-[test_serializers_entities.js]
-[test_serializers_entities_in_attr.js]
 [test_structuredcloneholder.js]
 [test_thirdpartyutil.js]
 [test_treewalker.js]
 head = head_xml.js
 [test_xhr_document.js]
 [test_xhr_standalone.js]
 [test_xhr_origin_attributes.js]
 [test_xml_parser.js]