VKCOM / noverify

Pretty fast linter (code static analysis utility) for PHP
MIT License
673 stars 57 forks source link

Panic on exclamation in doc string #1154

Closed NickMolloy closed 3 years ago

NickMolloy commented 3 years ago

PHP Version: 7.4

OS: Linux

Run command:

./noverify check example.php

The minimal code in which the bug appears:

<?php

/**
 * @param '!
 */

Actual Behavior:

23:51:10 Started
23:51:10 Indexing [example.php]
23:51:10 Panic while parsing /example/example.php: runtime error: invalid memory address or nil pointer dereference

Stack trace: goroutine 77 [running]:
runtime/debug.Stack(0xc005cb2198, 0xabc440, 0x1140f70)
    /opt/homebrew/Cellar/go/1.16.6/libexec/src/runtime/debug/stack.go:24 +0x9f
github.com/VKCOM/noverify/src/linter.(*Worker).ParseContents.func1(0xc0076f4360, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc005cb3a40)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:95 +0x76
panic(0xabc440, 0x1140f70)
    /opt/homebrew/Cellar/go/1.16.6/libexec/src/runtime/panic.go:965 +0x1b9
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).newExpr(0xc004f7cb00, 0x20001000b, 0xc000692550, 0x1, 0x1, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:417 +0x152
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).parseExpr(0xc004f7cb00, 0x0, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:248 +0x120a
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).parseExpr(0xc004f7cb00, 0x0, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:273 +0xfa5
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).Parse(0xc004f7cb00, 0xc004fb5886, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:174 +0xb4
github.com/VKCOM/noverify/src/phpdoc.nextTypeField(0xc004f7cb00, 0xc004fb5886, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/phpdoc/parser.go:214 +0x85
github.com/VKCOM/noverify/src/phpdoc.parseTypeVarComment(0xc004f7cb00, 0x2, 0xc004fb5880, 0x5, 0xc004fb5886, 0x2, 0xc007425230)
    /Users/petrmakhnev/noverify-2/src/phpdoc/parser.go:195 +0x2eb
github.com/VKCOM/noverify/src/phpdoc.Parse(0xc004f7cb00, 0xc004fb5878, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/parser.go:147 +0x4e9
github.com/VKCOM/noverify/src/linter.(*rootWalker).handleCommentToken(0xc00053b380, 0xc005af80c0, 0x40db01)
    /Users/petrmakhnev/noverify-2/src/linter/root.go:332 +0xb3
github.com/VKCOM/noverify/src/ir.traverseToken(0xc005af80c0, 0xc004f750b0, 0x1)
    /Users/petrmakhnev/noverify-2/src/ir/utils.go:18 +0x3d
github.com/VKCOM/noverify/src/ir.traverseToken(0xc005af8000, 0xc004f750b0, 0xc004f750b0)
    /Users/petrmakhnev/noverify-2/src/ir/utils.go:23 +0x93
github.com/VKCOM/noverify/src/ir.(*Root).IterateTokens(0xc007425170, 0xc004f750b0)
    /Users/petrmakhnev/noverify-2/src/ir/iterate.go:1314 +0x39
github.com/VKCOM/noverify/src/linter.(*rootWalker).EnterNode(0xc00053b380, 0xc75838, 0xc007425170, 0x58)
    /Users/petrmakhnev/noverify-2/src/linter/root.go:130 +0x111
github.com/VKCOM/noverify/src/ir.(*Root).Walk(0xc007425170, 0xc75e78, 0xc00053b380)
    /Users/petrmakhnev/noverify-2/src/ir/walk.go:1529 +0x4b
github.com/VKCOM/noverify/src/linter.(*Worker).analyzeFile(0xc003c36eb0, 0xc000035620, 0xc007425170, 0x1d, 0x1d, 0xc000035620)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:302 +0x4e5
github.com/VKCOM/noverify/src/linter.(*Worker).ParseContents(0xc003c36eb0, 0xc0076f4360, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:143 +0x5ce
github.com/VKCOM/noverify/src/linter.(*Worker).parseWithCache(0xc003c36eb0, 0xc0086ca1e0, 0x5e, 0xc0076f4360, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:161 +0x93
github.com/VKCOM/noverify/src/linter.(*Worker).IndexFile(0xc003c36eb0, 0xc0076f4360, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:216 +0x66c
github.com/VKCOM/noverify/src/linter.(*Worker).doParseFile(0xc003c36eb0, 0xc0076f4360, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:251 +0x525
github.com/VKCOM/noverify/src/linter.(*Linter).analyzeFiles.func3(0xc000035100, 0xc000112060, 0x0, 0xc000035140, 0xc0000351a0, 0xc005938c30, 0xb)
    /Users/petrmakhnev/noverify-2/src/linter/linter.go:104 +0x21e
created by github.com/VKCOM/noverify/src/linter.(*Linter).analyzeFiles
    /Users/petrmakhnev/noverify-2/src/linter/linter.go:94 +0x25f
23:51:10 Failed parsing /example/example.php: Panic while parsing /example/example.php: runtime error: invalid memory address or nil pointer dereference

Stack trace: goroutine 77 [running]:
runtime/debug.Stack(0xc005cb2198, 0xabc440, 0x1140f70)
    /opt/homebrew/Cellar/go/1.16.6/libexec/src/runtime/debug/stack.go:24 +0x9f
github.com/VKCOM/noverify/src/linter.(*Worker).ParseContents.func1(0xc0076f4360, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc005cb3a40)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:95 +0x76
panic(0xabc440, 0x1140f70)
    /opt/homebrew/Cellar/go/1.16.6/libexec/src/runtime/panic.go:965 +0x1b9
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).newExpr(0xc004f7cb00, 0x20001000b, 0xc000692550, 0x1, 0x1, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:417 +0x152
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).parseExpr(0xc004f7cb00, 0x0, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:248 +0x120a
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).parseExpr(0xc004f7cb00, 0x0, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:273 +0xfa5
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).Parse(0xc004f7cb00, 0xc004fb5886, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:174 +0xb4
github.com/VKCOM/noverify/src/phpdoc.nextTypeField(0xc004f7cb00, 0xc004fb5886, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/phpdoc/parser.go:214 +0x85
github.com/VKCOM/noverify/src/phpdoc.parseTypeVarComment(0xc004f7cb00, 0x2, 0xc004fb5880, 0x5, 0xc004fb5886, 0x2, 0xc007425230)
    /Users/petrmakhnev/noverify-2/src/phpdoc/parser.go:195 +0x2eb
github.com/VKCOM/noverify/src/phpdoc.Parse(0xc004f7cb00, 0xc004fb5878, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/parser.go:147 +0x4e9
github.com/VKCOM/noverify/src/linter.(*rootWalker).handleCommentToken(0xc00053b380, 0xc005af80c0, 0x40db01)
    /Users/petrmakhnev/noverify-2/src/linter/root.go:332 +0xb3
github.com/VKCOM/noverify/src/ir.traverseToken(0xc005af80c0, 0xc004f750b0, 0x1)
    /Users/petrmakhnev/noverify-2/src/ir/utils.go:18 +0x3d
github.com/VKCOM/noverify/src/ir.traverseToken(0xc005af8000, 0xc004f750b0, 0xc004f750b0)
    /Users/petrmakhnev/noverify-2/src/ir/utils.go:23 +0x93
github.com/VKCOM/noverify/src/ir.(*Root).IterateTokens(0xc007425170, 0xc004f750b0)
    /Users/petrmakhnev/noverify-2/src/ir/iterate.go:1314 +0x39
github.com/VKCOM/noverify/src/linter.(*rootWalker).EnterNode(0xc00053b380, 0xc75838, 0xc007425170, 0x58)
    /Users/petrmakhnev/noverify-2/src/linter/root.go:130 +0x111
github.com/VKCOM/noverify/src/ir.(*Root).Walk(0xc007425170, 0xc75e78, 0xc00053b380)
    /Users/petrmakhnev/noverify-2/src/ir/walk.go:1529 +0x4b
github.com/VKCOM/noverify/src/linter.(*Worker).analyzeFile(0xc003c36eb0, 0xc000035620, 0xc007425170, 0x1d, 0x1d, 0xc000035620)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:302 +0x4e5
github.com/VKCOM/noverify/src/linter.(*Worker).ParseContents(0xc003c36eb0, 0xc0076f4360, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:143 +0x5ce
github.com/VKCOM/noverify/src/linter.(*Worker).parseWithCache(0xc003c36eb0, 0xc0086ca1e0, 0x5e, 0xc0076f4360, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:161 +0x93
github.com/VKCOM/noverify/src/linter.(*Worker).IndexFile(0xc003c36eb0, 0xc0076f4360, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:216 +0x66c
github.com/VKCOM/noverify/src/linter.(*Worker).doParseFile(0xc003c36eb0, 0xc0076f4360, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:251 +0x525
github.com/VKCOM/noverify/src/linter.(*Linter).analyzeFiles.func3(0xc000035100, 0xc000112060, 0x0, 0xc000035140, 0xc0000351a0, 0xc005938c30, 0xb)
    /Users/petrmakhnev/noverify-2/src/linter/linter.go:104 +0x21e
created by github.com/VKCOM/noverify/src/linter.(*Linter).analyzeFiles
    /Users/petrmakhnev/noverify-2/src/linter/linter.go:94 +0x25f
23:51:10 Linting
23:51:10 Panic while parsing /example/example.php: runtime error: invalid memory address or nil pointer dereference

Stack trace: goroutine 90 [running]:
runtime/debug.Stack(0xc005cb6488, 0xabc440, 0x1140f70)
    /opt/homebrew/Cellar/go/1.16.6/libexec/src/runtime/debug/stack.go:24 +0x9f
github.com/VKCOM/noverify/src/linter.(*Worker).ParseContents.func1(0xc007403640, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc005cb7d30)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:95 +0x76
panic(0xabc440, 0x1140f70)
    /opt/homebrew/Cellar/go/1.16.6/libexec/src/runtime/panic.go:965 +0x1b9
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).newExpr(0xc004f7cb80, 0x20001000b, 0xc000592840, 0x1, 0x1, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:417 +0x152
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).parseExpr(0xc004f7cb80, 0x0, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:248 +0x120a
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).parseExpr(0xc004f7cb80, 0x0, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:273 +0xfa5
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).Parse(0xc004f7cb80, 0xc005c9eb1e, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:174 +0xb4
github.com/VKCOM/noverify/src/phpdoc.nextTypeField(0xc004f7cb80, 0xc005c9eb1e, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/phpdoc/parser.go:214 +0x85
github.com/VKCOM/noverify/src/phpdoc.parseTypeVarComment(0xc004f7cb80, 0x2, 0xc005c9eb18, 0x5, 0xc005c9eb1e, 0x2, 0xc004235f50)
    /Users/petrmakhnev/noverify-2/src/phpdoc/parser.go:195 +0x2eb
github.com/VKCOM/noverify/src/phpdoc.Parse(0xc004f7cb80, 0xc005c9eb10, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/parser.go:147 +0x4e9
github.com/VKCOM/noverify/src/linter.(*rootWalker).handleCommentToken(0xc000602300, 0xc005b080c0, 0x40db01)
    /Users/petrmakhnev/noverify-2/src/linter/root.go:332 +0xb3
github.com/VKCOM/noverify/src/ir.traverseToken(0xc005b080c0, 0xc0046b7f70, 0x1)
    /Users/petrmakhnev/noverify-2/src/ir/utils.go:18 +0x3d
github.com/VKCOM/noverify/src/ir.traverseToken(0xc005b08000, 0xc0046b7f70, 0xc0046b7f70)
    /Users/petrmakhnev/noverify-2/src/ir/utils.go:23 +0x93
github.com/VKCOM/noverify/src/ir.(*Root).IterateTokens(0xc004235e90, 0xc0046b7f70)
    /Users/petrmakhnev/noverify-2/src/ir/iterate.go:1314 +0x39
github.com/VKCOM/noverify/src/linter.(*rootWalker).EnterNode(0xc000602300, 0xc75838, 0xc004235e90, 0x58)
    /Users/petrmakhnev/noverify-2/src/linter/root.go:130 +0x111
github.com/VKCOM/noverify/src/ir.(*Root).Walk(0xc004235e90, 0xc75e78, 0xc000602300)
    /Users/petrmakhnev/noverify-2/src/ir/walk.go:1529 +0x4b
github.com/VKCOM/noverify/src/linter.(*Worker).analyzeFile(0xc003c370e0, 0xc0006e0300, 0xc004235e90, 0x1d, 0x1d, 0xc0006e0300)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:302 +0x4e5
github.com/VKCOM/noverify/src/linter.(*Worker).ParseContents(0xc003c370e0, 0xc007403640, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:143 +0x5ce
github.com/VKCOM/noverify/src/linter.(*Worker).doParseFile(0xc003c370e0, 0xc007403640, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:246 +0x11b
github.com/VKCOM/noverify/src/linter.(*Linter).analyzeFiles.func3(0xc000035901, 0xc000112060, 0x0, 0xc000035860, 0xc000035920, 0xc005938cb0, 0xb)
    /Users/petrmakhnev/noverify-2/src/linter/linter.go:104 +0x21e
created by github.com/VKCOM/noverify/src/linter.(*Linter).analyzeFiles
    /Users/petrmakhnev/noverify-2/src/linter/linter.go:94 +0x25f
23:51:10 Failed parsing /example/example.php: Panic while parsing /example/example.php: runtime error: invalid memory address or nil pointer dereference

Stack trace: goroutine 90 [running]:
runtime/debug.Stack(0xc005cb6488, 0xabc440, 0x1140f70)
    /opt/homebrew/Cellar/go/1.16.6/libexec/src/runtime/debug/stack.go:24 +0x9f
github.com/VKCOM/noverify/src/linter.(*Worker).ParseContents.func1(0xc007403640, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc005cb7d30)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:95 +0x76
panic(0xabc440, 0x1140f70)
    /opt/homebrew/Cellar/go/1.16.6/libexec/src/runtime/panic.go:965 +0x1b9
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).newExpr(0xc004f7cb80, 0x20001000b, 0xc000592840, 0x1, 0x1, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:417 +0x152
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).parseExpr(0xc004f7cb80, 0x0, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:248 +0x120a
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).parseExpr(0xc004f7cb80, 0x0, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:273 +0xfa5
github.com/VKCOM/noverify/src/phpdoc.(*TypeParser).Parse(0xc004f7cb80, 0xc005c9eb1e, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/phpdoc/type_parser.go:174 +0xb4
github.com/VKCOM/noverify/src/phpdoc.nextTypeField(0xc004f7cb80, 0xc005c9eb1e, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/phpdoc/parser.go:214 +0x85
github.com/VKCOM/noverify/src/phpdoc.parseTypeVarComment(0xc004f7cb80, 0x2, 0xc005c9eb18, 0x5, 0xc005c9eb1e, 0x2, 0xc004235f50)
    /Users/petrmakhnev/noverify-2/src/phpdoc/parser.go:195 +0x2eb
github.com/VKCOM/noverify/src/phpdoc.Parse(0xc004f7cb80, 0xc005c9eb10, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/petrmakhnev/noverify-2/src/phpdoc/parser.go:147 +0x4e9
github.com/VKCOM/noverify/src/linter.(*rootWalker).handleCommentToken(0xc000602300, 0xc005b080c0, 0x40db01)
    /Users/petrmakhnev/noverify-2/src/linter/root.go:332 +0xb3
github.com/VKCOM/noverify/src/ir.traverseToken(0xc005b080c0, 0xc0046b7f70, 0x1)
    /Users/petrmakhnev/noverify-2/src/ir/utils.go:18 +0x3d
github.com/VKCOM/noverify/src/ir.traverseToken(0xc005b08000, 0xc0046b7f70, 0xc0046b7f70)
    /Users/petrmakhnev/noverify-2/src/ir/utils.go:23 +0x93
github.com/VKCOM/noverify/src/ir.(*Root).IterateTokens(0xc004235e90, 0xc0046b7f70)
    /Users/petrmakhnev/noverify-2/src/ir/iterate.go:1314 +0x39
github.com/VKCOM/noverify/src/linter.(*rootWalker).EnterNode(0xc000602300, 0xc75838, 0xc004235e90, 0x58)
    /Users/petrmakhnev/noverify-2/src/linter/root.go:130 +0x111
github.com/VKCOM/noverify/src/ir.(*Root).Walk(0xc004235e90, 0xc75e78, 0xc000602300)
    /Users/petrmakhnev/noverify-2/src/ir/walk.go:1529 +0x4b
github.com/VKCOM/noverify/src/linter.(*Worker).analyzeFile(0xc003c370e0, 0xc0006e0300, 0xc004235e90, 0x1d, 0x1d, 0xc0006e0300)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:302 +0x4e5
github.com/VKCOM/noverify/src/linter.(*Worker).ParseContents(0xc003c370e0, 0xc007403640, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:143 +0x5ce
github.com/VKCOM/noverify/src/linter.(*Worker).doParseFile(0xc003c370e0, 0xc007403640, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/petrmakhnev/noverify-2/src/linter/worker.go:246 +0x11b
github.com/VKCOM/noverify/src/linter.(*Linter).analyzeFiles.func3(0xc000035901, 0xc000112060, 0x0, 0xc000035860, 0xc000035920, 0xc005938cb0, 0xb)
    /Users/petrmakhnev/noverify-2/src/linter/linter.go:104 +0x21e
created by github.com/VKCOM/noverify/src/linter.(*Linter).analyzeFiles
    /Users/petrmakhnev/noverify-2/src/linter/linter.go:94 +0x25f
23:51:10 No issues found. Your code is perfect.

Details:

This was encountered on an actual program that contain PHPUnit 9.5 as a dependency. The offending code can be seen here.

i582 commented 3 years ago

Hey It looks like a type parsing bug when defining a union of literals.

/*
 * @param 'a'|'b'|'c'
 */

Thanks for reporting, I will fix this bug shortly.

i582 commented 3 years ago

Thanks for reporting the bug! It is fixed in #1161.