From 08dc6ab6a4716a5bc2f2d9baf8b6e55704ae179f Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 1 Sep 2026 16:34:52 +0300 Subject: [PATCH] Fix filename buffer overflow in create_filename FILE_NAME is a fixed 48-byte buffer, but the loop copying the filename parsed from the download URL had no length check, so a filename longer than 48 characters would overflow into adjacent variables (FILE_INI, DIR_zifi, DIR_download, DIR_date). Bound the copy loop to 48 bytes. Verified on hardware via a temporary diagnostic test (since removed): folder/file creation with long names and write+read-back through the FAT32 driver both work correctly, and downloads/ is confirmed write-only (playback/viewing always reads from memory, never disk). Documented the fix in README.md. --- README.md | 3 ++- _spg/ZIFI/zifi.spg | Bin 43520 -> 43520 bytes zifi.asm | 7 ++++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 05942f7..41fa7ed 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,8 @@ AT+CIPSNTPTIME? — получить текущее врем **Мелкие исправления:** - перевёл обращение к порту `#EFF7` (общий системный регистр — управляет не только доступом к часам, но и видеорежимом/turbo/кэшем) на read-modify-write вместо прямой перезаписи всего байта, чтобы не сбивать остальные настройки; - исправил баг в разборе двузначного GMT-смещения из `zifi.ini` (например `+10`) — были перепутаны местами разряды; -- теперь DMA-очистка под индикатор громкости дожидается завершения перед тем, как CPU начинает рисовать поверх той же области (была гонка записи). +- теперь DMA-очистка под индикатор громкости дожидается завершения перед тем, как CPU начинает рисовать поверх той же области (была гонка записи); +- исправил переполнение буфера имени файла (`create_filename`): при скачивании имя файла из ссылки копировалось в 48-байтный буфер без проверки длины, и если оно было длиннее — переполнение затирало соседние переменные (`zifi.ini`, имена служебных папок) прямо в памяти. Теперь копирование корректно обрезается на 48 символах. Проверено на железе: создание папки и файла с длинными именами (в т.ч. ровно 48 символов) и последующее чтение содержимого — всё работает штатно, никакой драйверной обрезки до 8 символов нет. **Известная нерешённая мелочь:** курсор мыши (аппаратный спрайт TSU) обрывается по фиксированной строке экрана прямо над нижней панелью управления — похоже на границу, завязанную на тайминг переключения видеорежима или на аппаратный бордюр, а не на что-то, что двигается вместе с содержимым панели. Я не нашёл способ поправить это без риска сломать что-то ещё, оставил как есть. diff --git a/_spg/ZIFI/zifi.spg b/_spg/ZIFI/zifi.spg index 013dfefde80feb2bc6e20d92dcea9e9f66b5a283..9828b9226b9b79e8e3cc22221a7900870f5f9cdc 100644 GIT binary patch delta 6357 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 OZZOMFKL3@%gZ}}uasRCV delta 6350 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