Tighten Seriatim input validation
This commit is contained in:
@@ -45,13 +45,21 @@ func decodeTranscript(raw []byte) (transcript, error) {
|
||||
if !ok {
|
||||
return transcript{}, fmt.Errorf("segments are required")
|
||||
}
|
||||
var segments []segment
|
||||
if err := decodeJSON(segmentsRaw, &segments); err != nil {
|
||||
var segmentValues []json.RawMessage
|
||||
if err := decodeJSON(segmentsRaw, &segmentValues); err != nil {
|
||||
return transcript{}, fmt.Errorf("segments must be an array: %w", err)
|
||||
}
|
||||
if segments == nil {
|
||||
if segmentValues == nil {
|
||||
return transcript{}, fmt.Errorf("segments must be an array")
|
||||
}
|
||||
segments := make([]segment, 0, len(segmentValues))
|
||||
for i, rawSegment := range segmentValues {
|
||||
segment, err := decodeSegment(rawSegment, i)
|
||||
if err != nil {
|
||||
return transcript{}, err
|
||||
}
|
||||
segments = append(segments, segment)
|
||||
}
|
||||
|
||||
return transcript{
|
||||
Metadata: metadata,
|
||||
@@ -59,6 +67,50 @@ func decodeTranscript(raw []byte) (transcript, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func decodeSegment(raw []byte, index int) (segment, error) {
|
||||
var fields map[string]json.RawMessage
|
||||
if err := decodeJSON(raw, &fields); err != nil {
|
||||
return segment{}, fmt.Errorf("segment[%d] must be an object: %w", index, err)
|
||||
}
|
||||
if fields == nil {
|
||||
return segment{}, fmt.Errorf("segment[%d] must be an object", index)
|
||||
}
|
||||
|
||||
var decoded segment
|
||||
if err := decodeOptionalString(fields, "id", &decoded.ID); err != nil {
|
||||
return segment{}, fmt.Errorf("segment[%d] id must be a string: %w", index, err)
|
||||
}
|
||||
if err := decodeOptionalNumber(fields, "start", &decoded.Start); err != nil {
|
||||
return segment{}, fmt.Errorf("segment[%d] start must be a number: %w", index, err)
|
||||
}
|
||||
if err := decodeOptionalNumber(fields, "end", &decoded.End); err != nil {
|
||||
return segment{}, fmt.Errorf("segment[%d] end must be a number: %w", index, err)
|
||||
}
|
||||
if err := decodeOptionalString(fields, "speaker", &decoded.Speaker); err != nil {
|
||||
return segment{}, fmt.Errorf("segment[%d] speaker must be a string: %w", index, err)
|
||||
}
|
||||
if err := decodeOptionalString(fields, "text", &decoded.Text); err != nil {
|
||||
return segment{}, fmt.Errorf("segment[%d] text must be a string: %w", index, err)
|
||||
}
|
||||
return decoded, nil
|
||||
}
|
||||
|
||||
func decodeOptionalString(fields map[string]json.RawMessage, key string, out *string) error {
|
||||
raw, ok := fields[key]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return decodeJSON(raw, out)
|
||||
}
|
||||
|
||||
func decodeOptionalNumber(fields map[string]json.RawMessage, key string, out *json.Number) error {
|
||||
raw, ok := fields[key]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return decodeJSON(raw, out)
|
||||
}
|
||||
|
||||
func decodeJSON(raw []byte, out any) error {
|
||||
decoder := json.NewDecoder(bytes.NewReader(raw))
|
||||
decoder.UseNumber()
|
||||
|
||||
Reference in New Issue
Block a user