diff --git a/syft/pkg/cataloger/erlang/erlang_parser.go b/syft/pkg/cataloger/erlang/erlang_parser.go index ae22589b4..819c3bb41 100644 --- a/syft/pkg/cataloger/erlang/erlang_parser.go +++ b/syft/pkg/cataloger/erlang/erlang_parser.go @@ -156,7 +156,7 @@ func parseErlangString(data []byte, i *int) (erlangNode, error) { } if c == '\\' { *i++ - if len(data) >= *i { + if *i >= len(data) { return node(nil), fmt.Errorf("invalid escape without closed string at %d", *i) } c = data[*i] diff --git a/syft/pkg/cataloger/erlang/erlang_parser_test.go b/syft/pkg/cataloger/erlang/erlang_parser_test.go index adb031ddb..9b6950793 100644 --- a/syft/pkg/cataloger/erlang/erlang_parser_test.go +++ b/syft/pkg/cataloger/erlang/erlang_parser_test.go @@ -96,6 +96,11 @@ func Test_parseErlang(t *testing.T) { { foo, bar } ]}`, }, + { + name: "string with an escaped quote", + content: ` +{escaped, ["a\"b"]}`, + }, } for _, test := range tests { @@ -112,3 +117,14 @@ func Test_parseErlang(t *testing.T) { }) } } + +func Test_parseErlangString_escapedByte(t *testing.T) { + // a backslash escape mid-string used to always error out, since the bounds + // check at the escape site was inverted (len(data) >= *i is true for + // almost every position, not just an out-of-range one). + data := []byte(`"a\"b"`) + i := 0 + got, err := parseErlangString(data, &i) + require.NoError(t, err) + assert.Equal(t, `a"b`, got.String()) +}