Skip to content

Fix parsing deadlock #57

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

Merged
merged 1 commit into from
Feb 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions parse_json_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,14 @@ func (pj *internalParsedJson) parseMessage(msg []byte, ndjson bool) (err error)
wg.Add(1)
go func() {
defer wg.Done()
if !pj.unifiedMachine() {
if ok, done := pj.unifiedMachine(); !ok {
err = errors.New("Bad parsing while executing stage 2")
// Keep consuming...
for idx := range pj.indexChans {
if idx.index == -1 {
break
if !done {
for idx := range pj.indexChans {
if idx.index == -1 {
break
}
}
}
}
Expand All @@ -101,7 +103,7 @@ func (pj *internalParsedJson) parseMessage(msg []byte, ndjson bool) (err error)
}
return errors.New("Failed to find all structural indices for stage 1")
}
if !pj.unifiedMachine() {
if ok, _ := pj.unifiedMachine(); !ok {
// drain the channel until empty
for {
select {
Expand Down
7 changes: 6 additions & 1 deletion parse_json_amd64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -637,26 +637,31 @@ func benchmarkParseNumber(b *testing.B, neg int) {
}

func BenchmarkParseNumberFloat(b *testing.B) {
b.SetBytes(1)
for i := 0; i < b.N; i++ {
parseNumber([]byte("339.7784:"))
}
}

func BenchmarkParseAtof64FloatGolang(b *testing.B) {
b.SetBytes(1)
for i := 0; i < b.N; i++ {
strconv.ParseFloat("339.7784", 64)
}
}

func BenchmarkParseNumberFloatExp(b *testing.B) {
b.SetBytes(1)
for i := 0; i < b.N; i++ {
parseNumber([]byte("-5.09e75:"))
}
}

func BenchmarkParseNumberBig(b *testing.B) {
b.SetBytes(1)
x := []byte("123456789123456789123456789:")
for i := 0; i < b.N; i++ {
parseNumber([]byte("123456789123456789123456789:"))
parseNumber(x)
}
}

Expand Down
9 changes: 4 additions & 5 deletions stage2_build_tape_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,10 @@ func isValidNullAtom(buf []byte) bool {
return false
}

func (pj *internalParsedJson) unifiedMachine() bool {
func (pj *internalParsedJson) unifiedMachine() (ok, done bool) {
buf := pj.Message
const addOneForRoot = 1

done := false
idx := ^uint64(0) // location of the structural character in the input (buf)
offset := uint64(0) // used to contain last element of containing_scope_offset

Expand Down Expand Up @@ -433,17 +432,17 @@ succeed:

// Sanity checks
if len(pj.containingScopeOffset) != 0 {
return false
return false, done
}

pj.annotate_previousloc(offset>>retAddressShift, pj.get_current_loc()+addOneForRoot)
pj.write_tape(offset>>retAddressShift, 'r') // r is root

pj.isvalid = true
return true
return true, done

fail:
return false
return false, done
}

// structural chars here are
Expand Down