Skip to content

Commit

Permalink
Add max depth to comment parser
Browse files Browse the repository at this point in the history
  • Loading branch information
rossabaker committed Jan 2, 2023
1 parent 3a60e7e commit f09ae5a
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 7 deletions.
7 changes: 6 additions & 1 deletion core/src/main/scala/org/http4s/headers/User-Agent.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ package org.http4s
package headers

import org.http4s.parser.HttpHeaderParser
import org.http4s.parser.Rfc2616BasicRules
import org.http4s.util.{Renderable, Writer}

object `User-Agent` extends HeaderKey.Internal[`User-Agent`] with HeaderKey.Singleton {
@deprecated("Use parse(Int) instead", "0.21.34")
override def parse(s: String): ParseResult[`User-Agent`] =
HttpHeaderParser.USER_AGENT(s)
parse(Rfc2616BasicRules.CommentDefaultMaxDepth)(s)

def parse(maxDepth: Int)(s: String): ParseResult[`User-Agent`] =
HttpHeaderParser.USER_AGENT(maxDepth)(s)
}

sealed trait AgentToken extends Renderable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ object HttpHeaderParser
addParser_("SET-COOKIE".ci, `SET_COOKIE`)
addParser_("STRICT-TRANSPORT-SECURITY".ci, `STRICT_TRANSPORT_SECURITY`)
addParser_("TRANSFER-ENCODING".ci, `TRANSFER_ENCODING`)
addParser_("USER-AGENT".ci, `USER_AGENT`)
addParser_("USER-AGENT".ci, `USER_AGENT`(Rfc2616BasicRules.CommentDefaultMaxDepth))
addParser_("WWW-AUTHENTICATE".ci, `WWW_AUTHENTICATE`)
addParser_("X-B3-FLAGS".ci, `X_B3_FLAGS`)
addParser_("X-B3-PARENTSPANID".ci, `X_B3_PARENTSPANID`)
Expand Down
17 changes: 15 additions & 2 deletions core/src/main/scala/org/http4s/parser/Rfc2616BasicRules.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,19 @@ private[http4s] trait Rfc2616BasicRules extends Parser {
@nowarn("cat=deprecation")
def Token: Rule1[String] = rule(capture(oneOrMore(!CTL ~ !Separator ~ ANY)))

// TODO What's the replacement for DROP?
def Comment: Rule0 = rule("(" ~ zeroOrMore(CText | QuotedPair ~> DROP | Comment) ~ ")")
def Comment(maxDepth: Int): Rule0 = {
def go(n: Int): Rule0 =
if (n < 0) rule(fail("max comment depth exceeded"))
else
rule {
"(" ~ zeroOrMore(CText | QuotedPair ~> DROP | go(n - 1)) ~ ")"
}
go(maxDepth)
}

@deprecated("Use Comment(Int) instead", "0.21.34")
def Comment: Rule0 =
Comment(Rfc2616BasicRules.CommentDefaultMaxDepth)

def DROP: Any => Unit = { _ =>
()
Expand Down Expand Up @@ -89,4 +100,6 @@ private[http4s] object Rfc2616BasicRules {
.leftMap(e => ParseFailure("Invalid token", e.format(in)))

def isToken(in: ParserInput) = token(in).isRight

val CommentDefaultMaxDepth: Int = 100
}
10 changes: 7 additions & 3 deletions core/src/main/scala/org/http4s/parser/SimpleHeaders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,15 @@ private[parser] trait SimpleHeaders {
def TRANSFER_ENCODING(value: String): ParseResult[`Transfer-Encoding`] =
TransferCoding.parseList(value).map(`Transfer-Encoding`.apply)

@deprecated("Use USER_AGENT(Int) instead", "0.21.34")
def USER_AGENT(value: String): ParseResult[`User-Agent`] =
USER_AGENT(Rfc2616BasicRules.CommentDefaultMaxDepth)(value)

def USER_AGENT(maxDepth: Int)(value: String): ParseResult[`User-Agent`] =
new Http4sHeaderParser[`User-Agent`](value) {
def entry =
rule {
product ~ zeroOrMore(RWS ~ (product | comment)) ~> {
product ~ zeroOrMore(RWS ~ (product | comment(maxDepth))) ~ EOL ~> {
(product: AgentProduct, tokens: collection.Seq[AgentToken]) =>
(`User-Agent`(product, tokens.toList))
}
Expand All @@ -213,9 +217,9 @@ private[parser] trait SimpleHeaders {
Token ~ optional("/" ~ Token) ~> (AgentProduct(_, _))
}

def comment: Rule1[AgentComment] =
def comment(maxDepth: Int): Rule1[AgentComment] =
rule {
capture(Comment) ~> { (s: String) =>
capture(Comment(maxDepth)) ~> { (s: String) =>
AgentComment(s.substring(1, s.length - 1))
}
}
Expand Down

0 comments on commit f09ae5a

Please sign in to comment.