@@ -131,41 +131,48 @@ namespace nspanel_easy {
131131 [&strToSearch](const std::string& str) { return strToSearch == str; });
132132 }
133133
134- uint32_t decode_utf8 (const char * bytes) {
135- if (!bytes || bytes[0 ] == ' \0 ' ) {
136- return 0 ;
134+ uint32_t decode_nextion_icon_utf8 (const char * bytes, size_t length) {
135+ // Nextion icons are encoded as 1-3 byte UTF-8 sequences only
136+ if (!bytes || length == 0 || length > 3 ) {
137+ return 0 ; // Invalid: null, empty, or too long for Nextion icon
137138 }
138- uint32_t code_point = 0 ;
139+
139140 unsigned char byte = static_cast <unsigned char >(bytes[0 ]);
140- auto is_continuation = [](unsigned char b) { return (b & 0xC0 ) == 0x80 ; }; // Helper to check valid continuation byte
141+ uint32_t code_point = 0 ;
142+
143+ // 1-byte sequence (0x00-0x7F)
141144 if ((byte & 0x80 ) == 0x00 ) {
142145 code_point = byte;
143- } else if ((byte & 0xE0 ) == 0xC0 && is_continuation (bytes[1 ])) {
144- unsigned char b1 = static_cast <unsigned char >(bytes[1 ]);
145- code_point = ((byte & 0x1F ) << 6 ) | (b1 & 0x3F );
146- // Reject overlong encodings (code points < 0x80 encoded as 2 bytes)
147- if (code_point < 0x80 ) return 0 ;
148- } else if ((byte & 0xF0 ) == 0xE0 && is_continuation (bytes[1 ]) && is_continuation (bytes[2 ])) {
149- unsigned char b1 = static_cast <unsigned char >(bytes[1 ]);
150- unsigned char b2 = static_cast <unsigned char >(bytes[2 ]);
146+ }
147+ // 2-byte sequence (0xC0-0xDF)
148+ else if ((byte & 0xE0 ) == 0xC0 ) {
149+ if (length < 2 || (bytes[1 ] & 0xC0 ) != 0x80 ) {
150+ return 0 ; // Invalid: insufficient length or bad continuation byte
151+ }
152+ code_point = ((byte & 0x1F ) << 6 ) | (bytes[1 ] & 0x3F );
153+ // Reject overlong encodings
154+ if (code_point < 0x80 ) {
155+ return 0 ;
156+ }
157+ }
158+ // 3-byte sequence (0xE0-0xEF)
159+ else if ((byte & 0xF0 ) == 0xE0 ) {
160+ if (length < 3 || (bytes[1 ] & 0xC0 ) != 0x80 || (bytes[2 ] & 0xC0 ) != 0x80 ) {
161+ return 0 ; // Invalid: insufficient length or bad continuation bytes
162+ }
151163 code_point = ((byte & 0x0F ) << 12 ) |
152- ((b1 & 0x3F ) << 6 ) |
153- (b2 & 0x3F );
164+ ((bytes[ 1 ] & 0x3F ) << 6 ) |
165+ (bytes[ 2 ] & 0x3F );
154166 // Reject overlong encodings and surrogate code points
155- if (code_point < 0x800 || (code_point >= 0xD800 && code_point <= 0xDFFF )) return 0 ;
156- } else if ((byte & 0xF8 ) == 0xF0 && is_continuation (bytes[1 ]) && is_continuation (bytes[2 ]) && is_continuation (bytes[3 ])) {
157- unsigned char b1 = static_cast <unsigned char >(bytes[1 ]);
158- unsigned char b2 = static_cast <unsigned char >(bytes[2 ]);
159- unsigned char b3 = static_cast <unsigned char >(bytes[3 ]);
160- code_point = ((byte & 0x07 ) << 18 ) |
161- ((b1 & 0x3F ) << 12 ) |
162- ((b2 & 0x3F ) << 6 ) |
163- (b3 & 0x3F );
164- // Reject overlong encodings and values beyond Unicode max
165- if (code_point < 0x10000 || code_point > 0x10FFFF ) return 0 ;
166- } else {
167- code_point = 0 ;
167+ if (code_point < 0x800 || (code_point >= 0xD800 && code_point <= 0xDFFF )) {
168+ return 0 ;
169+ }
168170 }
171+ // Invalid: 4-byte sequences or invalid leading byte
172+ else {
173+ return 0 ;
174+ }
175+
169176 return code_point;
170177 }
171178
0 commit comments