| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/i18n/streaming_utf8_validator.h" | 5 #include "base/i18n/streaming_utf8_validator.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <stdio.h> | 9 #include <stdio.h> |
| 10 #include <string.h> | 10 #include <string.h> |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 #ifdef BASE_I18N_UTF8_VALIDATOR_THOROUGH_TEST | 25 #ifdef BASE_I18N_UTF8_VALIDATOR_THOROUGH_TEST |
| 26 | 26 |
| 27 #include "base/bind.h" | 27 #include "base/bind.h" |
| 28 #include "base/location.h" | 28 #include "base/location.h" |
| 29 #include "base/logging.h" | 29 #include "base/logging.h" |
| 30 #include "base/memory/ref_counted.h" | 30 #include "base/memory/ref_counted.h" |
| 31 #include "base/strings/string_util.h" | 31 #include "base/strings/string_util.h" |
| 32 #include "base/strings/stringprintf.h" | 32 #include "base/strings/stringprintf.h" |
| 33 #include "base/strings/utf_string_conversion_utils.h" | 33 #include "base/strings/utf_string_conversion_utils.h" |
| 34 #include "base/synchronization/condition_variable.h" | |
| 35 #include "base/synchronization/lock.h" | 34 #include "base/synchronization/lock.h" |
| 36 #include "base/threading/sequenced_worker_pool.h" | 35 #include "base/task_scheduler/post_task.h" |
| 36 #include "base/task_scheduler/task_scheduler.h" |
| 37 #include "third_party/icu/source/common/unicode/utf8.h" | 37 #include "third_party/icu/source/common/unicode/utf8.h" |
| 38 | 38 |
| 39 #endif // BASE_I18N_UTF8_VALIDATOR_THOROUGH_TEST | 39 #endif // BASE_I18N_UTF8_VALIDATOR_THOROUGH_TEST |
| 40 | 40 |
| 41 namespace base { | 41 namespace base { |
| 42 namespace { | 42 namespace { |
| 43 | 43 |
| 44 // Avoid having to qualify the enum values in the tests. | 44 // Avoid having to qualify the enum values in the tests. |
| 45 const StreamingUtf8Validator::State VALID_ENDPOINT = | 45 const StreamingUtf8Validator::State VALID_ENDPOINT = |
| 46 StreamingUtf8Validator::VALID_ENDPOINT; | 46 StreamingUtf8Validator::VALID_ENDPOINT; |
| 47 const StreamingUtf8Validator::State VALID_MIDPOINT = | 47 const StreamingUtf8Validator::State VALID_MIDPOINT = |
| 48 StreamingUtf8Validator::VALID_MIDPOINT; | 48 StreamingUtf8Validator::VALID_MIDPOINT; |
| 49 const StreamingUtf8Validator::State INVALID = StreamingUtf8Validator::INVALID; | 49 const StreamingUtf8Validator::State INVALID = StreamingUtf8Validator::INVALID; |
| 50 | 50 |
| 51 #ifdef BASE_I18N_UTF8_VALIDATOR_THOROUGH_TEST | 51 #ifdef BASE_I18N_UTF8_VALIDATOR_THOROUGH_TEST |
| 52 | 52 |
| 53 const uint32_t kThoroughTestChunkSize = 1 << 24; | 53 const uint32_t kThoroughTestChunkSize = 1 << 24; |
| 54 | 54 |
| 55 class StreamingUtf8ValidatorThoroughTest : public ::testing::Test { | 55 class StreamingUtf8ValidatorThoroughTest : public ::testing::Test { |
| 56 protected: | 56 protected: |
| 57 StreamingUtf8ValidatorThoroughTest() | 57 StreamingUtf8ValidatorThoroughTest() |
| 58 : all_done_(&lock_), tasks_dispatched_(0), tasks_finished_(0) {} | 58 : tasks_dispatched_(0), tasks_finished_(0) {} |
| 59 | 59 |
| 60 // This uses the same logic as base::IsStringUTF8 except it considers | 60 // This uses the same logic as base::IsStringUTF8 except it considers |
| 61 // non-characters valid (and doesn't require a string as input). | 61 // non-characters valid (and doesn't require a string as input). |
| 62 static bool IsStringUtf8(const char* src, int32_t src_len) { | 62 static bool IsStringUtf8(const char* src, int32_t src_len) { |
| 63 int32_t char_index = 0; | 63 int32_t char_index = 0; |
| 64 | 64 |
| 65 while (char_index < src_len) { | 65 while (char_index < src_len) { |
| 66 int32_t code_point; | 66 int32_t code_point; |
| 67 U8_NEXT(src, char_index, src_len, code_point); | 67 U8_NEXT(src, char_index, src_len, code_point); |
| 68 if (!base::IsValidCodepoint(code_point)) | 68 if (!base::IsValidCodepoint(code_point)) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 94 // pool. Signals |all_done_| at the end if it thinks all tasks are | 94 // pool. Signals |all_done_| at the end if it thinks all tasks are |
| 95 // finished. | 95 // finished. |
| 96 void TestRange(uint32_t begin, uint32_t size) { | 96 void TestRange(uint32_t begin, uint32_t size) { |
| 97 for (uint32_t i = 0; i < size; ++i) { | 97 for (uint32_t i = 0; i < size; ++i) { |
| 98 TestNumber(begin + i); | 98 TestNumber(begin + i); |
| 99 } | 99 } |
| 100 base::AutoLock al(lock_); | 100 base::AutoLock al(lock_); |
| 101 ++tasks_finished_; | 101 ++tasks_finished_; |
| 102 LOG(INFO) << tasks_finished_ << " / " << tasks_dispatched_ | 102 LOG(INFO) << tasks_finished_ << " / " << tasks_dispatched_ |
| 103 << " tasks done\n"; | 103 << " tasks done\n"; |
| 104 if (tasks_finished_ >= tasks_dispatched_) { | |
| 105 all_done_.Signal(); | |
| 106 } | |
| 107 } | 104 } |
| 108 | 105 |
| 109 protected: | 106 protected: |
| 110 base::Lock lock_; | 107 base::Lock lock_; |
| 111 base::ConditionVariable all_done_; | |
| 112 int tasks_dispatched_; | 108 int tasks_dispatched_; |
| 113 int tasks_finished_; | 109 int tasks_finished_; |
| 114 }; | 110 }; |
| 115 | 111 |
| 116 TEST_F(StreamingUtf8ValidatorThoroughTest, TestEverything) { | 112 TEST_F(StreamingUtf8ValidatorThoroughTest, TestEverything) { |
| 117 scoped_refptr<base::SequencedWorkerPool> pool = | 113 base::TaskScheduler::CreateAndStartWithDefaultParams( |
| 118 new base::SequencedWorkerPool(32, "TestEverything"); | 114 "StreamingUtf8ValidatorThoroughTest"); |
| 119 base::AutoLock al(lock_); | 115 { |
| 120 uint32_t begin = 0; | 116 base::AutoLock al(lock_); |
| 121 do { | 117 uint32_t begin = 0; |
| 122 pool->PostWorkerTask( | 118 do { |
| 123 FROM_HERE, | 119 base::PostTaskWithTraits( |
| 124 base::Bind(&StreamingUtf8ValidatorThoroughTest::TestRange, | 120 FROM_HERE, {base::TaskShutdownBehavior::BLOCK_SHUTDOWN}, |
| 125 base::Unretained(this), | 121 base::BindOnce(&StreamingUtf8ValidatorThoroughTest::TestRange, |
| 126 begin, | 122 base::Unretained(this), begin, |
| 127 kThoroughTestChunkSize)); | 123 kThoroughTestChunkSize)); |
| 128 ++tasks_dispatched_; | 124 ++tasks_dispatched_; |
| 129 begin += kThoroughTestChunkSize; | 125 begin += kThoroughTestChunkSize; |
| 130 } while (begin != 0); | 126 } while (begin != 0); |
| 131 while (tasks_finished_ < tasks_dispatched_) | 127 } |
| 132 all_done_.Wait(); | 128 base::TaskScheduler::GetInstance()->Shutdown(); |
| 129 base::TaskScheduler::GetInstance()->JoinForTesting(); |
| 130 base::TaskScheduler::SetInstance(nullptr); |
| 133 } | 131 } |
| 134 | 132 |
| 135 #endif // BASE_I18N_UTF8_VALIDATOR_THOROUGH_TEST | 133 #endif // BASE_I18N_UTF8_VALIDATOR_THOROUGH_TEST |
| 136 | 134 |
| 137 // These valid and invalid UTF-8 sequences are based on the tests from | 135 // These valid and invalid UTF-8 sequences are based on the tests from |
| 138 // base/strings/string_util_unittest.cc | 136 // base/strings/string_util_unittest.cc |
| 139 | 137 |
| 140 // All of the strings in |valid| must represent a single codepoint, because | 138 // All of the strings in |valid| must represent a single codepoint, because |
| 141 // partial sequences are constructed by taking non-empty prefixes of these | 139 // partial sequences are constructed by taking non-empty prefixes of these |
| 142 // strings. | 140 // strings. |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 TEST(StreamingUtf8ValidatorValidateTest, SimpleInvalidCase) { | 403 TEST(StreamingUtf8ValidatorValidateTest, SimpleInvalidCase) { |
| 406 EXPECT_FALSE(StreamingUtf8Validator::Validate("\xc0\x80")); | 404 EXPECT_FALSE(StreamingUtf8Validator::Validate("\xc0\x80")); |
| 407 } | 405 } |
| 408 | 406 |
| 409 TEST(StreamingUtf8ValidatorValidateTest, TruncatedIsInvalid) { | 407 TEST(StreamingUtf8ValidatorValidateTest, TruncatedIsInvalid) { |
| 410 EXPECT_FALSE(StreamingUtf8Validator::Validate("\xc2")); | 408 EXPECT_FALSE(StreamingUtf8Validator::Validate("\xc2")); |
| 411 } | 409 } |
| 412 | 410 |
| 413 } // namespace | 411 } // namespace |
| 414 } // namespace base | 412 } // namespace base |
| OLD | NEW |