Skip to content

Commit 8ba3179

Browse files
committed
fix: Throw on tag whitespace in gherkin-32 compatibility mode
When parsing tags, we (and cucumber/gherkin) split on the `@` character. So `@some tag @values` will parse as `['@some tag', '@value']`. This may be unexpected if e.g. a user has simply missed a `@` character. Therefore cucumber/gherkin will throw if a tag contains any whitespace. Historically we have accepted this, although we have triggered a deprecation since v4.9.0. Update the parser to throw if in `gherkin-32` compatibility mode.
1 parent 0fff3ee commit 8ba3179

File tree

4 files changed

+44
-2
lines changed

4 files changed

+44
-2
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Behat Gherkin Parser.
5+
* (c) Konstantin Kudryashov <ever.zet@gmail.com>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
namespace Behat\Gherkin\Exception;
12+
13+
class InvalidTagContentException extends ParserException
14+
{
15+
public function __construct(string $tag, ?string $file)
16+
{
17+
parent::__construct(
18+
sprintf(
19+
'Tags cannot include whitespace, found "%s"%s',
20+
$tag,
21+
is_string($file)
22+
? "in file {$file}"
23+
: ''
24+
),
25+
);
26+
}
27+
}

src/GherkinCompatibilityMode.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,15 @@ public function shouldRemoveTagPrefixChar(): bool
109109
};
110110
}
111111

112+
/**
113+
* @internal
114+
*/
115+
public function shouldThrowOnWhitespaceInTag(): bool
116+
{
117+
return match ($this) {
118+
// Note, although we don't throw we have triggered an E_USER_DEPRECATED in Parser::guardTags since v4.9.0
119+
self::LEGACY => false,
120+
default => true,
121+
};
122+
}
112123
}

src/Parser.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace Behat\Gherkin;
1212

1313
use Behat\Gherkin\Exception\FilesystemException;
14+
use Behat\Gherkin\Exception\InvalidTagContentException;
1415
use Behat\Gherkin\Exception\LexerException;
1516
use Behat\Gherkin\Exception\NodeException;
1617
use Behat\Gherkin\Exception\ParserException;
@@ -584,8 +585,12 @@ protected function guardTags(array $tags)
584585
{
585586
foreach ($tags as $tag) {
586587
if (preg_match('/\s/', $tag)) {
588+
if ($this->compatibilityMode->shouldThrowOnWhitespaceInTag()) {
589+
throw new InvalidTagContentException($tag, $this->file);
590+
}
591+
587592
trigger_error(
588-
sprintf('Whitespace in tags is deprecated, found "%s"', $tag),
593+
sprintf('Whitespace in tags is deprecated, found "%s" in %s', $tag, $this->file ?? 'unknown file'),
589594
E_USER_DEPRECATED
590595
);
591596
}

tests/Cucumber/CompatibilityTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ class CompatibilityTest extends TestCase
9191
'whitespace_in_tags.feature' => '/Whitespace in tags is deprecated/',
9292
],
9393
'gherkin-32' => [
94-
'whitespace_in_tags.feature' => '/Whitespace in tags is deprecated/',
9594
],
9695
];
9796

0 commit comments

Comments
 (0)