ed5a12789e4f0f4051d184fd9e78cddb1a0a8821 — Martin Angers 5 months 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 @@ }
  
  func (p *parser) parse() error {
+ 	finalErr := io.EOF
+ 
  	// bootstrap execution
  	p.pos = -1
  	p.advance()


@@ 169,13 171,13 @@ 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 @@ p.allow = '>'
  				continue
  			}
+ 			if atEOF {
+ 				finalErr = io.ErrUnexpectedEOF
+ 				break loop
+ 			}
  			err = ErrInvalidCodePoint
  
  		case ',':


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


@@ 228,6 238,10 @@ }
  
  			default:
+ 				if atEOF {
+ 					finalErr = io.ErrUnexpectedEOF
+ 					break loop
+ 				}
  				err = ErrInvalidCodePoint
  			}
  


@@ 270,8 284,10 @@ 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 @@ 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 @@ 7: }: }
  `, nil},
  
- 		{"{", "0: {: {", nil},
+ 		{"{", "0: {: {\n2: \x00:", io.ErrUnexpectedEOF},
  	}
  
  	for _, c := range cases {


@@ 180,6 180,7 @@ 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()))