All checks were successful
Create and publish a Docker image 🚀 / build-and-push-image (push) Successful in 1m49s
89 lines
1.7 KiB
Go
89 lines
1.7 KiB
Go
package httpsfv
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
// ErrInvalidStringFormat is returned when a string format is invalid.
|
|
var ErrInvalidStringFormat = errors.New("invalid string format")
|
|
|
|
// marshalString serializes as defined in
|
|
// https://httpwg.org/specs/rfc9651.html#ser-string.
|
|
func marshalString(b *strings.Builder, s string) error {
|
|
if err := b.WriteByte('"'); err != nil {
|
|
return err
|
|
}
|
|
|
|
for i := 0; i < len(s); i++ {
|
|
if s[i] <= '\u001F' || s[i] >= unicode.MaxASCII {
|
|
return ErrInvalidStringFormat
|
|
}
|
|
|
|
switch s[i] {
|
|
case '"', '\\':
|
|
if err := b.WriteByte('\\'); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if err := b.WriteByte(s[i]); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if err := b.WriteByte('"'); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// parseString parses as defined in
|
|
// https://httpwg.org/specs/rfc9651.html#parse-string.
|
|
func parseString(s *scanner) (string, error) {
|
|
if s.eof() || s.data[s.off] != '"' {
|
|
return "", &UnmarshalError{s.off, ErrInvalidStringFormat}
|
|
}
|
|
s.off++
|
|
|
|
var b strings.Builder
|
|
|
|
for !s.eof() {
|
|
c := s.data[s.off]
|
|
s.off++
|
|
|
|
switch c {
|
|
case '\\':
|
|
if s.eof() {
|
|
return "", &UnmarshalError{s.off, ErrInvalidStringFormat}
|
|
}
|
|
|
|
n := s.data[s.off]
|
|
if n != '"' && n != '\\' {
|
|
return "", &UnmarshalError{s.off, ErrInvalidStringFormat}
|
|
}
|
|
s.off++
|
|
|
|
if err := b.WriteByte(n); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
continue
|
|
case '"':
|
|
return b.String(), nil
|
|
default:
|
|
if c <= '\u001F' || c >= unicode.MaxASCII {
|
|
return "", &UnmarshalError{s.off, ErrInvalidStringFormat}
|
|
}
|
|
|
|
if err := b.WriteByte(c); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
}
|
|
|
|
return "", &UnmarshalError{s.off, ErrInvalidStringFormat}
|
|
}
|