Skip to content

Commit 6a2435a

Browse files
committed
Merge branch 'master' into dlemire/prune_validate_utf8
2 parents 8c4cf77 + 85001c5 commit 6a2435a

File tree

4 files changed

+51
-5
lines changed

4 files changed

+51
-5
lines changed

fuzz/fuzz_utf8.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,24 @@
1212
#include <cstdlib>
1313
#include "supported_implementations.h"
1414

15+
extern "C" int VerboseTestOneInput(const uint8_t *Data, size_t Size) {
16+
static const auto supported_implementations=get_runtime_supported_implementations();
17+
for(size_t i = 0; i <= Size; i++) {
18+
std::cout<<"size: "<<std::dec<<std::setw(8)<<i<<std::endl;
19+
std::cout<<"Input: \"";
20+
for(size_t j = 0; j < i; j++) {
21+
std::cout<<"\\x"<<std::hex<<std::setw(2)<<std::setfill('0')<<uint32_t(Data[j]);
22+
}
23+
std::cout<<"\""<<std::endl;
24+
for(const auto& e: supported_implementations) {
25+
if(!e->supported_by_runtime_system()) { continue; }
26+
const bool current=e->validate_utf8((const char*)Data,i);
27+
std::cout<<e->name()<<" returns "<<current<<std::endl;
28+
}
29+
std::cout<<std::endl;
30+
}
31+
return 0;
32+
}
1533

1634
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
1735

@@ -51,6 +69,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
5169
}
5270
std::cerr << "\"" <<std::endl;
5371

72+
VerboseTestOneInput(Data, Size);
73+
5474
std::abort();
5575
}
5676

include/simdjson/ppc64/simd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ template <> struct simd8<uint8_t> : base8_numeric<uint8_t> {
395395
template <typename T> struct simd8x64 {
396396
static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>);
397397
static_assert(NUM_CHUNKS == 4,
398-
"Westmere kernel should use four registers per 64-byte block.");
398+
"PPC64 kernel should use four registers per 64-byte block.");
399399
const simd8<T> chunks[NUM_CHUNKS];
400400

401401
simd8x64(const simd8x64<T> &o) = delete; // no copy allowed

src/ppc64/dom_parser_implementation.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ simdjson_really_inline json_character_block json_character_block::classify(const
4949
}
5050

5151
simdjson_really_inline bool is_ascii(const simd8x64<uint8_t>& input) {
52-
return input.reduce_or().saturating_sub(0b10000000u).bits_not_set_anywhere();
52+
// careful: 0x80 is not ascii.
53+
return input.reduce_or().saturating_sub(0b01111111u).bits_not_set_anywhere();
5354
}
5455

5556
simdjson_unused simdjson_really_inline simd8<bool> must_be_continuation(const simd8<uint8_t> prev1, const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {

tests/unicode_tests.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,15 +223,17 @@ void test() {
223223
"\x80",
224224
"\x91\x85\x95\x9e",
225225
"\x6c\x02\x8e\x18",
226-
"[[[[[[[[[[[[[[[\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"};
227-
for (size_t i = 0; i < 8; i++) {
226+
"\x25\x5b\x6e\x2c\x32\x2c\x5b\x5b\x33\x2c\x34\x2c\x05\x29\x2c\x33\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5d\x2c\x35\x2e\x33\x2c\x39\x2e\x33\x2c\x37\x2e\x33\x2c\x39\x2e\x34\x2c\x37\x2e\x33\x2c\x39\x2e\x33\x2c\x37\x2e\x33\x2c\x39\x2e\x34\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x20\x01\x01\x01\x01\x01\x02\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x23\x0a\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x7e\x7e\x0a\x0a\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5d\x2c\x37\x2e\x33\x2c\x39\x2e\x33\x2c\x37\x2e\x33\x2c\x39\x2e\x34\x2c\x37\x2e\x33\x2c\x39\x2e\x33\x2c\x37\x2e\x33\x2c\x39\x2e\x34\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x5d\x01\x01\x80\x01\x01\x01\x79\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01",
227+
"[[[[[[[[[[[[[[[\x80\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x010\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01",
228+
"\x20\x0b\x01\x01\x01\x64\x3a\x64\x3a\x64\x3a\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x5b\x30\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x80\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"};
229+
for (size_t i = 0; i < sizeof(goodsequences)/sizeof(goodsequences[0]); i++) {
228230
size_t len = std::strlen(goodsequences[i]);
229231
if (!simdjson::validate_utf8(goodsequences[i], len)) {
230232
printf("bug goodsequences[%zu]\n", i);
231233
abort();
232234
}
233235
}
234-
for (size_t i = 0; i < 26; i++) {
236+
for (size_t i = 0; i < sizeof(badsequences)/sizeof(badsequences[0]); i++) {
235237
size_t len = std::strlen(badsequences[i]);
236238
if (simdjson::validate_utf8(badsequences[i], len)) {
237239
printf("bug lookup2 badsequences[%zu]\n", i);
@@ -240,7 +242,30 @@ void test() {
240242
}
241243
printf("tests ok.\n");
242244
}
245+
246+
// This is an attempt at reproducing an issue with the utf8 fuzzer
247+
void puzzler() {
248+
std::cout << "running puzzler... " << std::endl;
249+
const char* bad64 = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
250+
size_t length = 64;
251+
std::cout << "Input: \"";
252+
for(size_t j = 0; j < length; j++) {
253+
std::cout << "\\x" << std::hex << std::setw(2) << std::setfill('0') << uint32_t(bad64[j]);
254+
}
255+
std::cout << "\"" << std::endl;
256+
bool is_ok{true};
257+
for(const auto& e: simdjson::available_implementations) {
258+
if(!e->supported_by_runtime_system()) { continue; }
259+
const bool current = e->validate_utf8(bad64, length);
260+
std::cout << e->name() << " returns " << current << std::endl;
261+
if(current) { is_ok = false; }
262+
}
263+
if(!is_ok) { abort(); }
264+
std::cout << "Ok!" << std::endl;
265+
}
266+
243267
int main() {
268+
puzzler();
244269
brute_force_tests();
245270
test();
246271
return EXIT_SUCCESS;

0 commit comments

Comments
 (0)