Repository: fastify/fastify
File: lib/contentTypeParser.js (JavaScript)

Code before:
  return this.customParsers.has(typeof contentType === 'string' ? contentType : contentType.toString())
}

ContentTypeParser.prototype.existingParser = function (contentType) {
  if (contentType === 'application/json' && this.customParsers.has(contentType)) {
    return this.customParsers.get(contentType).fn !== this[kDefaultJsonParse]
  }
  if (contentType === 'text/plain' && this.customParsers.has(contentType)) {
    return this.customParsers.get(contentType).fn !== defaultPlainTextParser
  }

  return this.hasParser(contentType)
}

ContentTypeParser.prototype.getParser = function (contentType) {
  if (this.hasParser(contentType)) {
    return this.customParsers.get(contentType)
  }

  const parser = this.cache.get(contentType)
  if (parser !== undefined) return parser

  // eslint-disable-next-line no-var
  for (var i = 0; i !== this.parserList.length; ++i) {
    const parserListItem = this.parserList[i]
    if (contentType.indexOf(parserListItem) === 0) {
      const parser = this.customParsers.get(parserListItem)
      this.cache.set(contentType, parser)
      return parser
    }
  }

  // eslint-disable-next-line no-var
  for (var j = 0; j !== this.parserRegExpList.length; ++j) {
    const parserRegExp = this.parserRegExpList[j]
    if (parserRegExp.test(contentType)) {
      const parser = this.customParsers.get(parserRegExp.toString())
      this.cache.set(contentType, parser)
      return parser
    }
  }

  return this.customParsers.get('')
}

ContentTypeParser.prototype.removeAll = function () {
  this.customParsers = new Map()
  this.parserRegExpList = []
  this.parserList = []
  this.cache = lru(100)
}

Review comment (security):
Don't do it like what I'm doing here, but just to ask - is this value trimmed and lowercased somewhere else?

Maybe we should do that before checking to increase matches? It is still valid to have spaces around the contentType value, and definitely fine to make it case insensitive AFAIK

```suggestion
    if (contentType.trim().toLowerCase().indexOf(parserListItem) === 0) {
```

Code after:
  return this.customParsers.has(typeof contentType === 'string' ? contentType : contentType.toString())
}

ContentTypeParser.prototype.existingParser = function (contentType) {
  if (contentType === 'application/json' && this.customParsers.has(contentType)) {
    return this.customParsers.get(contentType).fn !== this[kDefaultJsonParse]
  }
  if (contentType === 'text/plain' && this.customParsers.has(contentType)) {
    return this.customParsers.get(contentType).fn !== defaultPlainTextParser
  }

  return this.hasParser(contentType)
}

ContentTypeParser.prototype.getParser = function (contentType) {
  if (this.hasParser(contentType)) {
    return this.customParsers.get(contentType)
  }

  const parser = this.cache.get(contentType)
  if (parser !== undefined) return parser

  // eslint-disable-next-line no-var
  for (var i = 0; i !== this.parserList.length; ++i) {
    const parserListItem = this.parserList[i]
    if (contentType.indexOf(parserListItem) === 0) {
      const parser = this.customParsers.get(parserListItem)
      this.cache.set(contentType, parser)
      return parser
    }
  }

  // eslint-disable-next-line no-var
  for (var j = 0; j !== this.parserRegExpList.length; ++j) {
    const parserRegExp = this.parserRegExpList[j]
    if (parserRegExp.test(contentType)) {
      const parser = this.customParsers.get(parserRegExp.toString())
      this.cache.set(contentType, parser)
      return parser
    }
  }

  return this.customParsers.get('')
}

ContentTypeParser.prototype.removeAll = function () {
  this.customParsers = new Map()
  this.parserRegExpList = []
  this.parserList = []
  this.cache = new Fifo(100)
}