@@ -184,9 +184,9 @@ func TestLogger(t *testing.T) {
184184 }
185185
186186 logger := New (& LoggerOptions {
187- Name : "test" ,
188- Output : & buf ,
189- IncludeLocation : true ,
187+ Name : "test" ,
188+ Output : & buf ,
189+ IncludeLocation : true ,
190190 AdditionalLocationOffset : 1 ,
191191 })
192192
@@ -414,6 +414,32 @@ func TestLogger(t *testing.T) {
414414 assert .Equal (t , "[INFO] test: this is test: bytes=0xc perms=0755 bits=0b101\n " , rest )
415415 })
416416
417+ t .Run ("supports quote formatting" , func (t * testing.T ) {
418+ var buf bytes.Buffer
419+
420+ logger := New (& LoggerOptions {
421+ Name : "test" ,
422+ Output : & buf ,
423+ })
424+
425+ // unsafe is a string containing control characters and a byte
426+ // sequence which is invalid utf8 ("\xFFa") to assert that all
427+ // characters are properly encoded and produce valid utf8 output
428+ unsafe := "foo\n bar\b baz\xFF a"
429+
430+ logger .Info ("this is test" ,
431+ "unquoted" , "unquoted" , "quoted" , Quote ("quoted" ),
432+ "unsafeq" , Quote (unsafe ))
433+
434+ str := buf .String ()
435+ dataIdx := strings .IndexByte (str , ' ' )
436+ rest := str [dataIdx + 1 :]
437+
438+ assert .Equal (t , "[INFO] test: this is test: " +
439+ "unquoted=unquoted quoted=\" quoted\" " +
440+ "unsafeq=\" foo\\ nbar\\ bbaz\\ xffa\" \n " , rest )
441+ })
442+
417443 t .Run ("supports resetting the output" , func (t * testing.T ) {
418444 var first , second bytes.Buffer
419445
@@ -804,6 +830,49 @@ func TestLogger_JSON(t *testing.T) {
804830 assert .Equal (t , float64 (5 ), raw ["bits" ])
805831 })
806832
833+ t .Run ("ignores quote formatting requests" , func (t * testing.T ) {
834+ var buf bytes.Buffer
835+
836+ logger := New (& LoggerOptions {
837+ Name : "test" ,
838+ Output : & buf ,
839+ JSONFormat : true ,
840+ })
841+
842+ // unsafe is a string containing control characters and a byte
843+ // sequence which is invalid utf8 ("\xFFa") to assert that all
844+ // characters are properly encoded and produce valid json
845+ unsafe := "foo\n bar\b baz\xFF a"
846+
847+ logger .Info ("this is test" ,
848+ "unquoted" , "unquoted" , "quoted" , Quote ("quoted" ),
849+ "unsafeq" , Quote (unsafe ), "unsafe" , unsafe )
850+
851+ b := buf .Bytes ()
852+
853+ // Assert the JSON only contains valid utf8 strings with the
854+ // illegal byte replaced with the utf8 replacement character,
855+ // and not invalid json with byte(255)
856+ // Note: testify/assert.Contains did not work here
857+ if needle := []byte (`\ufffda` ); ! bytes .Contains (b , needle ) {
858+ t .Fatalf ("could not find %q (%v) in json bytes: %q" , needle , needle , b )
859+ }
860+ if needle := []byte {255 , 'a' }; bytes .Contains (b , needle ) {
861+ t .Fatalf ("found %q (%v) in json bytes: %q" , needle , needle , b )
862+ }
863+
864+ var raw map [string ]interface {}
865+ if err := json .Unmarshal (b , & raw ); err != nil {
866+ t .Fatal (err )
867+ }
868+
869+ assert .Equal (t , "this is test" , raw ["@message" ])
870+ assert .Equal (t , "unquoted" , raw ["unquoted" ])
871+ assert .Equal (t , "quoted" , raw ["quoted" ])
872+ assert .Equal (t , "foo\n bar\b baz\uFFFD a" , raw ["unsafe" ])
873+ assert .Equal (t , "foo\n bar\b baz\uFFFD a" , raw ["unsafeq" ])
874+ })
875+
807876 t .Run ("includes the caller location" , func (t * testing.T ) {
808877 var buf bytes.Buffer
809878
@@ -837,10 +906,10 @@ func TestLogger_JSON(t *testing.T) {
837906 }
838907
839908 logger := New (& LoggerOptions {
840- Name : "test" ,
841- Output : & buf ,
842- JSONFormat : true ,
843- IncludeLocation : true ,
909+ Name : "test" ,
910+ Output : & buf ,
911+ JSONFormat : true ,
912+ IncludeLocation : true ,
844913 AdditionalLocationOffset : 1 ,
845914 })
846915
0 commit comments