Bug 849688 - Crash with getStartPositionOfChar when argument is out of range. r=dholbert
authorRobert Longson <longsonr@gmail.com>
Wed, 13 Mar 2013 14:22:46 +0000
changeset 124644 bbde2235d308bda9d99cb1da8d8accbca59b214b
parent 124643 b9c6db9049cd9fc49a8b6bde9182e2dace137478
child 124645 80944f3666425d534cb92126d30744bce90feca7
push id24527
push userlongsonr@gmail.com
push dateWed, 13 Mar 2013 14:22:51 +0000
treeherdermozilla-inbound@bbde2235d308 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs849688
milestone22.0a1
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
Bug 849688 - Crash with getStartPositionOfChar when argument is out of range. r=dholbert
layout/svg/crashtests/849688-1.svg
layout/svg/crashtests/849688-2.svg
layout/svg/crashtests/crashtests.list
layout/svg/nsSVGTextFrame2.cpp
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/849688-1.svg
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+
+<text></text>
+
+<script>
+window.addEventListener("load", function() {
+    document.getElementsByTagName('text')[0].getStartPositionOfChar(1);
+}, false);
+</script>
+
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/849688-2.svg
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+
+<text>X</text>
+
+<script>
+window.addEventListener("load", function() {
+    document.getElementsByTagName('text')[0].getStartPositionOfChar(2);
+}, false);
+</script>
+
+</svg>
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -152,8 +152,10 @@ load 789390-1.html
 load 808318-1.svg
 load 813420-1.svg
 load 841163-1.svg
 load 841812-1.svg
 load 842009-1.svg
 load 842909-1.svg
 load 843072-1.svg
 load 847139-1.svg
