@@ -37,6 +37,7 @@ import (
3737	"os" 
3838	"strings" 
3939	"time" 
40+ 	"unicode/utf8" 
4041
4142	// 3rd Party 
4243	"github.com/google/uuid" 
@@ -367,7 +368,7 @@ func (s *Service) SendClientMessage(msg *message.Message) {
367368func  NewPBErrorMessage (err  error ) * pb.Message  {
368369	return  & pb.Message {
369370		Level :     pb .MessageLevel_WARN ,
370- 		Message :   err .Error (),
371+ 		Message :   validUTF8 ( err .Error () ),
371372		Timestamp : time .Now ().UTC ().Format (time .RFC3339 ),
372373		Error :     true ,
373374	}
@@ -377,7 +378,7 @@ func NewPBErrorMessage(err error) *pb.Message {
377378func  NewPBSuccessMessage (msg  string ) * pb.Message  {
378379	return  & pb.Message {
379380		Level :     pb .MessageLevel_SUCCESS ,
380- 		Message :   msg ,
381+ 		Message :   validUTF8 ( msg ) ,
381382		Timestamp : time .Now ().UTC ().Format (time .RFC3339 ),
382383	}
383384}
@@ -386,7 +387,7 @@ func NewPBSuccessMessage(msg string) *pb.Message {
386387func  NewPBNoteMessage (msg  string ) * pb.Message  {
387388	return  & pb.Message {
388389		Level :     pb .MessageLevel_NOTE ,
389- 		Message :   msg ,
390+ 		Message :   validUTF8 ( msg ) ,
390391		Timestamp : time .Now ().UTC ().Format (time .RFC3339 ),
391392	}
392393}
@@ -395,7 +396,7 @@ func NewPBNoteMessage(msg string) *pb.Message {
395396func  NewPBInfoMessage (msg  string ) * pb.Message  {
396397	return  & pb.Message {
397398		Level :     pb .MessageLevel_INFO ,
398- 		Message :   msg ,
399+ 		Message :   validUTF8 ( msg ) ,
399400		Timestamp : time .Now ().UTC ().Format (time .RFC3339 ),
400401	}
401402}
@@ -404,7 +405,7 @@ func NewPBInfoMessage(msg string) *pb.Message {
404405func  NewPBPlainMessage (msg  string ) * pb.Message  {
405406	return  & pb.Message {
406407		Level :     pb .MessageLevel_PLAIN ,
407- 		Message :   msg ,
408+ 		Message :   validUTF8 ( msg ) ,
408409		Timestamp : time .Now ().UTC ().Format (time .RFC3339 ),
409410	}
410411}
@@ -413,7 +414,7 @@ func NewPBPlainMessage(msg string) *pb.Message {
413414func  NewPBWarnMessage (msg  string ) * pb.Message  {
414415	return  & pb.Message {
415416		Level :     pb .MessageLevel_WARN ,
416- 		Message :   msg ,
417+ 		Message :   validUTF8 ( msg ) ,
417418		Timestamp : time .Now ().UTC ().Format (time .RFC3339 ),
418419	}
419420}
@@ -439,12 +440,25 @@ func NewPBMessageFromMessage(msg *message.Message) *pb.Message {
439440	}
440441	return  & pb.Message {
441442		Level :     level ,
442- 		Message :   msg .Message (),
443+ 		Message :   validUTF8 ( msg .Message () ),
443444		Timestamp : msg .Time ().UTC ().Format (time .RFC3339 ),
444445		Error :     msg .Error (),
445446	}
446447}
447448
449+ // validUTF8 ensures the string contains valid UTF-8 and replaces invalid characters with the '�' character 
450+ // gRPC messages must be valid UTF-8 
451+ func  validUTF8 (s  string ) string  {
452+ 	// Ensure the message is a valid UTF-8 string 
453+ 	if  utf8 .ValidString (s ) {
454+ 		return  s 
455+ 	}
456+ 	return  fmt .Sprintf (
457+ 		"\n *** The message contained invalid UTF-8 that was replaced with the '�' character ***\n \n %s" ,
458+ 		strings .ToValidUTF8 (s , "�" ),
459+ 	)
460+ }
461+ 
448462// getTLSConfig creates a new TLS configuration for the RPC service 
449463func  getTLSConfig (secure  bool , tlsKey , tlsCert , tlsCA  string ) (* tls.Config , error ) {
450464	slog .Debug ("entering into function" , "secure" , secure , "tlsKey" , tlsKey , "tlsCert" , tlsCert )
0 commit comments