@@ -232,14 +232,12 @@ function utf8ToArray (str: string): number[] {
232232 * @returns {string } - The UTF-8 encoded string.
233233 */
234234export const toUTF8 = ( arr : number [ ] ) : string => {
235- let result = ''
235+ let result = ""
236236 let skip = 0
237237
238238 for ( let i = 0 ; i < arr . length ; i ++ ) {
239239 const byte = arr [ i ]
240240
241- // this byte is part of a multi-byte sequence, skip it
242- // added to avoid modifying i within the loop which is considered unsafe.
243241 if ( skip > 0 ) {
244242 skip --
245243 continue
@@ -253,11 +251,9 @@ export const toUTF8 = (arr: number[]): string => {
253251
254252 // 2-byte sequence (110xxxxx 10xxxxxx)
255253 if ( byte >= 0xc0 && byte <= 0xdf ) {
256- if ( i + 1 >= arr . length ) {
257- throw new Error ( "Truncated UTF-8: expected 2 bytes" )
258- }
259- const byte2 = arr [ i + 1 ]
260- skip = 1
254+ const avail = arr . length - ( i + 1 ) // number of bytes available after current
255+ const byte2 = avail >= 1 ? arr [ i + 1 ] : 0
256+ skip = Math . min ( 1 , avail )
261257
262258 const codePoint = ( ( byte & 0x1f ) << 6 ) | ( byte2 & 0x3f )
263259 result += String . fromCharCode ( codePoint )
@@ -266,12 +262,10 @@ export const toUTF8 = (arr: number[]): string => {
266262
267263 // 3-byte sequence (1110xxxx 10xxxxxx 10xxxxxx)
268264 if ( byte >= 0xe0 && byte <= 0xef ) {
269- if ( i + 2 >= arr . length ) {
270- throw new Error ( "Truncated UTF-8: expected 3 bytes" )
271- }
272- const byte2 = arr [ i + 1 ]
273- const byte3 = arr [ i + 2 ]
274- skip = 2
265+ const avail = arr . length - ( i + 1 )
266+ const byte2 = avail >= 1 ? arr [ i + 1 ] : 0
267+ const byte3 = avail >= 2 ? arr [ i + 2 ] : 0
268+ skip = Math . min ( 2 , avail )
275269
276270 const codePoint =
277271 ( ( byte & 0x0f ) << 12 ) | ( ( byte2 & 0x3f ) << 6 ) | ( byte3 & 0x3f )
@@ -281,13 +275,11 @@ export const toUTF8 = (arr: number[]): string => {
281275
282276 // 4-byte sequence (11110xxx 10xxxxxx 10xxxxxx 10xxxxxx)
283277 if ( byte >= 0xf0 && byte <= 0xf7 ) {
284- if ( i + 3 >= arr . length ) {
285- throw new Error ( "Truncated UTF-8: expected 4 bytes" )
286- }
287- const byte2 = arr [ i + 1 ]
288- const byte3 = arr [ i + 2 ]
289- const byte4 = arr [ i + 3 ]
290- skip = 3
278+ const avail = arr . length - ( i + 1 )
279+ const byte2 = avail >= 1 ? arr [ i + 1 ] : 0
280+ const byte3 = avail >= 2 ? arr [ i + 2 ] : 0
281+ const byte4 = avail >= 3 ? arr [ i + 3 ] : 0
282+ skip = Math . min ( 3 , avail )
291283
292284 const codePoint =
293285 ( ( byte & 0x07 ) << 18 ) |
@@ -301,8 +293,7 @@ export const toUTF8 = (arr: number[]): string => {
301293 continue
302294 }
303295
304- // invalid leading byte for UTF-8
305- // throw new Error(`Invalid UTF-8 leading byte: 0x${byte.toString(16)}`)
296+ // If it's an invalid leading byte, keep prior behavior: do nothing / skip
306297 }
307298
308299 return result
0 commit comments