Skip to content

fix(unpack): Не падать на записях с датой раньше 1601 года - #47

Merged
zeegin merged 1 commit into
mainfrom
fix/negative-filetime
Sep 17, 2026
Merged

zeegin merged 1 commit into
mainfrom
fix/negative-filetime

Conversation

@zeegin

@zeegin zeegin commented Sep 17, 2026

Copy link
Copy Markdown
Member

Наиболее вероятная причина #3 и #5. Найдено при разборе настоящих дистрибутивов с releases.1c.ru.

Что происходит

onec_dtools.read_included_file_info читает FILETIME как беззнаковый "Q". Дата раньше 1601 года хранится как отрицательное 64-битное число, и -17400000000 превращается в 18446744056309551616. Дальше datetime(1601,1,1) + timedelta(microseconds=...) бросает OverflowError.

Падение происходит при разборе оглавления, до записи первого файла — отсюда симптом «вообще не распаковывает», а не «распаковал половину».

Это не синтетика

Значение взято из реального 1cv8.efd. Прогон настоящих дистрибутивов, скачанных с releases.1c.ru:

StateAccounting_2_0_110_66_setup1c.zip   БГУ, ред. 2.0                 10 записей из 83
AccountingCorp_3_0_206_19_setupt1c.zip   Бухгалтерия КОРП, ред. 3.0    21 запись из 26
Trade_11_6_1_61_setup1c.zip              Управление торговлей, ред. 11  0 из 79

Распаковка настоящего 1cv8.efd из AccountingCorp — до и после правки:

до:     [ERROR] Unexpected error: date value out of range
        файлов на выходе: 0

после:  [OK] Unpacking completed successfully
        файлов: 26, объём: 946M, время: 2 с

БГУ, тот самый продукт из #3:

после:  [OK] Unpacking completed successfully
        файлов: 83, объём: 2.3G, время: 5 с

Целостность сверена с оглавлением: 26 из 26 записей совпали по размеру до байта, расхождений нет.

Почему это #3 и #5

Попутно опровергается гипотеза из #13: там основным подозреваемым был assert header == 1. В обоих файлах header == 1, дело не в нём.

Правка

Разбор описания записи больше не делегируется onec_dtools: FILETIME читается знаковым, непредставимая дата даёт None вместо исключения. Файл получает текущее время — ровно так же, как для всех прочих дат вне диапазона, что _apply_file_mtime уже делал.

Отдельно стоит отметить: в AccountingCorp есть и записи с положительными, но бессмысленными датами — 1602-10-14, 1604-07-27. Они не роняли разбор и попадали под существующее отсечение по MIN_REPRESENTABLE_MTIME. Трогать их не понадобилось.

Тесты

310 → 322. Три обратные мутации:

мутация результат
знаковое чтение обратно в "Q" 1 failed
вернуть делегирование в onec_dtools 2 failed
убрать отсечение неположительных значений 3 failed

Первый прогон мутаций дал ложно-зелёный результат, и это стоит зафиксировать: Apple-сборка Python 3.9 на macOS хранит байт-код не в __pycache__, а в централизованном кэше ~/Library/Caches/com.apple.python/. Подмена "q" на "Q" не меняет размер файла, восстановление прошло в ту же секунду — и кэш счёл запись актуальной. Ни чистка __pycache__, ни -B не помогают: -B запрещает запись, а не чтение. Мутационную проверку на этой машине нужно сопровождать удалением каталога в ~/Library/Caches/com.apple.python/.

Там же нашлась настоящая дыра в моём тесте: проверка с названием «читает знаковым» проходила и на "Q", потому что конвертер гасит и беззнакового гиганта через переполнение. Добавлен отдельный тест, который пиннит именно знаковость.

322 passed
покрытие 87.75%
ruff: All checks passed

onec_dtools читает FILETIME как беззнаковый "Q", поэтому -17400000000
превращается в 18446744056309551616, и datetime + timedelta бросает
OverflowError. Падение происходит при разборе оглавления, до записи
первого файла, — пользователь получает «Неожиданная ошибка: date value
out of range» и ноль файлов на выходе.

Такие записи есть в настоящих поставках с releases.1c.ru. Проверено на
двух скачанных дистрибутивах:

  Бухгалтерия государственного учреждения 2.0.110.66 — 10 записей из 83
  Бухгалтерия предприятия КОРП 3.0.206.19            — 21 запись из 26

До правки оба давали [ERROR] и пустой каталог. После — распаковываются
целиком: 83 файла (2.3 ГБ) и 26 файлов (946 МБ), размеры совпадают с
объявленными в оглавлении до байта.

Разбор описания записи больше не делегируется onec_dtools: FILETIME
читается знаковым, а непредставимая дата даёт None вместо исключения.
Файл получает текущее время — так же, как для всех прочих дат вне
диапазона, что уже делал _apply_file_mtime.

Это наиболее вероятная причина #3 и #5: продукты совпадают с
названными там, механизм отказа — тот же.

Тесты: 310 -> 322.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 17, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-17T14:25:32.882276Z 98bf0db PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@zeegin
zeegin merged commit 93af653 into main Sep 17, 2026
3 checks passed
@zeegin
zeegin deleted the fix/negative-filetime branch September 17, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant