|
|
|
@@ -312,12 +312,25 @@ func (s *Source) decodeWithPreference(ctx context.Context, stream io.Reader, met |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// maxCaptureBytes caps the amount of stream data buffered while the native |
|
|
|
// decoder is deciding whether it can handle the format. Without a cap, a |
|
|
|
// decoder that reads extensively before returning ErrUnsupported could grow |
|
|
|
// this buffer unboundedly on a corrupt or adversarial stream. |
|
|
|
const maxCaptureBytes = 1 << 20 // 1 MiB |
|
|
|
|
|
|
|
// errCaptureLimitExceeded is returned by capturingReader when the buffer cap |
|
|
|
// is hit. The caller should treat it like ErrUnsupported and fall back. |
|
|
|
var errCaptureLimitExceeded = errors.New("capture buffer limit exceeded") |
|
|
|
|
|
|
|
type capturingReader struct { |
|
|
|
r io.Reader |
|
|
|
buf bytes.Buffer |
|
|
|
} |
|
|
|
|
|
|
|
func (r *capturingReader) Read(p []byte) (int, error) { |
|
|
|
if r.buf.Len() >= maxCaptureBytes { |
|
|
|
return 0, errCaptureLimitExceeded |
|
|
|
} |
|
|
|
n, err := r.r.Read(p) |
|
|
|
if n > 0 { |
|
|
|
_, _ = r.buf.Write(p[:n]) |
|
|
|
|