diff --git a/gen/apc_parsers.py b/gen/apc_parsers.py index 8c38e3f5f..3d0632b9f 100755 --- a/gen/apc_parsers.py +++ b/gen/apc_parsers.py @@ -113,11 +113,11 @@ def generate( if payload_allowed: payload_after_value = "case ';': state = PAYLOAD; break;" payload = ', PAYLOAD' - parr = 'static uint8_t payload[4096];' + parr = 'uint8_t *payload = parser_buf;' payload_case = f''' case PAYLOAD: {{ sz = parser_buf_pos - pos; - g.payload_sz = sizeof(payload); + g.payload_sz = MAX(BUF_EXTRA, sz); if (!base64_decode8(parser_buf + pos, sz, payload, &g.payload_sz)) {{ REPORT_ERROR("Failed to parse {command_class} command payload with error: payload size (%zu) too large", sz); return; }} pos = parser_buf_pos; @@ -132,7 +132,7 @@ def generate( return f''' #include "base64.h" static inline void -{function_name}(PS *self, const uint8_t *parser_buf, const size_t parser_buf_pos) {{ +{function_name}(PS *self, uint8_t *parser_buf, const size_t parser_buf_pos) {{ unsigned int pos = 1; enum PARSER_STATES {{ KEY, EQUAL, UINT, INT, FLAG, AFTER_VALUE {payload} }}; enum PARSER_STATES state = KEY, value_state = FLAG; diff --git a/kitty/parse-graphics-command.h b/kitty/parse-graphics-command.h index 58119ee86..369f676cc 100644 --- a/kitty/parse-graphics-command.h +++ b/kitty/parse-graphics-command.h @@ -3,7 +3,7 @@ #pragma once #include "base64.h" -static inline void parse_graphics_code(PS *self, const uint8_t *parser_buf, +static inline void parse_graphics_code(PS *self, uint8_t *parser_buf, const size_t parser_buf_pos) { unsigned int pos = 1; enum PARSER_STATES { KEY, EQUAL, UINT, INT, FLAG, AFTER_VALUE, PAYLOAD }; @@ -14,7 +14,7 @@ static inline void parse_graphics_code(PS *self, const uint8_t *parser_buf, bool is_negative; memset(&g, 0, sizeof(g)); size_t sz; - static uint8_t payload[4096]; + uint8_t *payload = parser_buf; enum KEYS { action = 'a', @@ -320,7 +320,7 @@ static inline void parse_graphics_code(PS *self, const uint8_t *parser_buf, case PAYLOAD: { sz = parser_buf_pos - pos; - g.payload_sz = sizeof(payload); + g.payload_sz = MAX(BUF_EXTRA, sz); if (!base64_decode8(parser_buf + pos, sz, payload, &g.payload_sz)) { REPORT_ERROR("Failed to parse GraphicsCommand command payload with " "error: payload size (%zu) too large", diff --git a/kitty_tests/graphics.py b/kitty_tests/graphics.py index 8e364f8c4..d6ab2026e 100644 --- a/kitty_tests/graphics.py +++ b/kitty_tests/graphics.py @@ -7,13 +7,12 @@ import time import unittest import zlib -from base64 import standard_b64decode, standard_b64encode from contextlib import suppress from dataclasses import dataclass from io import BytesIO from itertools import cycle -from kitty.fast_data_types import load_png_data, shm_unlink, shm_write, xor_data +from kitty.fast_data_types import base64_decode, base64_encode, load_png_data, shm_unlink, shm_write, xor_data from . import BaseTest, parse_bytes @@ -28,7 +27,7 @@ def send_command(screen, cmd, payload=b''): if payload: if isinstance(payload, str): payload = payload.encode('utf-8') - payload = standard_b64encode(payload).decode('ascii') + payload = base64_encode(payload).decode('ascii') cmd += ';' + payload cmd += '\033\\' c = screen.callbacks @@ -342,20 +341,27 @@ def test_load_images(self): img = g.image_for_client_id(1) self.ae(img['data'], b'abcdefghijklmnop') + random_data = byte_block(32 * 1024) + sl( + random_data, + s=1024, + v=8, + expecting_data=random_data + ) + # Test compression - random_data = byte_block(3 * 1024) compressed_random_data = zlib.compress(random_data) sl( compressed_random_data, - s=24, - v=32, + s=1024, + v=8, o='z', expecting_data=random_data ) # Test chunked + compressed b = len(compressed_random_data) // 2 - self.assertIsNone(pl(compressed_random_data[:b], s=24, v=32, o='z', m=1)) + self.assertIsNone(pl(compressed_random_data[:b], s=1024, v=8, o='z', m=1)) self.ae(pl(compressed_random_data[b:], m=0), 'OK') img = g.image_for_client_id(1) self.ae(img['data'], random_data) @@ -364,10 +370,10 @@ def test_load_images(self): def load_temp(prefix='tty-graphics-protocol-'): f = tempfile.NamedTemporaryFile(prefix=prefix) f.write(random_data), f.flush() - sl(f.name, s=24, v=32, t='f', expecting_data=random_data) + sl(f.name, s=1024, v=8, t='f', expecting_data=random_data) self.assertTrue(os.path.exists(f.name)) f.seek(0), f.truncate(), f.write(compressed_random_data), f.flush() - sl(f.name, s=24, v=32, t='t', o='z', expecting_data=random_data) + sl(f.name, s=1024, v=8, t='t', o='z', expecting_data=random_data) return f f = load_temp() @@ -381,7 +387,7 @@ def load_temp(prefix='tty-graphics-protocol-'): # Test loading from POSIX SHM name = '/kitty-test-shm' shm_write(name, random_data) - sl(name, s=24, v=32, t='s', expecting_data=random_data) + sl(name, s=1024, v=8, t='s', expecting_data=random_data) self.assertRaises( FileNotFoundError, shm_unlink, name ) # check that file was deleted @@ -421,7 +427,7 @@ def png(mode='RGBA'): def test_load_png_simple(self): # 1x1 transparent PNG - png_data = standard_b64decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==') + png_data = base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==') expected = b'\x00\xff\xff\x7f' self.ae(load_png_data(png_data), (expected, 1, 1)) s, g, pl, sl = load_helpers(self)