@@ -7,6 +7,31 @@ import type {
77 QaEvidenceProducerContextFile ,
88} from "../../shared/evidence-gallery-types.js" ;
99
10+ /** Slices a UTF-16 string without returning dangling surrogate halves at either edge. */
11+ function sliceUtf16Safe ( input : string , start : number , end ?: number ) : string {
12+ const len = input . length ;
13+ let from = start < 0 ? Math . max ( len + start , 0 ) : Math . min ( start , len ) ;
14+ let to = end === undefined ? len : end < 0 ? Math . max ( len + end , 0 ) : Math . min ( end , len ) ;
15+ if ( to <= from ) {
16+ return "" ;
17+ }
18+ const isHighSurrogate = ( codeUnit : number ) => codeUnit >= 0xd800 && codeUnit <= 0xdbff ;
19+ const isLowSurrogate = ( codeUnit : number ) => codeUnit >= 0xdc00 && codeUnit <= 0xdfff ;
20+ if ( from > 0 && from < len ) {
21+ const codeUnit = input . charCodeAt ( from ) ;
22+ if ( isLowSurrogate ( codeUnit ) && isHighSurrogate ( input . charCodeAt ( from - 1 ) ) ) {
23+ from += 1 ;
24+ }
25+ }
26+ if ( to > 0 && to < len ) {
27+ const codeUnit = input . charCodeAt ( to - 1 ) ;
28+ if ( isHighSurrogate ( codeUnit ) && isLowSurrogate ( input . charCodeAt ( to ) ) ) {
29+ to -= 1 ;
30+ }
31+ }
32+ return input . slice ( from , to ) ;
33+ }
34+
1035/* ===== Shared types (unchanged from the bus protocol) ===== */
1136
1237type Conversation = {
@@ -560,7 +585,7 @@ function isSensitiveCaptureField(label: string): boolean {
560585 ) ;
561586}
562587
563- function redactCaptureScalar ( value : string , label ?: string ) : string {
588+ export function redactCaptureScalar ( value : string , label ?: string ) : string {
564589 const trimmed = value . trim ( ) ;
565590 if ( ! trimmed ) {
566591 return "" ;
@@ -572,7 +597,7 @@ function redactCaptureScalar(value: string, label?: string): string {
572597 return "[redacted]" ;
573598 }
574599 if ( trimmed . length > 400 ) {
575- return `${ trimmed . slice ( 0 , 280 ) } \n…\n${ trimmed . slice ( - 80 ) } ` ;
600+ return `${ sliceUtf16Safe ( trimmed , 0 , 280 ) } \n…\n${ sliceUtf16Safe ( trimmed , - 80 ) } ` ;
576601 }
577602 return trimmed ;
578603}
0 commit comments