Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUGFIX] Allow line feeds within <html> tag #987

Merged
merged 1 commit into from
Apr 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Drop support for PHP 7.1 (#967)

### Fixed
- Allow line feeds within `<html>` tag (#987)

## 5.0.1

Expand Down
2 changes: 1 addition & 1 deletion src/HtmlProcessor/AbstractHtmlProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ private function addContentTypeMetaTag(string $html): string
);
} elseif ($hasHtmlTag) {
$reworkedHtml = \preg_replace(
'/<html(.*?)>/i',
'/<html(.*?)>/is',
'<html$1><head>' . self::CONTENT_TYPE_META_TAG . '</head>',
$html
);
Expand Down
72 changes: 71 additions & 1 deletion tests/Unit/HtmlProcessor/AbstractHtmlProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,75 @@ public function addsMissingHtmlTag(string $html): void
self::assertStringContainsString('<html>', $result);
}

/**
* @return array<string, array<int, string>>
*/
public function provideContentWithHtmlTag(): array
{
return [
'HTML only' => ['<html></html>'],
'HTML start tag only' => ['<html>'],
'doctype and HTML only' => ['<!DOCTYPE html><html></html>'],
'HTML and body content only' => ['<html><p>Hello</p></html>'],
'HTML and HEAD element' => ['<html><head></head></html>'],
'HTML and BODY element' => ['<html><body></body></html>'],
'HTML, HEAD AND BODY element' => ['<html><head></head><body></body></html>'],
];
}

/**
* @return array<string, array<int, string>> The second element of each dataset is optional, and is the expected
* normalization of the `<html>` tag, if different.
*/
public function provideHtmlTagWithAttributes(): array
{
return [
'with one attribute' => ['<html lang="de">'],
'with two attributes' => ['<html lang="de" dir="ltr">'],
'with line feeds within tag' => ["<html\nlang='de'\n>", '<html lang="de">'],
'with Windows line endings within tag' => ["<html\r\nlang='de'\r\n>", '<html lang="de">'],
'with TABs within tag' => ["<html\tlang='de'\t>", '<html lang="de">'],
];
}

/**
* @test
*
* @param string $html
*
* @dataProvider provideContentWithHtmlTag
* @dataProvider provideHtmlTagWithAttributes
*/
public function notAddsSecondHtmlTag(string $html): void
{
$subject = TestingHtmlProcessor::fromHtml($html);

$result = $subject->render();

$htmlTagCount = \preg_match_all('%<html[\\s/>]%', $result);
self::assertSame(1, $htmlTagCount);
}

/**
* @test
*
* @param string $html
* @param ?string $normalizedHtmlTag
*
* @dataProvider provideHtmlTagWithAttributes
*/
public function preservesHtmlTagAttributes(string $html, ?string $normalizedHtmlTag = null): void
{
if ($normalizedHtmlTag === null) {
$normalizedHtmlTag = $html;
}
$subject = TestingHtmlProcessor::fromHtml($html);

$result = $subject->render();

self::assertStringContainsString($normalizedHtmlTag, $result);
}

/**
* @return string[][]
*/
Expand Down Expand Up @@ -457,14 +526,15 @@ public function provideContentWithoutHeadTag(): array
* @param string $html
*
* @dataProvider provideContentWithoutHeadTag
* @dataProvider provideHtmlTagWithAttributes
*/
public function addsMissingHeadTagExactlyOnce(string $html): void
{
$subject = TestingHtmlProcessor::fromHtml($html);

$result = $subject->render();

$headTagCount = \substr_count($result, '<head>');
$headTagCount = \preg_match_all('%<head[\\s/>]%', $result);
self::assertSame(1, $headTagCount);
}

Expand Down