DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
utf8.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file utf8.h
6 * @brief Strict UTF-8 validation (RFC 3629), one shared copy.
7 *
8 * Several protocols must reject non-UTF-8 input: WebSocket TEXT frames
9 * (RFC 6455 8.1, fail with close 1007) and MQTT strings (MQTT 1.5.3). Both use
10 * this single validator rather than each rolling its own. Header-only inline,
11 * like the other shared primitives - zero link cost when unused.
12 *
13 * @author Douglas Quigg (dstroy0)
14 * @date 2026
15 */
16
17#ifndef DETERMINISTICESPASYNCWEBSERVER_DET_UTF8_H
18#define DETERMINISTICESPASYNCWEBSERVER_DET_UTF8_H
19
20#include <stddef.h>
21#include <stdint.h>
22
23/**
24 * @brief True if [s, s+n) is well-formed UTF-8.
25 *
26 * Rejects overlong encodings, surrogate code points (U+D800..U+DFFF), values
27 * above U+10FFFF, bad continuation bytes, and truncated multi-byte sequences.
28 */
29inline bool det_utf8_valid(const uint8_t *s, size_t n)
30{
31 size_t i = 0;
32 while (i < n)
33 {
34 uint8_t c = s[i];
35 if (c < 0x80)
36 {
37 i++;
38 continue;
39 }
40 size_t need;
41 uint32_t cp;
42 uint32_t lo;
43 if ((c & 0xE0) == 0xC0)
44 {
45 need = 1;
46 cp = c & 0x1F;
47 lo = 0x80;
48 }
49 else if ((c & 0xF0) == 0xE0)
50 {
51 need = 2;
52 cp = c & 0x0F;
53 lo = 0x800;
54 }
55 else if ((c & 0xF8) == 0xF0)
56 {
57 need = 3;
58 cp = c & 0x07;
59 lo = 0x10000;
60 }
61 else
62 return false; // 0x80..0xBF lead, or 0xF8.. invalid
63 if (i + need >= n)
64 return false; // truncated multi-byte sequence
65 for (size_t k = 1; k <= need; k++)
66 {
67 uint8_t cc = s[i + k];
68 if ((cc & 0xC0) != 0x80)
69 return false; // bad continuation byte
70 cp = (cp << 6) | (cc & 0x3F);
71 }
72 if (cp < lo || cp > 0x10FFFFu || (cp >= 0xD800u && cp <= 0xDFFFu))
73 return false; // overlong, out-of-range, or surrogate
74 i += need + 1;
75 }
76 return true;
77}
78
79#endif // DETERMINISTICESPASYNCWEBSERVER_DET_UTF8_H
bool det_utf8_valid(const uint8_t *s, size_t n)
True if [s, s+n) is well-formed UTF-8.
Definition utf8.h:29