Skip to content

Commit 252675c

Browse files
committed
Tokenizers/Comment: bug fix - empty docblock
This commit fixes an edge case tokenizer bug, where a - completely empty, not even whitespace - _DocBlock_, would not be tokenized correctly. Without this commit, the `/***/` code snippet was tokenized as: ``` 13 | L10 | C 1 | CC 0 | ( 0) | T_DOC_COMMENT_OPEN_TAG | [ 5]: /***/ 14 | L10 | C 6 | CC 0 | ( 0) | T_DOC_COMMENT_CLOSE_TAG | [ 0]: ``` With the fix applied, it will be tokenized as: ``` 13 | L10 | C 1 | CC 0 | ( 0) | T_DOC_COMMENT_OPEN_TAG | [ 3]: /** 14 | L10 | C 4 | CC 0 | ( 0) | T_DOC_COMMENT_CLOSE_TAG | [ 2]: */ ```
1 parent c54cb10 commit 252675c

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

src/Tokenizers/Comment.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,16 @@ public function tokenizeString($string, $eolChar, $stackPtr)
4141
extra star when they are used for function and class comments.
4242
*/
4343

44-
$char = ($numChars - strlen(ltrim($string, '/*')));
45-
$openTag = substr($string, 0, $char);
46-
$string = ltrim($string, '/*');
44+
$char = ($numChars - strlen(ltrim($string, '/*')));
45+
$lastChars = substr($string, -2);
46+
if ($char === $numChars && $lastChars === '*/') {
47+
// Edge case: docblock without whitespace or contents.
48+
$openTag = substr($string, 0, -2);
49+
$string = $lastChars;
50+
} else {
51+
$openTag = substr($string, 0, $char);
52+
$string = ltrim($string, '/*');
53+
}
4754

4855
$tokens[$stackPtr] = [
4956
'content' => $openTag,

tests/Core/Tokenizer/Comment/SingleLineDocBlockTest.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
/* testEmptyBlockCommentNoWhiteSpace */
44
/**/
55

6+
/* testEmptyDocblockNoWhiteSpace */
7+
/***/
8+
69
/* testEmptyDocblockWithWhiteSpace */
710
/** */
811

tests/Core/Tokenizer/Comment/SingleLineDocBlockTest.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ final class SingleLineDocBlockTest extends CommentTestCase
2828
public static function dataDocblockOpenerCloser()
2929
{
3030
return [
31+
'Single line docblock: empty, no whitespace' => [
32+
'marker' => '/* testEmptyDocblockNoWhiteSpace */',
33+
'closerOffset' => 1,
34+
'expectedTags' => [],
35+
],
3136
'Single line docblock: only whitespace' => [
3237
'marker' => '/* testEmptyDocblockWithWhiteSpace */',
3338
'closerOffset' => 2,
@@ -79,12 +84,31 @@ public function testEmptyBlockCommentNoWhiteSpace()
7984

8085

8186
/**
82-
* Verify tokenization of an empty, single line DocBlock.
87+
* Verify tokenization of an empty, single line DocBlock without whitespace between the opener and closer.
8388
*
8489
* @phpcs:disable Squiz.Arrays.ArrayDeclaration.SpaceBeforeDoubleArrow -- Readability is better with alignment.
8590
*
8691
* @return void
8792
*/
93+
public function testEmptyDocblockNoWhiteSpace()
94+
{
95+
$expectedSequence = [
96+
[T_DOC_COMMENT_OPEN_TAG => '/**'],
97+
[T_DOC_COMMENT_CLOSE_TAG => '*/'],
98+
];
99+
100+
$target = $this->getTargetToken('/* '.__FUNCTION__.' */', T_DOC_COMMENT_OPEN_TAG);
101+
102+
$this->checkTokenSequence($target, $expectedSequence);
103+
104+
}//end testEmptyDocblockNoWhiteSpace()
105+
106+
107+
/**
108+
* Verify tokenization of an empty, single line DocBlock.
109+
*
110+
* @return void
111+
*/
88112
public function testEmptyDocblockWithWhiteSpace()
89113
{
90114
$expectedSequence = [

0 commit comments

Comments
 (0)