~mna/zerojson

ed5a12789e4f0f4051d184fd9e78cddb1a0a8821 — Martin Angers 1 year, 23 days ago 2dfbb18
exit with ErrUnexpectedEOF on incomplete objects
2 files changed, 23 insertions(+), 6 deletions(-)

M zerojson.go
M zerojson_test.go
M zerojson.go => zerojson.go +21 -5
@@ 156,6 156,8 @@ type parser struct {
}

func (p *parser) parse() error {
	finalErr := io.EOF

	// bootstrap execution
	p.pos = -1
	p.advance()


@@ 169,13 171,13 @@ loop:
			err error
		)

		start := p.pos
		start, atEOF := p.pos, p.eof()
		typ = p.cur
		p.advance()

		if p.debug {
			peek := p.stack.peek()
			fmt.Printf("%d: stack=%c ; allow=%c ; char=%c\n", start, peek, typ, p.allow)
			fmt.Printf("%d: stack=%c ; allow=%c ; atEOF=%t ; char=%c\n", start, peek, p.allow, atEOF, typ)
		}

		switch p.allow {


@@ 184,6 186,10 @@ loop:
				p.allow = '>'
				continue
			}
			if atEOF {
				finalErr = io.ErrUnexpectedEOF
				break loop
			}
			err = ErrInvalidCodePoint

		case ',':


@@ 208,6 214,10 @@ loop:
					p.allow = 0
				}
			} else {
				if atEOF {
					finalErr = io.ErrUnexpectedEOF
					break loop
				}
				err = ErrInvalidCodePoint
			}



@@ 228,6 238,10 @@ loop:
				}

			default:
				if atEOF {
					finalErr = io.ErrUnexpectedEOF
					break loop
				}
				err = ErrInvalidCodePoint
			}



@@ 270,8 284,10 @@ loop:
				err = p.scanToken(nullTrail)

			default:
				if p.eof() {
					// TODO: if a token was required, error
				if atEOF {
					if p.allow == '>' {
						finalErr = io.ErrUnexpectedEOF
					}
					break loop
				}
				err = ErrInvalidCodePoint


@@ 282,7 298,7 @@ loop:
			return e
		}
	}
	return p.emit(p.pos, p.cur, nil, io.EOF)
	return p.emit(p.pos, p.cur, nil, finalErr)
}

func (p *parser) scanNumber(first byte) error {

M zerojson_test.go => zerojson_test.go +2 -1
@@ 164,7 164,7 @@ func TestParser(t *testing.T) {
7: }: }
`, nil},

		{"{", "0: {: {", nil},
		{"{", "0: {: {\n2: \x00:", io.ErrUnexpectedEOF},
	}

	for _, c := range cases {


@@ 180,6 180,7 @@ func TestParser(t *testing.T) {
					fmt.Fprintf(&buf, "%d: %c: %s\n", offset, typ, string(v))
					return err
				},
				debug: true,
			}
			err := p.parse()
			require.Equal(t, strings.TrimSpace(c.out), strings.TrimSpace(buf.String()))