Changeset 286171 in webkit
- Timestamp:
- Nov 25, 2021, 9:04:29 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Headers.cmake (modified) (1 diff)
-
Source/WebCore/WebCore.xcodeproj/project.pbxproj (modified) (4 diffs)
-
Source/WebCore/platform/SharedBuffer.cpp (modified) (3 diffs)
-
Source/WebCore/platform/SharedBuffer.h (modified) (2 diffs)
-
Source/WebCore/platform/SharedBufferChunkReader.cpp (modified) (6 diffs)
-
Source/WebCore/platform/SharedBufferChunkReader.h (modified) (4 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp (modified) (2 diffs)
-
Tools/TestWebKitAPI/Tests/WebCore/SharedBufferTest.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r286169 r286171 1 2021-11-25 Jean-Yves Avenard <jya@apple.com> 2 3 Avoid flattening a SharedBuffer when reading reading it through SharedBufferChunkReader. 4 https://bugs.webkit.org/show_bug.cgi?id=233481 5 rdar://problem/85733358 6 7 Reviewed by Cameron McCormack 8 9 SharedBufferChunkReader required the SharedBuffer to be flattened which 10 would mutate the underlying SharedBuffer. 11 The peek method was also incorrect if the data read overlapped multiple 12 segments (it would return too many characters) and some members were used 13 without being initialised. 14 15 Additionally, add a similar read method in SharedBuffer that will be used 16 in bug 233030. 17 18 Covered in existing tests, API tests added. 19 20 * Headers.cmake: 21 * WebCore.xcodeproj/project.pbxproj: 22 * platform/SharedBuffer.cpp: 23 (WebCore::SharedBuffer::getSomeData const): 24 (WebCore::SharedBuffer::getSegmentForPosition const): 25 (WebCore::SharedBuffer::read const): 26 * platform/SharedBuffer.h: 27 * platform/SharedBufferChunkReader.cpp: 28 (WebCore::SharedBufferChunkReader::SharedBufferChunkReader): 29 (WebCore::SharedBufferChunkReader::nextChunk): 30 (WebCore::SharedBufferChunkReader::peek): 31 * platform/SharedBufferChunkReader.h: 32 1 33 2021-11-25 Antti Koivisto <antti@apple.com> 2 34 -
trunk/Source/WebCore/Headers.cmake
r286019 r286171 1172 1172 platform/SerializedPlatformDataCueValue.h 1173 1173 platform/SharedBuffer.h 1174 platform/SharedBufferChunkReader.h 1174 1175 platform/SharedStringHash.h 1175 1176 platform/SleepDisabler.h -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r286167 r286171 489 489 1A4A2DF00A1B852A00C807F8 /* JSHTMLAnchorElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A4A2DEC0A1B852A00C807F8 /* JSHTMLAnchorElement.h */; }; 490 490 1A4A954E0B4EDCCB002D8C3C /* SharedBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A4A954C0B4EDCCB002D8C3C /* SharedBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; }; 491 51FA2EDF27506FDE0011C15D /* SharedBufferChunkReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FA2ED6274F78370011C15D /* SharedBufferChunkReader.h */; settings = {ATTRIBUTES = (Private, ); }; }; 491 492 1A4DA4221CDD3A8300F4473C /* LinkIconCollector.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A4DA4201CDD3A8300F4473C /* LinkIconCollector.h */; settings = {ATTRIBUTES = (Private, ); }; }; 492 493 1A569D120D7E2B82007C3983 /* objc_class.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A569CE30D7E2B82007C3983 /* objc_class.h */; }; … … 9607 9608 51F886BE1F32920700C193EF /* JSNavigatorServiceWorker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNavigatorServiceWorker.cpp; sourceTree = "<group>"; }; 9608 9609 51F886BF1F32920700C193EF /* JSNavigatorServiceWorker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNavigatorServiceWorker.h; sourceTree = "<group>"; }; 9610 51FA2ED6274F78370011C15D /* SharedBufferChunkReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedBufferChunkReader.h; sourceTree = "<group>"; }; 9611 51FA2ED7274F78370011C15D /* SharedBufferChunkReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedBufferChunkReader.cpp; sourceTree = "<group>"; }; 9609 9612 51FB5502113E3E9100821176 /* JSCloseEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCloseEvent.h; sourceTree = "<group>"; }; 9610 9613 51FB5503113E3E9100821176 /* JSCloseEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCloseEvent.cpp; sourceTree = "<group>"; }; … … 29214 29217 1A4A954B0B4EDCCB002D8C3C /* SharedBuffer.cpp */, 29215 29218 1A4A954C0B4EDCCB002D8C3C /* SharedBuffer.h */, 29219 51FA2ED7274F78370011C15D /* SharedBufferChunkReader.cpp */, 29220 51FA2ED6274F78370011C15D /* SharedBufferChunkReader.h */, 29216 29221 834DFACE1F7DAE5700C2725B /* SharedStringHash.cpp */, 29217 29222 834DFACC1F7DAE5600C2725B /* SharedStringHash.h */, … … 36223 36228 1D9F0FC12122029B005D8FD4 /* ShareData.h in Headers */, 36224 36229 1A4A954E0B4EDCCB002D8C3C /* SharedBuffer.h in Headers */, 36230 51FA2EDF27506FDE0011C15D /* SharedBufferChunkReader.h in Headers */, 36225 36231 510A91DC24CF46FE00BFD89C /* SharedGamepadValue.h in Headers */, 36226 36232 CD36C16B260A65CC00C8C529 /* SharedRoutingArbitrator.h in Headers */, -
trunk/Source/WebCore/platform/SharedBuffer.cpp
r285069 r286171 157 157 SharedBufferDataView SharedBuffer::getSomeData(size_t position) const 158 158 { 159 const DataSegmentVectorEntry* element = getSegmentForPosition(position); 160 return { element->segment.copyRef(), position - element->beginPosition }; 161 } 162 163 const SharedBuffer::DataSegmentVectorEntry* SharedBuffer::getSegmentForPosition(size_t position) const 164 { 159 165 RELEASE_ASSERT(position < m_size); 160 166 auto comparator = [](const size_t& position, const DataSegmentVectorEntry& entry) { … … 163 169 const DataSegmentVectorEntry* element = std::upper_bound(m_segments.begin(), m_segments.end(), position, comparator); 164 170 element--; // std::upper_bound gives a pointer to the element that is greater than position. We want the element just before that. 165 return { element->segment.copyRef(), position - element->beginPosition };171 return element; 166 172 } 167 173 … … 276 282 } 277 283 return false; 284 } 285 286 Vector<uint8_t> SharedBuffer::read(size_t offset, size_t length) const 287 { 288 Vector<uint8_t> data; 289 if (offset >= size()) 290 return data; 291 auto remaining = std::min(length, size() - offset); 292 if (!remaining) 293 return data; 294 295 data.reserveInitialCapacity(remaining); 296 auto* currentSegment = getSegmentForPosition(offset); 297 size_t offsetInSegment = offset - currentSegment->beginPosition; 298 size_t availableInSegment = std::min(currentSegment->segment->size() - offsetInSegment, remaining); 299 data.append(currentSegment->segment->data() + offsetInSegment, availableInSegment); 300 301 remaining -= availableInSegment; 302 303 auto* afterLastSegment = end(); 304 305 while (remaining && ++currentSegment != afterLastSegment) { 306 size_t lengthInSegment = std::min(currentSegment->segment->size(), remaining); 307 data.append(currentSegment->segment->data(), lengthInSegment); 308 remaining -= lengthInSegment; 309 } 310 return data; 278 311 } 279 312 -
trunk/Source/WebCore/platform/SharedBuffer.h
r285069 r286171 103 103 const char* dataAsCharPtr() const { return reinterpret_cast<const char*>(data()); } 104 104 Vector<uint8_t> copyData() const; 105 Vector<uint8_t> read(size_t offset, size_t length) const; 105 106 106 107 // Similar to copyData() but avoids copying and will take the data instead when it is safe (The SharedBuffer is not shared). … … 245 246 // Combines all the segments into a Vector and returns that vector after clearing the SharedBuffer. 246 247 Vector<uint8_t> takeData(); 247 248 249 const DataSegmentVectorEntry* getSegmentForPosition(size_t positition) const; 250 248 251 static RefPtr<SharedBuffer> createFromReadingFile(const String& filePath); 249 252 -
trunk/Source/WebCore/platform/SharedBufferChunkReader.cpp
r278516 r286171 1 1 /* 2 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2021 Apple Inc. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 32 33 #include "SharedBufferChunkReader.h" 33 34 35 namespace WebCore { 36 34 37 #if ENABLE(MHTML) 35 38 36 // FIXME: This class is overkill. Remove this class and just iterate the segments of a SharedBuffer37 // using the cool new SharedBuffer::begin() and SharedBuffer::end() instead of using this class.38 39 #include "SharedBuffer.h"40 41 namespace WebCore {42 43 39 SharedBufferChunkReader::SharedBufferChunkReader(SharedBuffer* buffer, const Vector<char>& separator) 44 : m_buffer(buffer) 40 : m_iteratorCurrent(buffer->begin()) 41 , m_iteratorEnd(buffer->end()) 42 , m_segment(m_iteratorCurrent != m_iteratorEnd ? m_iteratorCurrent->segment->data() : nullptr) 45 43 , m_separator(separator) 46 44 { … … 48 46 49 47 SharedBufferChunkReader::SharedBufferChunkReader(SharedBuffer* buffer, const char* separator) 50 : m_buffer(buffer) 48 : m_iteratorCurrent(buffer->begin()) 49 , m_iteratorEnd(buffer->end()) 50 , m_segment(m_iteratorCurrent != m_iteratorEnd ? m_iteratorCurrent->segment->data() : nullptr) 51 51 { 52 52 setSeparator(separator); … … 66 66 bool SharedBufferChunkReader::nextChunk(Vector<uint8_t>& chunk, bool includeSeparator) 67 67 { 68 if (m_ reachedEndOfFile)68 if (m_iteratorCurrent == m_iteratorEnd) 69 69 return false; 70 70 71 71 chunk.clear(); 72 72 while (true) { 73 while (m_segmentIndex < m_segmentLength) { 73 while (m_segmentIndex < m_iteratorCurrent->segment->size()) { 74 // FIXME: The existing code to check for separators doesn't work correctly with arbitrary separator strings. 74 75 auto currentCharacter = m_segment[m_segmentIndex++]; 75 76 if (currentCharacter != m_separator[m_separatorIndex]) { … … 93 94 // Read the next segment. 94 95 m_segmentIndex = 0; 95 m_bufferPosition += m_segmentLength; 96 // Let's pretend all the data is in one block. 97 // FIXME: This class should be removed in favor of just iterating the segments of the SharedBuffer. 98 m_segment = m_buffer->data() + m_bufferPosition; 99 m_segmentLength = m_buffer->size() - m_bufferPosition; 100 if (!m_segmentLength) { 101 m_reachedEndOfFile = true; 96 if (++m_iteratorCurrent == m_iteratorEnd) { 97 m_segment = nullptr; 102 98 if (m_separatorIndex > 0) 103 99 chunk.append(reinterpret_cast<const uint8_t*>(m_separator.data()), m_separatorIndex); 104 100 return !chunk.isEmpty(); 105 101 } 102 m_segment = m_iteratorCurrent->segment->data(); 106 103 } 104 107 105 ASSERT_NOT_REACHED(); 108 106 return false; … … 121 119 { 122 120 data.clear(); 123 if (requestedSize <= m_segmentLength - m_segmentIndex) { 124 data.append(m_segment + m_segmentIndex, requestedSize); 125 return requestedSize; 126 } 121 if (m_iteratorCurrent == m_iteratorEnd) 122 return 0; 127 123 128 size_t readBytesCount = m_segmentLength - m_segmentIndex;129 data.append(m_segment + m_segmentIndex, readBytesCount);124 size_t availableInSegment = std::min(m_iteratorCurrent->segment->size() - m_segmentIndex, requestedSize); 125 data.append(m_segment + m_segmentIndex, availableInSegment); 130 126 131 size_t bufferPosition = m_bufferPosition + m_segmentLength;132 const uint8_t* segment = nullptr;127 size_t readBytesCount = availableInSegment; 128 requestedSize -= readBytesCount; 133 129 134 // Let's pretend all the data is in one block. 135 // FIXME: This class should be removed in favor of just iterating the segments of the SharedBuffer. 136 if (bufferPosition != m_buffer->size()) { 137 segment = m_buffer->data() + bufferPosition; 138 size_t segmentLength = m_buffer->size() - bufferPosition; 139 if (segmentLength > requestedSize) 140 segmentLength = requestedSize; 141 data.append(segment, segmentLength); 142 readBytesCount += segmentLength; 143 bufferPosition += segmentLength; 130 auto currentSegment = m_iteratorCurrent; 131 132 while (requestedSize && ++currentSegment != m_iteratorEnd) { 133 const uint8_t* segment = currentSegment->segment->data(); 134 size_t lengthInSegment = std::min(currentSegment->segment->size(), requestedSize); 135 data.append(segment, lengthInSegment); 136 readBytesCount += lengthInSegment; 137 requestedSize -= lengthInSegment; 144 138 } 145 139 return readBytesCount; 146 140 } 147 141 142 #endif 143 148 144 } 149 145 150 #endif -
trunk/Source/WebCore/platform/SharedBufferChunkReader.h
r278516 r286171 1 1 /* 2 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2021 Apple Inc. All rights reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 33 34 #if ENABLE(MHTML) 34 35 36 #include "SharedBuffer.h" 35 37 #include <wtf/Vector.h> 36 38 #include <wtf/text/WTFString.h> … … 38 40 namespace WebCore { 39 41 40 class SharedBuffer; 41 42 class SharedBufferChunkReader { 42 class WEBCORE_EXPORT SharedBufferChunkReader { 43 43 public: 44 44 SharedBufferChunkReader(SharedBuffer*, const Vector<char>& separator); … … 59 59 60 60 private: 61 SharedBuffer * m_buffer;62 size_t m_bufferPosition { 0 };61 SharedBuffer::DataSegmentVector::const_iterator m_iteratorCurrent; 62 const SharedBuffer::DataSegmentVector::const_iterator m_iteratorEnd; 63 63 const uint8_t* m_segment { nullptr }; 64 size_t m_segmentLength { 0 };65 64 size_t m_segmentIndex { 0 }; 66 bool m_reachedEndOfFile;67 65 Vector<char> m_separator { false }; 68 66 size_t m_separatorIndex { 0 }; -
trunk/Tools/ChangeLog
r286170 r286171 1 2021-11-25 Jean-Yves Avenard <jya@apple.com> 2 3 Avoid flattening a SharedBuffer when reading reading it through SharedBufferChunkReader. 4 https://bugs.webkit.org/show_bug.cgi?id=233481 5 rdar://problem/85733358 6 7 Reviewed by Cameron McCormack. 8 9 Add API tests. 10 API tests original data come from the original bug that added 11 SharedBufferChunkReader (bug 59946) and then expanded. 12 13 * TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp: 14 (TestWebKitAPI::TEST_F): 15 (TestWebKitAPI::readAllChunks): 16 (TestWebKitAPI::checkChunks): 17 (TestWebKitAPI::checkDataInRange): 18 * TestWebKitAPI/Tests/WebCore/SharedBufferTest.h: 19 1 20 2021-11-25 Lauro Moura <lmoura@igalia.com> 2 21 -
trunk/Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp
r283851 r286171 32 32 #include <JavaScriptCore/ArrayBuffer.h> 33 33 #include <WebCore/SharedBuffer.h> 34 #if ENABLE(MHTML) 35 #include <WebCore/SharedBufferChunkReader.h> 36 #endif 34 37 #include <wtf/MainThread.h> 35 38 #include <wtf/StringExtras.h> … … 230 233 } 231 234 232 } 235 TEST_F(SharedBufferTest, read) 236 { 237 const char* const simpleText = "This is a simple test."; 238 239 auto check = [](SharedBuffer& sharedBuffer) { 240 Vector<uint8_t> data = sharedBuffer.read(4, 3); 241 EXPECT_EQ(data.size(), 3u); 242 EXPECT_EQ(String(data.data(), 3), " is"); 243 244 data = sharedBuffer.read(4, 1000); 245 EXPECT_EQ(data.size(), 18u); 246 247 EXPECT_EQ(String(data.data(), 18), " is a simple test."); 248 }; 249 auto sharedBuffer = SharedBuffer::create(simpleText, strlen(simpleText)); 250 check(sharedBuffer); 251 252 sharedBuffer = SharedBuffer::create(); 253 for (size_t i = 0; i < strlen(simpleText); i++) 254 sharedBuffer->append(&simpleText[i], 1); 255 check(sharedBuffer); 256 257 sharedBuffer = SharedBuffer::create(); 258 for (size_t i = 0; i < strlen(simpleText); i += 2) 259 sharedBuffer->append(&simpleText[i], 2); 260 EXPECT_EQ(sharedBuffer->size(), strlen(simpleText)); 261 check(sharedBuffer); 262 } 263 264 #if ENABLE(MHTML) 265 // SharedBufferChunkReader unit-tests ------------------------------------- 266 template< typename T, size_t N > 267 constexpr size_t arraysize( const T (&)[N] ) { return N; } 268 269 static void readAllChunks(std::vector<String>* chunks, SharedBuffer& buffer, const String& separator = "\r\n", bool includeSeparator = false) 270 { 271 SharedBufferChunkReader chunkReader(&buffer, separator.utf8().data()); 272 String chunk = chunkReader.nextChunkAsUTF8StringWithLatin1Fallback(includeSeparator); 273 while (!chunk.isNull()) { 274 chunks->push_back(chunk); 275 chunk = chunkReader.nextChunkAsUTF8StringWithLatin1Fallback(includeSeparator); 276 } 277 } 278 279 static bool checkChunks(const std::vector<String>& chunks, const char* const expectedChunks[], size_t expectedSize) 280 { 281 if (chunks.size() != expectedSize) { 282 EXPECT_EQ(chunks.size(), expectedSize); 283 return false; 284 } 285 286 for (size_t i = 0; i < chunks.size(); ++i) { 287 if (chunks[i] != expectedChunks[i]) 288 return false; 289 } 290 return true; 291 } 292 293 static void checkDataInRange(const Vector<uint8_t>& data, size_t start, size_t length) 294 { 295 ASSERT_EQ(data.size(), length); 296 for (size_t i = 0; i < length; ++i) 297 ASSERT_EQ(data[i], static_cast<uint8_t>(start + i)); 298 } 299 300 TEST_F(SharedBufferChunkReaderTest, includeSeparator) 301 { 302 auto check = [](SharedBuffer& sharedBuffer) { 303 SharedBufferChunkReader chunkReader(&sharedBuffer, "\x10\x11\x12"); 304 Vector<uint8_t> out; 305 EXPECT_TRUE(chunkReader.nextChunk(out)); 306 checkDataInRange(out, 0, 16); 307 308 EXPECT_TRUE(chunkReader.nextChunk(out)); 309 checkDataInRange(out, 19, 237); 310 311 EXPECT_FALSE(chunkReader.nextChunk(out)); 312 }; 313 uint8_t data[256]; 314 for (size_t i = 0; i < 256; ++i) 315 data[i] = i; 316 317 auto sharedBuffer = SharedBuffer::create(data, 256); 318 check(sharedBuffer); 319 sharedBuffer = SharedBuffer::create(); 320 for (size_t i = 0; i < 256; ++i) { 321 char c = i; 322 sharedBuffer->append(&c, 1); 323 } 324 check(sharedBuffer); 325 } 326 327 TEST_F(SharedBufferChunkReaderTest, peekData) 328 { 329 const char* const simpleText = "This is a simple test."; 330 331 auto check = [](SharedBuffer& sharedBuffer) { 332 SharedBufferChunkReader chunkReader(&sharedBuffer, "is"); 333 334 String chunk = chunkReader.nextChunkAsUTF8StringWithLatin1Fallback(); 335 EXPECT_EQ(chunk, "Th"); 336 337 Vector<uint8_t> data; 338 size_t read = chunkReader.peek(data, 3); 339 EXPECT_EQ(read, 3u); 340 341 EXPECT_EQ(String(data.data(), 3), " is"); 342 343 read = chunkReader.peek(data, 1000); 344 EXPECT_EQ(read, 18u); 345 346 EXPECT_EQ(String(data.data(), 18), " is a simple test."); 347 348 // Ensure the cursor has not changed. 349 chunk = chunkReader.nextChunkAsUTF8StringWithLatin1Fallback(); 350 EXPECT_EQ(chunk, " "); 351 352 chunk = chunkReader.nextChunkAsUTF8StringWithLatin1Fallback(); 353 EXPECT_EQ(chunk, " a simple test."); 354 355 chunk = chunkReader.nextChunkAsUTF8StringWithLatin1Fallback(); 356 EXPECT_TRUE(chunk.isNull()); 357 }; 358 auto sharedBuffer = SharedBuffer::create(simpleText, strlen(simpleText)); 359 check(sharedBuffer); 360 361 sharedBuffer = SharedBuffer::create(); 362 for (size_t i = 0; i < strlen(simpleText); i++) 363 sharedBuffer->append(&simpleText[i], 1); 364 check(sharedBuffer); 365 366 sharedBuffer = SharedBuffer::create(); 367 for (size_t i = 0; i < strlen(simpleText); i += 2) 368 sharedBuffer->append(&simpleText[i], 2); 369 EXPECT_EQ(sharedBuffer->size(), strlen(simpleText)); 370 check(sharedBuffer); 371 } 372 373 TEST_F(SharedBufferChunkReaderTest, readAllChunksInMultiSegment) 374 { 375 const char* const simpleText = "This is the most ridiculous history there is."; 376 auto check = [](SharedBuffer& sharedBuffer) { 377 std::vector<String> chunks; 378 const char* const expectedChunks1WithoutSeparator[] = { "Th", "s ", "s the most r", "d", "culous h", "story there ", "s." }; 379 readAllChunks(&chunks, sharedBuffer, "i"); 380 EXPECT_TRUE(checkChunks(chunks, expectedChunks1WithoutSeparator, arraysize(expectedChunks1WithoutSeparator))); 381 382 chunks.clear(); 383 const char* const expectedChunks1WithSeparator[] = { "Thi", "s i", "s the most ri", "di", "culous hi", "story there i", "s." }; 384 readAllChunks(&chunks, sharedBuffer, "i", true); 385 EXPECT_TRUE(checkChunks(chunks, expectedChunks1WithSeparator, arraysize(expectedChunks1WithSeparator))); 386 387 chunks.clear(); 388 const char* const expectedChunks2WithoutSeparator[] = { "Th", " ", " the most ridiculous h", "tory there ", "." }; 389 readAllChunks(&chunks, sharedBuffer, "is"); 390 EXPECT_TRUE(checkChunks(chunks, expectedChunks2WithoutSeparator, arraysize(expectedChunks2WithoutSeparator))); 391 392 chunks.clear(); 393 const char* const expectedChunks2WithSeparator[] = { "This", " is", " the most ridiculous his", "tory there is", "." }; 394 readAllChunks(&chunks, sharedBuffer, "is", true); 395 EXPECT_TRUE(checkChunks(chunks, expectedChunks2WithSeparator, arraysize(expectedChunks2WithSeparator))); 396 397 chunks.clear(); 398 const char* const expectedChunks3WithoutSeparator[] = { "This is the most ridiculous h", "ory there is." }; 399 readAllChunks(&chunks, sharedBuffer, "ist"); 400 EXPECT_TRUE(checkChunks(chunks, expectedChunks3WithoutSeparator, arraysize(expectedChunks3WithoutSeparator))); 401 402 chunks.clear(); 403 const char* const expectedChunks3WithSeparator[] = { "This is the most ridiculous hist", "ory there is." }; 404 readAllChunks(&chunks, sharedBuffer, "ist", true); 405 EXPECT_TRUE(checkChunks(chunks, expectedChunks3WithSeparator, arraysize(expectedChunks3WithSeparator))); 406 }; 407 auto sharedBuffer = SharedBuffer::create(simpleText, strlen(simpleText)); 408 check(sharedBuffer); 409 sharedBuffer = SharedBuffer::create(); 410 for (size_t i = 0; i < strlen(simpleText); i++) 411 sharedBuffer->append(&simpleText[i], 1); 412 EXPECT_EQ(sharedBuffer->size(), strlen(simpleText)); 413 check(sharedBuffer); 414 415 sharedBuffer = SharedBuffer::create(); 416 for (size_t i = 0; i < strlen(simpleText); i += 5) 417 sharedBuffer->append(&simpleText[i], 5); 418 EXPECT_EQ(sharedBuffer->size(), strlen(simpleText)); 419 check(sharedBuffer); 420 } 421 422 TEST_F(SharedBufferChunkReaderTest, changingIterator) 423 { 424 { 425 const char* const simpleText = "This is the most ridiculous history there is."; 426 auto sharedBuffer = SharedBuffer::create(simpleText, strlen(simpleText)); 427 SharedBufferChunkReader chunkReader(sharedBuffer.ptr(), "is"); 428 String chunk = chunkReader.nextChunkAsUTF8StringWithLatin1Fallback(); 429 EXPECT_EQ(chunk, "Th"); 430 431 chunk = chunkReader.nextChunkAsUTF8StringWithLatin1Fallback(); 432 EXPECT_EQ(chunk, " "); 433 434 chunkReader.setSeparator("he"); 435 chunk = chunkReader.nextChunkAsUTF8StringWithLatin1Fallback(); 436 EXPECT_EQ(chunk, " t"); 437 438 chunk = chunkReader.nextChunkAsUTF8StringWithLatin1Fallback(); 439 EXPECT_EQ(chunk, " most ridiculous history t"); 440 441 // Set a non existing separator. 442 chunkReader.setSeparator("tchinta"); 443 chunk = chunkReader.nextChunkAsUTF8StringWithLatin1Fallback(); 444 EXPECT_EQ(chunk, "re is."); 445 446 // We should be at the end of the string, so any subsequent call to nextChunk should return null. 447 chunkReader.setSeparator("."); 448 chunk = chunkReader.nextChunkAsUTF8StringWithLatin1Fallback(true); 449 EXPECT_TRUE(chunk.isNull()); 450 } 451 452 { 453 const char* const simpleText = "dog"; 454 auto sharedBuffer = SharedBuffer::create(simpleText, strlen(simpleText)); 455 const char* const expectedChunksWithoutSeparator[] = { "" }; 456 std::vector<String> chunks; 457 readAllChunks(&chunks, sharedBuffer, "dog"); 458 EXPECT_TRUE(checkChunks(chunks, expectedChunksWithoutSeparator, arraysize(expectedChunksWithoutSeparator))); 459 460 chunks.clear(); 461 const char* const expectedChunksWithSeparator[] = { "dog" }; 462 readAllChunks(&chunks, sharedBuffer, "dog", true); 463 EXPECT_TRUE(checkChunks(chunks, expectedChunksWithSeparator, arraysize(expectedChunksWithSeparator))); 464 } 465 466 // Ends with repeated separators. 467 { 468 const char* const simpleText = "Beaucoup de chats catcatcatcatcat"; 469 auto sharedBuffer = SharedBuffer::create(simpleText, strlen(simpleText)); 470 const char* const expectedChunksWithoutSeparator[] = { "Beaucoup de chats ", "", "", "", "" }; 471 std::vector<String> chunks; 472 readAllChunks(&chunks, sharedBuffer, "cat"); 473 EXPECT_TRUE(checkChunks(chunks, expectedChunksWithoutSeparator, arraysize(expectedChunksWithoutSeparator))); 474 475 chunks.clear(); 476 const char* const expectedChunksWithSeparator[] = { "Beaucoup de chats cat", "cat", "cat", "cat", "cat" }; 477 readAllChunks(&chunks, sharedBuffer, "cat", true); 478 EXPECT_TRUE(checkChunks(chunks, expectedChunksWithSeparator, arraysize(expectedChunksWithSeparator))); 479 } 480 { 481 const char* const simpleText = "This is a simple test.\r\nNothing special.\r\n"; 482 const char* const expectedChunks[] = { "This is a simple test.", "Nothing special." }; 483 auto sharedBuffer = SharedBuffer::create(simpleText, strlen(simpleText)); 484 std::vector<String> chunks; 485 readAllChunks(&chunks, sharedBuffer); 486 EXPECT_TRUE(checkChunks(chunks, expectedChunks, arraysize(expectedChunks))); 487 } 488 489 { 490 const char* const simpleText = "This is a simple test.\r\nNothing special."; 491 const char* const expectedChunks[] = { "This is a simple test.", "Nothing special." }; 492 auto sharedBuffer = SharedBuffer::create(simpleText, strlen(simpleText)); 493 494 std::vector<String> chunks; 495 readAllChunks(&chunks, sharedBuffer); 496 EXPECT_TRUE(checkChunks(chunks, expectedChunks, arraysize(expectedChunks))); 497 } 498 499 { 500 const char* const simpleText = "Simple line with no EOL."; 501 const char* const expectedChunks[] = { "Simple line with no EOL." }; 502 auto sharedBuffer = SharedBuffer::create(simpleText, strlen(simpleText)); 503 504 std::vector<String> chunks; 505 readAllChunks(&chunks, sharedBuffer); 506 EXPECT_TRUE(checkChunks(chunks, expectedChunks, arraysize(expectedChunks))); 507 } 508 509 { 510 const char* const simpleText = "Line that has a EOL\r\nand then ends with a CR\r"; 511 const char* const expectedChunks[] = { "Line that has a EOL", "and then ends with a CR\r" }; 512 auto sharedBuffer = SharedBuffer::create(simpleText, strlen(simpleText)); 513 514 std::vector<String> chunks; 515 readAllChunks(&chunks, sharedBuffer); 516 EXPECT_TRUE(checkChunks(chunks, expectedChunks, arraysize(expectedChunks))); 517 } 518 519 { 520 const char* const simpleText = "Repeated CRs should not cause probems\r\r\r\nShouln't they?"; 521 const char* const expectedChunks[] = { "Repeated CRs should not cause probems\r\r", "Shouln't they?" }; 522 auto sharedBuffer = SharedBuffer::create(simpleText, strlen(simpleText)); 523 524 std::vector<String> chunks; 525 readAllChunks(&chunks, sharedBuffer); 526 EXPECT_TRUE(checkChunks(chunks, expectedChunks, arraysize(expectedChunks))); 527 } 528 { 529 const char* const simpleText = "EOL\r\n betwe\r\nen segments"; 530 const char* const expectedChunks[] = { "EOL", " betwe", "en segments" }; 531 auto sharedBuffer = SharedBuffer::create(simpleText, strlen(simpleText)); 532 533 std::vector<String> chunks; 534 readAllChunks(&chunks, sharedBuffer); 535 EXPECT_TRUE(checkChunks(chunks, expectedChunks, arraysize(expectedChunks))); 536 } 537 } 538 #endif 539 540 } -
trunk/Tools/TestWebKitAPI/Tests/WebCore/SharedBufferTest.h
r210310 r286171 44 44 }; 45 45 46 #if ENABLE(MHTML) 47 class SharedBufferChunkReaderTest : public testing::Test { 48 }; 49 #endif 50 46 51 } // namespace TestWebKitAPI
Note:
See TracChangeset
for help on using the changeset viewer.