@@ -243,17 +243,17 @@ WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, ui
243243 // for fear of aliasing
244244 return SUCCESS ;
245245}
246+
247+ // credit: based on code from Google Fuchsia (Apache Licensed)
246248WARN_UNUSED bool implementation::validate_utf8 (const char *buf, size_t len) const noexcept {
247249 const uint8_t *data = (const uint8_t *)buf;
248250 uint64_t pos = 0 ;
249251 uint64_t next_pos = 0 ;
250252 uint32_t code_point = 0 ;
251253 while (pos < len) {
252-
253254 // check of the next 8 bytes are ascii.
254255 next_pos = pos + 16 ;
255- if (next_pos <=
256- len) { // if it is safe to read 8 more bytes, check that they are ascii
256+ if (next_pos <= len) { // if it is safe to read 8 more bytes, check that they are ascii
257257 uint64_t v1;
258258 memcpy (&v1, data + pos, sizeof (uint64_t ));
259259 uint64_t v2;
@@ -265,34 +265,21 @@ WARN_UNUSED bool implementation::validate_utf8(const char *buf, size_t len) cons
265265 }
266266 }
267267 unsigned char byte = data[pos];
268-
269268 if (byte < 0b10000000 ) {
270269 pos++;
271270 continue ;
272271 } else if ((byte & 0b11100000 ) == 0b11000000 ) {
273272 next_pos = pos + 2 ;
274- if (next_pos > len) {
275- return false ;
276- }
277- if ((data[pos + 1 ] & 0b11000000 ) != 0b10000000 ) {
278- return false ;
279- }
273+ if (next_pos > len) { return false ; }
274+ if ((data[pos + 1 ] & 0b11000000 ) != 0b10000000 ) { return false ; }
280275 // range check
281276 code_point = (byte & 0b00011111 ) << 6 | (data[pos + 1 ] & 0b00111111 );
282- if (code_point < 0x80 || 0x7ff < code_point) {
283- return false ;
284- }
277+ if (code_point < 0x80 || 0x7ff < code_point) { return false ; }
285278 } else if ((byte & 0b11110000 ) == 0b11100000 ) {
286279 next_pos = pos + 3 ;
287- if (next_pos > len) {
288- return false ;
289- }
290- if ((data[pos + 1 ] & 0b11000000 ) != 0b10000000 ) {
291- return false ;
292- }
293- if ((data[pos + 2 ] & 0b11000000 ) != 0b10000000 ) {
294- return false ;
295- }
280+ if (next_pos > len) { return false ; }
281+ if ((data[pos + 1 ] & 0b11000000 ) != 0b10000000 ) { return false ; }
282+ if ((data[pos + 2 ] & 0b11000000 ) != 0b10000000 ) { return false ; }
296283 // range check
297284 code_point = (byte & 0b00001111 ) << 12 |
298285 (data[pos + 1 ] & 0b00111111 ) << 6 |
@@ -303,25 +290,15 @@ WARN_UNUSED bool implementation::validate_utf8(const char *buf, size_t len) cons
303290 }
304291 } else if ((byte & 0b11111000 ) == 0b11110000 ) { // 0b11110000
305292 next_pos = pos + 4 ;
306- if (next_pos > len) {
307- return false ;
308- }
309- if ((data[pos + 1 ] & 0b11000000 ) != 0b10000000 ) {
310- return false ;
311- }
312- if ((data[pos + 2 ] & 0b11000000 ) != 0b10000000 ) {
313- return false ;
314- }
315- if ((data[pos + 3 ] & 0b11000000 ) != 0b10000000 ) {
316- return false ;
317- }
293+ if (next_pos > len) { return false ; }
294+ if ((data[pos + 1 ] & 0b11000000 ) != 0b10000000 ) { return false ; }
295+ if ((data[pos + 2 ] & 0b11000000 ) != 0b10000000 ) { return false ; }
296+ if ((data[pos + 3 ] & 0b11000000 ) != 0b10000000 ) { return false ; }
318297 // range check
319298 code_point =
320299 (byte & 0b00000111 ) << 18 | (data[pos + 1 ] & 0b00111111 ) << 12 |
321300 (data[pos + 2 ] & 0b00111111 ) << 6 | (data[pos + 3 ] & 0b00111111 );
322- if (code_point < 0xffff || 0x10ffff < code_point) {
323- return false ;
324- }
301+ if (code_point < 0xffff || 0x10ffff < code_point) { return false ; }
325302 } else {
326303 // we may have a continuation
327304 return false ;
0 commit comments