From 6d3cf2b25ec1d758e37a12213dbaf97e62d205f9 Mon Sep 17 00:00:00 2001 From: Divarion_D Date: Sun, 13 Sep 2026 14:29:54 +0300 Subject: [PATCH] test(core): cover the Http\Request input abstraction and sanitizers Request had no tests despite being the front door for all HTTP input. Built from injected arrays (no superglobals), the new suite locks: - GET/POST merge precedence (POST wins), input/get/post/has/all accessors and their defaults. - Typed accessors: getInt() coercion, getBool() via FILTER_VALIDATE_BOOLEAN. - Server-derived helpers: method/isPost/isAjax/uri/userAgent/host (with the HTTP_HOST -> SERVER_NAME fallback) and their empty-server defaults. - Client IP resolution: first valid X-Forwarded-For entry, skipping invalid headers to X-Real-IP, and the 0.0.0.0 sentinel when nothing is usable. - Security sanitizers (the important part): NUL-byte stripping, ../ traversal neutralisation, ')); + $this->assertStringContainsString('<script', Request::parseCleanValue(''), 'case-insensitive'); + + $comment = Request::parseCleanValue('ab'); + $this->assertStringNotContainsString('', $comment); + + $this->assertSame("O'Brien", Request::parseCleanValue("O\\'Brien"), 'stripslashes'); + $this->assertSame("a\nb", Request::parseCleanValue("a\r\nb"), 'CRLF normalised to LF'); + $this->assertSame('trimmed', Request::parseCleanValue(' trimmed ')); + $this->assertSame('', Request::parseCleanValue('')); + } + + public function testParseCleanKeySanitises(): void { + $this->assertSame('page_id', Request::parseCleanKey('page_id'), 'valid key preserved'); + $this->assertSame('username', Request::parseCleanKey('user..name'), 'double-dot stripped'); + $this->assertSame('', Request::parseCleanKey('__proto__'), '__x__ pattern removed'); + $this->assertStringStartsWith('a<b', Request::parseCleanKey('aassertSame('', Request::parseCleanKey('')); + } + + public function testCleanGlobalsScrubsRecursivelyInPlace(): void { + $data = [ + 'nul' => "a\0b", + 'rtl' => 'x‮y', + 'deep' => ['trav' => '../etc/passwd'], + ]; + Request::cleanGlobals($data); + + $this->assertSame('ab', $data['nul']); + $this->assertSame('xy', $data['rtl'], 'RTL override removed'); + $this->assertSame('../etc/passwd', $data['deep']['trav']); + } +}