Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panics found through fuzzing #32

Closed
mstoykov opened this issue Oct 6, 2020 · 2 comments
Closed

Panics found through fuzzing #32

mstoykov opened this issue Oct 6, 2020 · 2 comments

Comments

@mstoykov
Copy link
Contributor

mstoykov commented Oct 6, 2020

Here is a small script reproducing a panic that I found while fuzzing:
Notes:

  • those were the more readable examples (without strange non printable characters)
  • I use []byte mostly because it makes the copying between output and program easier
package main

import (
	"fmt"
	"runtime/debug"

	"github.com/dlclark/regexp2"
)

var testCases = []struct {
	r, s []byte
}{
	{
		s: []byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
		r: []byte{0x28, 0x28, 0x29, 0x5c, 0x37, 0x28, 0x3f, 0x28, 0x29, 0x29},
	},
	{
		r: []byte{0x28, 0x5c, 0x32, 0x28, 0x3f, 0x28, 0x30, 0x29, 0x29},
		s: []byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
	},
	{
		r: []byte{0x28, 0x3f, 0x28, 0x29, 0x29, 0x5c, 0x31, 0x30, 0x28, 0x3f, 0x28, 0x30, 0x29},
		s: []byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
	},

	{
		r: []byte{0x28, 0x29, 0x28, 0x28, 0x29, 0x5c, 0x37, 0x28, 0x3f, 0x28, 0x29, 0x29},
		s: []byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
	},
}

func test(r, s []byte) (b bool) {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println(r)
			debug.PrintStack()
			b = true
		}
	}()

	re, err := regexp2.Compile(string(r), regexp2.ECMAScript|regexp2.Multiline)
	if err != nil {
		return false
	}
	_, _ = re.FindStringMatch(string(s))
	return false
}

func main() {
	for _, c := range testCases {
		fmt.Println("#############################################################################")
		if test(c.r, c.s) {
			fmt.Printf("Test case regex='%#v', string='%#v' panics\nstring values '%s', '%s'\n",
				c.r, c.s, string(c.r), string(c.s),
			)
		} else {
			fmt.Printf("Test case regex='%#v', string='%#v' DOES NOT panic\nstring values '%s', '%s'\n",
				c.r, c.s, string(c.r), string(c.s),
			)
		}
	}
}

Output is

#############################################################################
runtime error: index out of range [3] with length 3
goroutine 1 [running]:
runtime/debug.Stack(0x34, 0x0, 0x0)
	runtime/debug/stack.go:24 +0x9d
runtime/debug.PrintStack()
	runtime/debug/stack.go:16 +0x22
main.test.func1(0xc000083e38)
	command-line-arguments/test.go:36 +0x97
panic(0x4f0c20, 0xc0000162a0)
	runtime/panic.go:969 +0x166
github.com/dlclark/regexp2.(*Match).addMatch(0xc0000d6000, 0x3, 0x1, 0x0)
	github.com/dlclark/regexp2/match.go:170 +0x31c
github.com/dlclark/regexp2.(*runner).capture(0xc0000d4000, 0x3, 0x1, 0x1)
	github.com/dlclark/regexp2/runner.go:1420 +0x9e
github.com/dlclark/regexp2.(*runner).execute(0xc0000d4000, 0x0, 0x0)
	github.com/dlclark/regexp2/runner.go:254 +0x276e
github.com/dlclark/regexp2.(*runner).scan(0xc0000d4000, 0xc000018150, 0x9, 0xc, 0x0, 0x0, 0x7fffffffffffffff, 0x9, 0xc, 0x4490be)
	github.com/dlclark/regexp2/runner.go:144 +0x1c3
github.com/dlclark/regexp2.(*Regexp).run(0xc0000d2080, 0xc000083d00, 0xffffffffffffffff, 0xc000018150, 0x9, 0xc, 0x0, 0x0, 0x0)
	github.com/dlclark/regexp2/runner.go:91 +0xf0