+load 849688-1.svg
+load 849688-2.svg
--- a/layout/svg/nsSVGTextFrame2.cpp
+++ b/layout/svg/nsSVGTextFrame2.cpp
@@ -3613,21 +3613,16 @@ nsSVGTextFrame2::GetNumberOfChars(nsICon
  * Implements the SVG DOM GetComputedTextLength method for the specified
  * text child element.
  */
 float
 nsSVGTextFrame2::GetComputedTextLength(nsIContent* aContent)
 {
   UpdateGlyphPositioning(false);
 
-  nsIFrame* kid = GetFirstPrincipalChild();
-  if (!kid) {
-    return 0.0f;
-  }
-
   float cssPxPerDevPx = PresContext()->
     AppUnitsToFloatCSSPixels(PresContext()->AppUnitsPerDevPixel());
 
   nscoord length = 0;
   TextRenderedRunIterator it(this, TextRenderedRunIterator::eAllFrames,
                              aContent);
   for (TextRenderedRun run = it.Current(); run.mFrame; run = it.Next()) {
     length += run.GetAdvanceWidth();
@@ -3642,28 +3637,23 @@ nsSVGTextFrame2::GetComputedTextLength(n
  * text content element.
  */
 float
 nsSVGTextFrame2::GetSubStringLength(nsIContent* aContent,
                                     uint32_t charnum, uint32_t nchars)
 {
   UpdateGlyphPositioning(false);
 
-  nsIFrame* kid = GetFirstPrincipalChild();
-  if (!kid) {
-    return 0.0f;
-  }
-
   // Convert charnum/nchars from addressable characters relative to
   // aContent to global character indices.
   CharIterator chit(this, CharIterator::eAddressable, aContent);
   if (!chit.AdvanceToSubtree() ||
+      chit.AtEnd() ||
       !chit.Next(charnum) ||
-      chit.IsAfterSubtree() ||
-      chit.AtEnd()) {
+      chit.IsAfterSubtree()) {
     return 0.0f;
   }
   charnum = chit.TextElementCharIndex();
   chit.NextWithinSubtree(nchars);
   nchars = chit.TextElementCharIndex() - charnum;
 
   // Find each rendered run that intersects with the range defined
   // by charnum/nchars.
@@ -3712,21 +3702,16 @@ nsSVGTextFrame2::GetSubStringLength(nsIC
  * text content element.
  */
 int32_t
 nsSVGTextFrame2::GetCharNumAtPosition(nsIContent* aContent,
                                       mozilla::nsISVGPoint* aPoint)
 {
   UpdateGlyphPositioning(false);
 
-  nsIFrame* kid = GetFirstPrincipalChild();
-  if (!kid) {
-    return 0.0f;
-  }
-
   nsPresContext* context = PresContext();
 
   gfxPoint p(aPoint->X(), aPoint->Y());
 
   int32_t result = -1;
 
   TextRenderedRunIterator it(this, TextRenderedRunIterator::eAllFrames, aContent);
   for (TextRenderedRun run = it.Current(); run.mFrame; run = it.Next()) {
@@ -3752,18 +3737,18 @@ nsresult
 nsSVGTextFrame2::GetStartPositionOfChar(nsIContent* aContent,
                                         uint32_t aCharNum,
                                         mozilla::nsISVGPoint** aResult)
 {
   UpdateGlyphPositioning(false);
 
   CharIterator it(this, CharIterator::eAddressable, aContent);
   if (!it.AdvanceToSubtree() ||
-      !it.Next(aCharNum) ||
-      it.AtEnd()) {
+      it.AtEnd() ||
+      !it.Next(aCharNum)) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   // We need to return the start position of the whole glyph.
   uint32_t startIndex = it.GlyphStartTextElementCharIndex();
 
   NS_ADDREF(*aResult = new DOMSVGPoint(mPositions[startIndex].mPosition));
   return NS_OK;
@@ -3777,18 +3762,18 @@ nsresult
 nsSVGTextFrame2::GetEndPositionOfChar(nsIContent* aContent,
                                       uint32_t aCharNum,
                                       mozilla::nsISVGPoint** aResult)
 {
   UpdateGlyphPositioning(false);
 
   CharIterator it(this, CharIterator::eAddressable, aContent);
   if (!it.AdvanceToSubtree() ||
-      !it.Next(aCharNum) ||
-      it.AtEnd()) {
+      it.AtEnd() ||
+      !it.Next(aCharNum)) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   // We need to return the end position of the whole glyph.
   uint32_t startIndex = it.GlyphStartTextElementCharIndex();
 
   // Get the advance of the glyph.
   gfxFloat advance = it.GetGlyphAdvance(PresContext());
@@ -3815,18 +3800,18 @@ nsresult
 nsSVGTextFrame2::GetExtentOfChar(nsIContent* aContent,
                                  uint32_t aCharNum,
                                  nsIDOMSVGRect** aResult)
 {
   UpdateGlyphPositioning(false);
 
   CharIterator it(this, CharIterator::eAddressable, aContent);
   if (!it.AdvanceToSubtree() ||
-      !it.Next(aCharNum) ||
-      it.AtEnd()) {
+      it.AtEnd() ||
+      !it.Next(aCharNum)) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   nsPresContext* presContext = PresContext();
 
   float cssPxPerDevPx = presContext->
     AppUnitsToFloatCSSPixels(presContext->AppUnitsPerDevPixel());
 
@@ -3867,18 +3852,18 @@ nsresult
 nsSVGTextFrame2::GetRotationOfChar(nsIContent* aContent,
                                    uint32_t aCharNum,
                                    float* aResult)
 {
   UpdateGlyphPositioning(false);
 
   CharIterator it(this, CharIterator::eAddressable, aContent);
   if (!it.AdvanceToSubtree() ||
-      !it.Next(aCharNum) ||
-      it.AtEnd()) {
+      it.AtEnd() ||
+      !it.Next(aCharNum)) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   *aResult = mPositions[it.TextElementCharIndex()].mAngle * 180.0 / M_PI;
   return NS_OK;
 }
 
 //----------------------------------------------------------------------