Skip to content

Commit

Permalink
Merge pull request #9 from nlnwa/fix-slow-state
Browse files Browse the repository at this point in the history
Fix nonlinear runtime in stateQuery and stateFragment
  • Loading branch information
andrbo authored Jun 14, 2022
2 parents 441bfd9 + adac416 commit 9a67708
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 25 deletions.
41 changes: 16 additions & 25 deletions url/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ func (p *parser) basicParser(urlOrRef string, base *Url, url *Url, stateOverride
input.nextCodePoint()
} else {
url.cannotBeABaseUrl = true
buffer.Reset()
state = stateCannotBeABaseUrl
}
} else if !stateOverridden {
Expand Down Expand Up @@ -602,21 +601,15 @@ func (p *parser) basicParser(urlOrRef string, base *Url, url *Url, stateOverride
if r == '?' {
url.search = new(string)
state = stateQuery
if len(url.path) == 0 {
url.path = append(url.path, "")
}
url.path[0] += buffer.String()
url.path = append(url.path, buffer.String())
buffer.Reset()
} else if r == '#' {
url.hash = new(string)
state = stateFragment
if len(url.path) == 0 {
url.path = append(url.path, "")
}
url.path[0] += buffer.String()
url.path = append(url.path, buffer.String())
buffer.Reset()
} else {
if !input.eof && !isURLCodePoint(r) && r != '%' {
} else if !input.eof {
if !isURLCodePoint(r) && r != '%' {
if err := p.handleError(url, errors.IllegalCodePoint); err != nil {
return nil, err
}
Expand All @@ -626,25 +619,19 @@ func (p *parser) basicParser(urlOrRef string, base *Url, url *Url, stateOverride
if err := p.handleError(url, errors.InvalidPercentEncoding); err != nil {
return nil, err
}
}
if !input.eof {
if invalidPercentEncoding {
buffer.WriteString(p.percentEncodeInvalidRune(r, C0PercentEncodeSet))
} else {
buffer.WriteString(p.percentEncodeRune(r, C0PercentEncodeSet))
}
buffer.WriteString(p.percentEncodeInvalidRune(r, C0PercentEncodeSet))
} else {
if len(url.path) == 0 {
url.path = append(url.path, "")
}
url.path[0] += buffer.String()
buffer.Reset()
buffer.WriteString(p.percentEncodeRune(r, C0PercentEncodeSet))
}
} else {
url.path = append(url.path, buffer.String())
}
case stateQuery:
if !stateOverridden && r == '#' {
url.hash = new(string)
state = stateFragment
*url.search = buffer.String()
buffer.Reset()
} else if !input.eof {
if !isURLCodePoint(r) && r != '%' {
if err := p.handleError(url, errors.IllegalCodePoint); err != nil {
Expand All @@ -660,7 +647,9 @@ func (p *parser) basicParser(urlOrRef string, base *Url, url *Url, stateOverride
if url.isSpecialScheme(url.protocol) {
encodeSet = p.opts.specialQueryPercentEncodeSet
}
*url.search += p.percentEncodeRune(r, encodeSet)
buffer.WriteString(p.percentEncodeRune(r, encodeSet))
} else {
*url.search = buffer.String()
}
case stateFragment:
if !input.eof {
Expand All @@ -678,7 +667,9 @@ func (p *parser) basicParser(urlOrRef string, base *Url, url *Url, stateOverride
if url.isSpecialScheme(url.protocol) {
encodeSet = p.opts.specialFragmentPercentEncodeSet
}
*url.hash += p.percentEncodeRune(r, encodeSet)
buffer.WriteString(p.percentEncodeRune(r, encodeSet))
} else {
*url.hash = buffer.String()
}
}

Expand Down
19 changes: 19 additions & 0 deletions url/url_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -629,3 +629,22 @@ func BenchmarkIssue6(b *testing.B) {
})
}
}

func BenchmarkIssue8(b *testing.B) {
// https://github.com/nlnwa/whatwg-url/issues/8
for i := 10; i <= 20; i++ {
n := 1 << i
b.Run(fmt.Sprint(n), func(b *testing.B) {
var buf strings.Builder
buf.Grow(n + 32)
buf.WriteString("http://example.com/?foo=bar")
for j := 0; j <= n; j++ {
buf.WriteString("&foo=bar")
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = Parse(buf.String())
}
})
}
}

0 comments on commit 9a67708

Please sign in to comment.