github.com/dlclark/regexp2.(*Regexp).FindStringMatch(...)
	github.com/dlclark/regexp2/regexp.go:159
main.test(0x5b91b8, 0xa, 0xa, 0x5b9188, 0x9, 0x9, 0x0)
	command-line-arguments/test.go:45 +0x168
main.main()
	command-line-arguments/test.go:52 +0x174
Test case regex='[]byte{0x28, 0x28, 0x29, 0x5c, 0x37, 0x28, 0x3f, 0x28, 0x29, 0x29}', string='[]byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}' panics
string values '(()\7(?())', '000000000'
#############################################################################
runtime error: index out of range [2] with length 2
goroutine 1 [running]:
runtime/debug.Stack(0x34, 0x0, 0x0)
	runtime/debug/stack.go:24 +0x9d
runtime/debug.PrintStack()
	runtime/debug/stack.go:16 +0x22
main.test.func1(0xc000083e38)
	command-line-arguments/test.go:36 +0x97
panic(0x4f0c20, 0xc0000162c0)
	runtime/panic.go:969 +0x166
github.com/dlclark/regexp2.(*Match).addMatch(0xc0000d60e0, 0x2, 0x0, 0x1)
	github.com/dlclark/regexp2/match.go:170 +0x31c
github.com/dlclark/regexp2.(*runner).capture(0xc0000d4100, 0x2, 0x0, 0x1)
	github.com/dlclark/regexp2/runner.go:1420 +0x9e
github.com/dlclark/regexp2.(*runner).execute(0xc0000d4100, 0x0, 0x0)
	github.com/dlclark/regexp2/runner.go:254 +0x276e
github.com/dlclark/regexp2.(*runner).scan(0xc0000d4100, 0xc0000181b0, 0x9, 0xc, 0x0, 0x0, 0x7fffffffffffffff, 0x9, 0xc, 0x4490be)
	github.com/dlclark/regexp2/runner.go:144 +0x1c3
github.com/dlclark/regexp2.(*Regexp).run(0xc0000d2180, 0xc000083d00, 0xffffffffffffffff, 0xc0000181b0, 0x9, 0xc, 0x0, 0x0, 0x0)
	github.com/dlclark/regexp2/runner.go:91 +0xf0
github.com/dlclark/regexp2.(*Regexp).FindStringMatch(...)
	github.com/dlclark/regexp2/regexp.go:159
main.test(0x5b9198, 0x9, 0x9, 0x5b91a8, 0x9, 0x9, 0x0)
	command-line-arguments/test.go:45 +0x168
main.main()
	command-line-arguments/test.go:52 +0x174
Test case regex='[]byte{0x28, 0x5c, 0x32, 0x28, 0x3f, 0x28, 0x30, 0x29, 0x29}', string='[]byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}' panics
string values '(\2(?(0))', '000000000'
#############################################################################
runtime error: index out of range [1] with length 1
goroutine 1 [running]:
runtime/debug.Stack(0x34, 0x0, 0x0)
	runtime/debug/stack.go:24 +0x9d
runtime/debug.PrintStack()
	runtime/debug/stack.go:16 +0x22
main.test.func1(0xc000083e38)
	command-line-arguments/test.go:36 +0x97
panic(0x4f0c20, 0xc0000162e0)
	runtime/panic.go:969 +0x166
github.com/dlclark/regexp2.(*Match).addMatch(0xc0000d61c0, 0x1, 0x0, 0x1)
	github.com/dlclark/regexp2/match.go:170 +0x31c
github.com/dlclark/regexp2.(*runner).capture(0xc0000d4200, 0x1, 0x0, 0x1)
	github.com/dlclark/regexp2/runner.go:1420 +0x9e
github.com/dlclark/regexp2.(*runner).execute(0xc0000d4200, 0x0, 0x0)
	github.com/dlclark/regexp2/runner.go:254 +0x276e
github.com/dlclark/regexp2.(*runner).scan(0xc0000d4200, 0xc0000281c0, 0xd, 0x10, 0x0, 0x0, 0x7fffffffffffffff, 0xd, 0x10, 0x4490be)
	github.com/dlclark/regexp2/runner.go:144 +0x1c3
github.com/dlclark/regexp2.(*Regexp).run(0xc0000d2280, 0xc000083d00, 0xffffffffffffffff, 0xc0000281c0, 0xd, 0x10, 0x0, 0x0, 0x0)
	github.com/dlclark/regexp2/runner.go:91 +0xf0
github.com/dlclark/regexp2.(*Regexp).FindStringMatch(...)
	github.com/dlclark/regexp2/regexp.go:159
main.test(0x5b9588, 0xd, 0xd, 0x5b9598, 0xd, 0xd, 0x0)
	command-line-arguments/test.go:45 +0x168
main.main()
	command-line-arguments/test.go:52 +0x174
Test case regex='[]byte{0x28, 0x3f, 0x28, 0x29, 0x29, 0x5c, 0x31, 0x30, 0x28, 0x3f, 0x28, 0x30, 0x29}', string='[]byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}' panics
string values '(?())\10(?(0)', '0000000000000'
#############################################################################
runtime error: index out of range [4] with length 4
goroutine 1 [running]:
runtime/debug.Stack(0x34, 0x0, 0x0)
	runtime/debug/stack.go:24 +0x9d
runtime/debug.PrintStack()
	runtime/debug/stack.go:16 +0x22
main.test.func1(0xc000083e38)
	command-line-arguments/test.go:36 +0x97
panic(0x4f0c20, 0xc000016320)
	runtime/panic.go:969 +0x166
github.com/dlclark/regexp2.(*Match).addMatch(0xc0000d62a0, 0x4, 0x1, 0x0)
	github.com/dlclark/regexp2/match.go:170 +0x31c
github.com/dlclark/regexp2.(*runner).capture(0xc0000d4300, 0x4, 0x1, 0x1)
	github.com/dlclark/regexp2/runner.go:1420 +0x9e
github.com/dlclark/regexp2.(*runner).execute(0xc0000d4300, 0x0, 0x0)
	github.com/dlclark/regexp2/runner.go:254 +0x276e
github.com/dlclark/regexp2.(*runner).scan(0xc0000d4300, 0xc000018210, 0xc, 0xc, 0x0, 0x0, 0x7fffffffffffffff, 0xc, 0xc, 0x4490be)
	github.com/dlclark/regexp2/runner.go:144 +0x1c3
github.com/dlclark/regexp2.(*Regexp).run(0xc0000d2380, 0xc000083d00, 0xffffffffffffffff, 0xc000018210, 0xc, 0xc, 0x0, 0x0, 0x0)
	github.com/dlclark/regexp2/runner.go:91 +0xf0
github.com/dlclark/regexp2.(*Regexp).FindStringMatch(...)
	github.com/dlclark/regexp2/regexp.go:159
main.test(0x5b91c8, 0xc, 0xc, 0x5b91d8, 0xc, 0xc, 0x0)
	command-line-arguments/test.go:45 +0x168
main.main()
	command-line-arguments/test.go:52 +0x174
Test case regex='[]byte{0x28, 0x29, 0x28, 0x28, 0x29, 0x5c, 0x37, 0x28, 0x3f, 0x28, 0x29, 0x29}', string='[]byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}' panics
string values '()(()\7(?())', '000000000000'
@mstoykov mstoykov changed the title Panics foudn through fuzzing Panics found through fuzzing Oct 6, 2020
@dlclark
Copy link
Owner

dlclark commented Oct 6, 2020

Thanks! I’m traveling this week so it may be a little bit before I get to this.

@dlclark dlclark closed this as completed in 955551b Oct 7, 2020
@dlclark
Copy link
Owner

dlclark commented Oct 7, 2020

All of these were errors because of an octal parsing bug for the \2( or \7( part of the pattern. These now all correctly give an error on parsing now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants