Skip to content

Commit

Permalink
Fix uncaught OverflowException: The buffer size is too big for the de…
Browse files Browse the repository at this point in the history
…fined file size limit
  • Loading branch information
mougrim authored Nov 1, 2023
1 parent a7ba091 commit cf51475
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 5 deletions.
21 changes: 16 additions & 5 deletions Sitemap.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ private function createNewFile()
* elements that did not fit into the previous file. (See self::flush)
*/
$this->writer->text("\n");
$this->flush(true);
$this->flush();
}

/**
Expand Down Expand Up @@ -209,17 +209,22 @@ private function finishFile()
*/
public function write()
{
$this->finishFile();
if ($this->writer !== null) {
$this->flush();
$this->finishFile();
}
}

/**
* Flushes buffer into file
*
* @param int $footSize Size of the remaining closing tags
* @return bool is new file created
* @throws \OverflowException
*/
private function flush($footSize = 10)
{
$isNewFileCreated = false;
$data = $this->writer->flush(true);
$dataSize = mb_strlen($data, '8bit');

Expand All @@ -235,10 +240,13 @@ private function flush($footSize = 10)
}
$this->finishFile();
$this->createNewFile();
$isNewFileCreated = true;
}

$this->writerBackend->append($data);
$this->byteCount += $dataSize;

return $isNewFileCreated;
}

/**
Expand Down Expand Up @@ -268,8 +276,11 @@ protected function validateLocation($location) {
*/
public function addItem($location, $lastModified = null, $changeFrequency = null, $priority = null)
{
if ($this->urlsCount >= $this->maxUrls) {
$this->finishFile();
if ($this->urlsCount >= $this->maxUrls && $this->writer !== null) {
$isNewFileCreated = $this->flush();
if (!$isNewFileCreated) {
$this->finishFile();
}
}

if ($this->writerBackend === null) {
Expand Down Expand Up @@ -517,4 +528,4 @@ public function setStylesheet($stylesheetUrl)
$this->stylesheet = $stylesheetUrl;
}
}
}
}
161 changes: 161 additions & 0 deletions tests/SitemapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

class SitemapTest extends \PHPUnit_Framework_TestCase
{
const HEADER_LENGTH = 100;
const FOOTER_LENGTH = 10;
const ELEMENT_LENGTH_WITHOUT_URL = 137;

/**
* Asserts validity of simtemap according to XSD schema
* @param string $fileName
Expand Down Expand Up @@ -365,4 +369,161 @@ public function testBufferSizeImpact()

$this->assertLessThan($times[0] * 1.2, $times[1]);
}

public function testBufferSizeIsNotTooBigOnFinishFileInWrite()
{
$time = 100;
$urlLength = 13;
$urlsQty = 4;

$sitemapPath = __DIR__ . '/sitemap.xml';
$sitemap = new Sitemap($sitemapPath);
$sitemap->setBufferSize(3);
$sitemap->setMaxUrls(4);
$sitemap->setMaxBytes(
self::HEADER_LENGTH + self::FOOTER_LENGTH + self::ELEMENT_LENGTH_WITHOUT_URL * $urlsQty
+ $urlLength * $urlsQty - 1
);

for ($i = 0; $i < $urlsQty; $i++) {
$sitemap->addItem(
// url 13 bytes
"https://a.b/{$i}",
$time,
Sitemap::WEEKLY,
1
);
}
$sitemap->write();

$expectedFiles = array(
__DIR__ . '/sitemap.xml',
__DIR__ . '/sitemap_2.xml',
);
$expected[] = <<<EOF
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://a.b/0</loc>
<lastmod>1970-01-01T00:01:40+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://a.b/1</loc>
<lastmod>1970-01-01T00:01:40+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://a.b/2</loc>
<lastmod>1970-01-01T00:01:40+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
</urlset>
EOF;
$expected[] = <<<EOF
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://a.b/3</loc>
<lastmod>1970-01-01T00:01:40+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
</urlset>
EOF;
foreach ($expectedFiles as $expectedFileNumber => $expectedFile) {
$this->assertTrue(file_exists($expectedFile), "$expectedFile does not exist!");
$this->assertIsValidSitemap($expectedFile);

$actual = trim(file_get_contents($expectedFile));
$this->assertEquals($expected[$expectedFileNumber], $actual);

unlink($expectedFile);
}
}

public function testBufferSizeIsNotTooBigOnFinishFileInAddItem()
{
$time = 100;
$urlLength = 13;
$urlsQty = 5;

$sitemapPath = __DIR__ . '/sitemap.xml';
$sitemap = new Sitemap($sitemapPath);
$sitemap->setBufferSize(3);
$sitemap->setMaxUrls(4);
$sitemap->setMaxBytes(
// 100 + 10 + 137 * 4
self::HEADER_LENGTH + self::FOOTER_LENGTH + self::ELEMENT_LENGTH_WITHOUT_URL * 4
+ $urlLength * 4 - 1
);

for ($i = 0; $i < $urlsQty; $i++) {
$sitemap->addItem(
// url 13 bytes
"https://a.b/{$i}",
$time,
Sitemap::WEEKLY,
1
);
}
$sitemap->write();

$expectedFiles = array(
__DIR__ . '/sitemap.xml',
__DIR__ . '/sitemap_2.xml',
);
$expected[] = <<<EOF
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://a.b/0</loc>
<lastmod>1970-01-01T00:01:40+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://a.b/1</loc>
<lastmod>1970-01-01T00:01:40+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://a.b/2</loc>
<lastmod>1970-01-01T00:01:40+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
</urlset>
EOF;
$expected[] = <<<EOF
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://a.b/3</loc>
<lastmod>1970-01-01T00:01:40+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://a.b/4</loc>
<lastmod>1970-01-01T00:01:40+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
</urlset>
EOF;
foreach ($expectedFiles as $expectedFileNumber => $expectedFile) {
$this->assertTrue(file_exists($expectedFile), "$expectedFile does not exist!");
$this->assertIsValidSitemap($expectedFile);

$actual = trim(file_get_contents($expectedFile));
$this->assertEquals($expected[$expectedFileNumber], $actual);

unlink($expectedFile);
}
}
}

0 comments on commit cf51475

Please sign in to comment.