Reviewed by Antti.
authorantti <antti@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 30 Aug 2007 13:12:46 +0000 (13:12 +0000)
committerantti <antti@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 30 Aug 2007 13:12:46 +0000 (13:12 +0000)
        - fix <rdar://problem/5423270> CrashTracer: [USER] 1 crash in Safari at com.apple.WebCore:
          WebCore::plainTextToMallocAllocatedBuffer + 762

        * editing/TextIterator.cpp: (WebCore::plainTextToMallocAllocatedBuffer):
        Check for a malloc failure and exit the function if it failed.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@25314 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/editing/TextIterator.cpp

index ba9ebc564760fe2c7d01de83461ca87928329978..d8adc6b398d8ed1b9f613aa2ec02b3a9efae8ec4 100644 (file)
@@ -1,3 +1,13 @@
+2007-08-30  Darin Adler  <darin@apple.com>
+
+        Reviewed by Antti.
+        - fix <rdar://problem/5423270> CrashTracer: [USER] 1 crash in Safari at com.apple.WebCore:
+          WebCore::plainTextToMallocAllocatedBuffer + 762
+
+        * editing/TextIterator.cpp: (WebCore::plainTextToMallocAllocatedBuffer):
+        Check for a malloc failure and exit the function if it failed.
+
 2007-08-29  Anders Carlsson  <andersca@apple.com>
 
         Reviewed by Oliver.
index 0231682b2e0acf6b66fab953e278afc5b84b7ca6..b168270fd1a5788e6e8cd7bbc4455a27982b8dc8 100644 (file)
@@ -1240,8 +1240,10 @@ PassRefPtr<Range> TextIterator::rangeFromLocationAndLength(Element *scope, int r
     
 UChar* plainTextToMallocAllocatedBuffer(const Range* r, unsigned& bufferLength) 
 {
+    UChar* result = 0;
+
     // Do this in pieces to avoid massive reallocations if there is a large amount of text.
-    // Use system malloc for buffers since they can consume lots of memory and current TCMalloc is unable return it back to OS
+    // Use system malloc for buffers since they can consume lots of memory and current TCMalloc is unable return it back to OS.
     static const unsigned cMaxSegmentSize = 1 << 16;
     bufferLength = 0;
     Vector<pair<UChar*, unsigned> >* textSegments = 0;
@@ -1249,34 +1251,47 @@ UChar* plainTextToMallocAllocatedBuffer(const Range* r, unsigned& bufferLength)
     textBuffer.reserveCapacity(cMaxSegmentSize);
     for (TextIterator it(r); !it.atEnd(); it.advance()) {
         if (textBuffer.size() && textBuffer.size() + it.length() > cMaxSegmentSize) {
+            UChar* newSegmentBuffer = static_cast<UChar*>(malloc(textBuffer.size() * sizeof(UChar)));
+            if (!newSegmentBuffer)
+                goto exit;
+            memcpy(newSegmentBuffer, textBuffer.data(), textBuffer.size() * sizeof(UChar));
+            pair<UChar*, unsigned> newSegment(newSegmentBuffer, textBuffer.size());
             if (!textSegments)
                 textSegments = new Vector<pair<UChar*, unsigned> >;
-            pair<UChar*, unsigned> newSegment(static_cast<UChar*>(malloc(textBuffer.size() * sizeof(UChar))), textBuffer.size());
-            memcpy(newSegment.first, textBuffer.data(), textBuffer.size() * sizeof(UChar));
             textSegments->append(newSegment);
             textBuffer.clear();
         }
         textBuffer.append(it.characters(), it.length());
         bufferLength += it.length();
     }
-    
+
     if (!bufferLength)
         return 0;
-    
+
     // Since we know the size now, we can make a single buffer out of the pieces with one big alloc
-    UChar* resultBuffer = static_cast<UChar*>(malloc(bufferLength * sizeof(UChar)));
-    UChar* resultPos = resultBuffer;
+    result = static_cast<UChar*>(malloc(bufferLength * sizeof(UChar)));
+    if (!result)
+        goto exit;
+
+    UChar* resultPos = result;
     if (textSegments) {
-        for (unsigned n = 0; n < textSegments->size(); n++) {
-            const pair<UChar*, unsigned>& s = textSegments->at(n);
-            memcpy(resultPos, s.first, s.second * sizeof(UChar));
-            free(s.first);
-            resultPos += s.second;
+        unsigned size = textSegments->size();
+        for (unsigned i = 0; i < size; ++i) {
+            const pair<UChar*, unsigned>& segment = textSegments->at(i);
+            memcpy(resultPos, segment.first, segment.second * sizeof(UChar));
+            resultPos += segment.second;
         }
-        delete textSegments;
     }
     memcpy(resultPos, textBuffer.data(), textBuffer.size() * sizeof(UChar));
-    return resultBuffer;
+
+exit:
+    if (textSegments) {
+        unsigned size = textSegments->size();
+        for (unsigned i = 0; i < size; ++i)
+            free(textSegments->at(i).first);
+        delete textSegments;
+    }
+    return result;
 }
 
 DeprecatedString plainText(const Range* r)