@@ -231,6 +231,51 @@ func TestLogSender_SkipHugeLog(t *testing.T) {
231
231
require .ErrorIs (t , err , context .Canceled )
232
232
}
233
233
234
+ func TestLogSender_InvalidUTF8 (t * testing.T ) {
235
+ t .Parallel ()
236
+ testCtx := testutil .Context (t , testutil .WaitShort )
237
+ ctx , cancel := context .WithCancel (testCtx )
238
+ logger := slogtest .Make (t , nil ).Leveled (slog .LevelDebug )
239
+ fDest := newFakeLogDest ()
240
+ uut := NewLogSender (logger )
241
+
242
+ t0 := dbtime .Now ()
243
+ ls1 := uuid.UUID {0x11 }
244
+
245
+ uut .Enqueue (ls1 ,
246
+ Log {
247
+ CreatedAt : t0 ,
248
+ Output : "test log 0, src 1\xc3 \x28 " ,
249
+ Level : codersdk .LogLevelInfo ,
250
+ },
251
+ Log {
252
+ CreatedAt : t0 ,
253
+ Output : "test log 1, src 1" ,
254
+ Level : codersdk .LogLevelInfo ,
255
+ })
256
+
257
+ loopErr := make (chan error , 1 )
258
+ go func () {
259
+ err := uut .SendLoop (ctx , fDest )
260
+ loopErr <- err
261
+ }()
262
+
263
+ req := testutil .RequireRecvCtx (ctx , t , fDest .reqs )
264
+ require .NotNil (t , req )
265
+ require .Len (t , req .Logs , 2 , "it should sanitize invalid UTF-8, but still send" )
266
+ // the 0xc3, 0x28 is an invalid 2-byte sequence in UTF-8. The sanitizer replaces 0xc3 with ❌, and then
267
+ // interprets 0x28 as a 1-byte sequence "("
268
+ require .Equal (t , "test log 0, src 1❌(" , req .Logs [0 ].GetOutput ())
269
+ require .Equal (t , proto .Log_INFO , req .Logs [0 ].GetLevel ())
270
+ require .Equal (t , "test log 1, src 1" , req .Logs [1 ].GetOutput ())
271
+ require .Equal (t , proto .Log_INFO , req .Logs [1 ].GetLevel ())
272
+ testutil .RequireSendCtx (ctx , t , fDest .resps , & proto.BatchCreateLogsResponse {})
273
+
274
+ cancel ()
275
+ err := testutil .RequireRecvCtx (testCtx , t , loopErr )
276
+ require .ErrorIs (t , err , context .Canceled )
277
+ }
278
+
234
279
func TestLogSender_Batch (t * testing.T ) {
235
280
t .Parallel ()
236
281
testCtx := testutil .Context (t , testutil .WaitShort )
0 commit comments