Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: third_party/WebKit/Source/wtf/ArrayBufferBuilder.cpp

Issue 1414553002: Fix out-of-memory crashes related to ArrayBuffer allocation Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 24 matching lines...) Expand all
35 #include <limits> 35 #include <limits>
36 36
37 namespace WTF { 37 namespace WTF {
38 38
39 static const int defaultBufferCapacity = 32768; 39 static const int defaultBufferCapacity = 32768;
40 40
41 ArrayBufferBuilder::ArrayBufferBuilder() 41 ArrayBufferBuilder::ArrayBufferBuilder()
42 : m_bytesUsed(0) 42 : m_bytesUsed(0)
43 , m_variableCapacity(true) 43 , m_variableCapacity(true)
44 { 44 {
45 m_buffer = ArrayBuffer::create(defaultBufferCapacity, 1); 45 m_buffer = ArrayBuffer::createOrNull(defaultBufferCapacity, 1);
46 } 46 }
47 47
48 bool ArrayBufferBuilder::expandCapacity(unsigned sizeToIncrease) 48 bool ArrayBufferBuilder::expandCapacity(unsigned sizeToIncrease)
49 { 49 {
50 unsigned currentBufferSize = m_buffer->byteLength(); 50 unsigned currentBufferSize = m_buffer->byteLength();
51 51
52 // If the size of the buffer exceeds max of unsigned, it can't be grown any 52 // If the size of the buffer exceeds max of unsigned, it can't be grown any
53 // more. 53 // more.
54 if (sizeToIncrease > std::numeric_limits<unsigned>::max() - m_bytesUsed) 54 if (sizeToIncrease > std::numeric_limits<unsigned>::max() - m_bytesUsed)
55 return false; 55 return false;
56 56
57 unsigned newBufferSize = m_bytesUsed + sizeToIncrease; 57 unsigned newBufferSize = m_bytesUsed + sizeToIncrease;
58 58
59 // Grow exponentially if possible. 59 // Grow exponentially if possible.
60 unsigned exponentialGrowthNewBufferSize = std::numeric_limits<unsigned>::max (); 60 unsigned exponentialGrowthNewBufferSize = std::numeric_limits<unsigned>::max ();
61 if (currentBufferSize <= std::numeric_limits<unsigned>::max() / 2) 61 if (currentBufferSize <= std::numeric_limits<unsigned>::max() / 2)
62 exponentialGrowthNewBufferSize = currentBufferSize * 2; 62 exponentialGrowthNewBufferSize = currentBufferSize * 2;
63 if (exponentialGrowthNewBufferSize > newBufferSize) 63 if (exponentialGrowthNewBufferSize > newBufferSize)
64 newBufferSize = exponentialGrowthNewBufferSize; 64 newBufferSize = exponentialGrowthNewBufferSize;
65 65
66 // Copy existing data in current buffer to new buffer. 66 // Copy existing data in current buffer to new buffer.
67 RefPtr<ArrayBuffer> newBuffer = ArrayBuffer::create(newBufferSize, 1); 67 RefPtr<ArrayBuffer> newBuffer = ArrayBuffer::createOrNull(newBufferSize, 1);
68 if (!newBuffer) 68 if (!newBuffer)
69 return false; 69 return false;
70 70
71 memcpy(newBuffer->data(), m_buffer->data(), m_bytesUsed); 71 memcpy(newBuffer->data(), m_buffer->data(), m_bytesUsed);
72 m_buffer = newBuffer; 72 m_buffer = newBuffer;
73 return true; 73 return true;
74 } 74 }
75 75
76 unsigned ArrayBufferBuilder::append(const char* data, unsigned length) 76 unsigned ArrayBufferBuilder::append(const char* data, unsigned length)
77 { 77 {
(...skipping 21 matching lines...) Expand all
99 99
100 return bytesToSave; 100 return bytesToSave;
101 } 101 }
102 102
103 PassRefPtr<ArrayBuffer> ArrayBufferBuilder::toArrayBuffer() 103 PassRefPtr<ArrayBuffer> ArrayBufferBuilder::toArrayBuffer()
104 { 104 {
105 // Fully used. Return m_buffer as-is. 105 // Fully used. Return m_buffer as-is.
106 if (m_buffer->byteLength() == m_bytesUsed) 106 if (m_buffer->byteLength() == m_bytesUsed)
107 return m_buffer; 107 return m_buffer;
108 108
109 return m_buffer->slice(0, m_bytesUsed); 109 RefPtr<ArrayBuffer> tmp = m_buffer->sliceOrNull(0, m_bytesUsed);
110 if (tmp)
111 return tmp;
112 return m_buffer;
110 } 113 }
111 114
112 String ArrayBufferBuilder::toString() 115 String ArrayBufferBuilder::toString()
113 { 116 {
114 return String(static_cast<const char*>(m_buffer->data()), m_bytesUsed); 117 return String(static_cast<const char*>(m_buffer->data()), m_bytesUsed);
115 } 118 }
116 119
117 void ArrayBufferBuilder::shrinkToFit() 120 void ArrayBufferBuilder::shrinkToFit()
118 { 121 {
119 ASSERT(m_bytesUsed <= m_buffer->byteLength()); 122 ASSERT(m_bytesUsed <= m_buffer->byteLength());
120 123
121 if (m_buffer->byteLength() > m_bytesUsed) 124 if (m_buffer->byteLength() > m_bytesUsed) {
122 m_buffer = m_buffer->slice(0, m_bytesUsed); 125 RefPtr<ArrayBuffer> tmp = m_buffer->sliceOrNull(0, m_bytesUsed);
126 if (tmp)
127 m_buffer = tmp;
128 }
123 } 129 }
124 130
125 } // namespace WTF 131 } // namespace WTF
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698