Skip to content

DetectReader might OOM #479

@ivanjaros

Description

@ivanjaros

If for some reason the readLimit gets set to 0, the DetectReader will read the entire file into memory. This can be many GBs in size that would be read into memory for no valid reason.

There should be a condition to never allow reading more than a MB, for example, for whatever conditions there might be regarding the readLimit. I would personally also read in chunks up to said limit and try to detect mime for each run for the so far read data instead of ingesting the entire source []byte because you might need only 100 bytes while reading 3072.

func DetectReader(r io.Reader) (*MIME, error) {
	var in []byte
	var err error

	// Using atomic because readLimit can be written at the same time in other goroutine.
	l := atomic.LoadUint32(&readLimit)
	if l == 0 {
		in, err = ioutil.ReadAll(r) <-------------------------- BAD !!
		if err != nil {
			return errMIME, err
		}
	} else {
		var n int
		in = make([]byte, l)
		// io.UnexpectedEOF means len(r) < len(in). It is not an error in this case,
		// it just means the input file is smaller than the allocated bytes slice.
		n, err = io.ReadFull(r, in)
		if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
			return errMIME, err
		}
		in = in[:n]
	}

	mu.RLock()
	defer mu.RUnlock()
	return root.match(in, l), nil
}

Thanks for this great library though! Something like this should be built-in. Good job.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions