From 5ca1fa783f34186be45db5f7fafc70134e1a9334 Mon Sep 17 00:00:00 2001 From: Kenneth Hough Date: Wed, 3 Jun 2026 00:26:47 -0500 Subject: [PATCH] Fix: MCP commit_draft shipped raw bzip2 bytes into published HTML (4.10.1) A page's header/footer are FKs to KyteSectionTemplate, which stores its content bzip2-compressed. getObject()'s FK expansion returns those fields raw, and the page-assembly path concatenates them straight into the output. The human publish path was saved only incidentally by hook_response_data() decompressing header/footer first; the MCP commit path (DraftService::commitDraft -> publishFromContent) never runs that hook, so it shipped the raw "BZh..." bytes into the published ' + . '

café — 日本語

'; + $this->assertFalse(KytePageController::hasBinaryContamination($html)); + } + + public function testDetectsEmbeddedBzip2Stream(): void + { + // The exact failure mode: a compressed stylesheet concatenated into a + // '; + $this->assertTrue(KytePageController::hasBinaryContamination($html)); + } + + public function testDetectsInvalidUtf8(): void + { + $html = '

' . chr(0xFF) . '

'; // 0xFF is never valid UTF-8 + $this->assertTrue(KytePageController::hasBinaryContamination($html)); + } + + public function testDoesNotFalsePositiveOnLiteralBZhText(): void + { + // Prose that merely contains "BZh" (no full bzip2 block magic) and is + // valid UTF-8 must publish normally. + $html = '

The BZh2 compression algorithm is great.

'; + $this->assertFalse(KytePageController::hasBinaryContamination($html)); + } + + public function testEmptyStringIsClean(): void + { + $this->assertFalse(KytePageController::hasBinaryContamination('')); + } +}