@@ -450,24 +450,63 @@ bbf_rewrite_truncated_identifiers(const char *msg)
450450 found = strstr (search_msg , key );
451451 while (found )
452452 {
453+ int prefix_len = found - search_msg ;
454+ int orig_len = strlen (entry -> original_name );
455+ int suffix_len = strlen (found + key_len );
456+ char * newmsg = MemoryContextAlloc (TopMemoryContext ,
457+ prefix_len + orig_len + suffix_len + 1 );
458+ char * oldresult = result ;
459+
460+ memcpy (newmsg , search_msg , prefix_len );
461+ memcpy (newmsg + prefix_len , entry -> original_name , orig_len );
462+ memcpy (newmsg + prefix_len + orig_len , found + key_len , suffix_len + 1 );
463+
464+ if (oldresult )
465+ pfree (oldresult );
466+
467+ result = newmsg ;
468+ search_msg = newmsg ;
469+ found = strstr (search_msg + prefix_len + orig_len , key );
470+ }
471+ }
472+ }
473+
474+ /* Validate UTF-8 before returning — avoid crashing the TDS layer */
475+ if (result )
476+ {
477+ const unsigned char * p = (const unsigned char * ) result ;
478+ while (* p )
479+ {
480+ if (* p >= 0x80 )
481+ {
482+ if ((* p & 0xE0 ) == 0xC0 )
453483 {
454- int prefix_len = found - search_msg ;
455- int orig_len = strlen (entry -> original_name );
456- int suffix_len = strlen (found + key_len );
457- char * newmsg = MemoryContextAlloc (TopMemoryContext ,
458- prefix_len + orig_len + suffix_len + 1 );
459- memcpy (newmsg , search_msg , prefix_len );
460- memcpy (newmsg + prefix_len , entry -> original_name , orig_len );
461- memcpy (newmsg + prefix_len + orig_len , found + key_len , suffix_len + 1 );
462- search_msg = newmsg ;
463- result = newmsg ;
464- found = strstr (search_msg + prefix_len + orig_len , key );
484+ if ((p [1 ] & 0xC0 ) != 0x80 ) goto invalid ;
485+ p += 2 ;
465486 }
487+ else if ((* p & 0xF0 ) == 0xE0 )
488+ {
489+ if ((p [1 ] & 0xC0 ) != 0x80 || (p [2 ] & 0xC0 ) != 0x80 ) goto invalid ;
490+ p += 3 ;
491+ }
492+ else if ((* p & 0xF8 ) == 0xF0 )
493+ {
494+ if ((p [1 ] & 0xC0 ) != 0x80 || (p [2 ] & 0xC0 ) != 0x80 || (p [3 ] & 0xC0 ) != 0x80 ) goto invalid ;
495+ p += 4 ;
496+ }
497+ else
498+ goto invalid ;
466499 }
500+ else
501+ p ++ ;
467502 }
468503 }
469504
470505 return result ;
506+
507+ invalid :
508+ pfree (result );
509+ return NULL ;
471510}
472511
473512PG_FUNCTION_INFO_V1 (init_catalog );
0 commit comments