Skip to content

Commit c98a149

Browse files
n-peugnetbzick
authored andcommitted
Fix reusing a *Tokenizer after an empty stream has been closed
When parsing an empty reader, Stream.head does not get allocated by the pool at any time and holds a pointer to undefToken. Previously, on Stream.Close() it was released to the pool, which added the pointer to undefToken to the pool. As the next call to ParseStream() has to allocate a new token for the first keyword, it got it from the pool and received the last released token, which was the pointer to undefToken. Finally when Stream.IsValid() checked if Stream.head == undefToken, this evaluated to true, and returned false. Now, to make sure that we never release a pointer to undefToken into the pool, we add a check for this in Stream.Close(). Closes: #30
1 parent 3c29bb0 commit c98a149

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

stream.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func (s *Stream) SetHistorySize(size int) *Stream {
6767

6868
// Close releases all token objects to pool
6969
func (s *Stream) Close() {
70-
for ptr := s.head; ptr != nil; {
70+
for ptr := s.head; ptr != nil && ptr != undefToken; {
7171
p := ptr.next
7272
s.t.freeToken(ptr)
7373
ptr = p

stream_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,29 @@ func TestIssue26(t *testing.T) {
286286
}
287287
}
288288

289+
// TestIssue30 second use of ParseStream() after a first closed empty stream,
290+
// produces an incorrectly invalid stream.
291+
func TestIssue30(t *testing.T) {
292+
parser := New()
293+
294+
// first stream is empty
295+
buf1 := bytes.NewBufferString("")
296+
stream1 := parser.ParseStream(buf1, 4096)
297+
for stream1.IsValid() {
298+
t.Error("stream1 should have been invalid from the beginning")
299+
}
300+
// closing the first stream before opening the new one
301+
stream1.Close()
302+
303+
// second stream created from the same parser
304+
buf2 := bytes.NewBufferString("hello world")
305+
stream2 := parser.ParseStream(buf2, 4096)
306+
defer stream2.Close()
307+
if !stream2.IsValid() {
308+
t.Fatal("stream2 should be valid")
309+
}
310+
}
311+
289312
func TestStreamOverflow(t *testing.T) {
290313
parser := New()
291314
buf := bytes.NewBuffer([]byte("a b c"))

0 commit comments

Comments
 (0)