From 644ee460afaebf1a075f7c3c11a52210e2610c34 Mon Sep 17 00:00:00 2001 From: infosave2007 Date: Sat, 24 Jan 2026 13:17:57 +0300 Subject: [PATCH] fix(qr): Use Qt qCompress format for QR code encoding Amnezia Android uses qUncompress which expects: - 4-byte big-endian uncompressed length prefix - zlib compressed data (gzcompress output) Previously we used a custom 12-byte header (version, compressedLen, uncompressedLen) which was incompatible with Qt's qUncompress. This fix ensures X-Ray QR codes can be properly decoded by Amnezia VPN app. --- inc/QrUtil.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/inc/QrUtil.php b/inc/QrUtil.php index e679531..8f77a29 100644 --- a/inc/QrUtil.php +++ b/inc/QrUtil.php @@ -63,15 +63,15 @@ class QrUtil public static function encodeOldPayloadFromJson(string $jsonText): string { $json = self::normalizeJson($jsonText); - // Old format uses zlib (gzcompress) with header [version, compressed_len, uncompressed_len] + // Qt qCompress format: 4-byte big-endian uncompressed length + zlib compressed data + // This is what Amnezia Android's qUncompress expects $compressed = gzcompress($json, 9); if ($compressed === false) { throw new RuntimeException('gzcompress failed'); } $uncompressedLen = strlen($json); - $compressedLen = strlen($compressed) + 4; - $version = 0x07C00100; // align with working payload header (big-endian) - $header = pack('N3', $version, $compressedLen, $uncompressedLen); + // Qt format: 4 bytes of uncompressed length (big-endian) + zlib data + $header = pack('N', $uncompressedLen); return self::urlsafe_b64_encode($header . $compressed); }