ELF — это база данных, которая отказывается в этом признаться:
Фарид Закария довёл мысль до конца. Его прототип SELF — исполняемый файл, который целиком является базой SQLite:
Отсюда
Цена: около 5 миллисекунд на старте и страницы, которые копируются из b-дерева вместо отображения в память.
@prog_stuff
.strtab делает интернирование строк, .gnu.hash работает индексом, таблица заголовков секций — это таблица таблиц, а st_name — внешний ключ, разложенный руками.Фарид Закария довёл мысль до конца. Его прототип SELF — исполняемый файл, который целиком является базой SQLite:
file hello показывает «SQLite 3.x database», ./hello печатает Hello, world!, а sqlite3 hello 'SELECT soname FROM ldd' отвечает libc.so.6. Запуск идёт через binfmt_misc и отдельный интерпретатор.Отсюда
strip — это DELETE и VACUUM, patchelf — UPDATE, а LD_PRELOAD — строка в таблице, которую можно включить и откатить транзакцией.Цена: около 5 миллисекунд на старте и страницы, которые копируются из b-дерева вместо отображения в память.
@prog_stuff
На скриншоте ролик, к которому YouTube показывает пометку «снято камерой». Внутри — рендер из Big Buck Bunny.
Дэвид Бьюкенен разобрал, почему C2PA на Android так подделывается. Приложения-камеры опираются на Key Attestation и Play Integrity, а рут, полученный через эксплойт, обе проверки не тревожит: загрузчик остаётся заблокированным, ключи AVB — вендорскими, и серверы Google спокойно выдают устройству ключи подписи. Сам ключ из StrongBox не вытащить, но попросить Titan M2 подписать произвольные данные рут может.
Проверял автор на Pixel 8a и 9a, рут брал одноклик-эксплойтом CVE-2026-43499, который на полностью обновлённых Pixel всё ещё работает. Приложение Pixel Camera при этом имеет Assurance Level 2 — высший из определённых сейчас уровней программы соответствия C2PA.
Google закрыла отчёт как «Won't fix (infeasible)», выплатила 7500 долларов, а плашка у ролика после публикации исчезла — автор считает, что её сняли руками.
@prog_stuff
Дэвид Бьюкенен разобрал, почему C2PA на Android так подделывается. Приложения-камеры опираются на Key Attestation и Play Integrity, а рут, полученный через эксплойт, обе проверки не тревожит: загрузчик остаётся заблокированным, ключи AVB — вендорскими, и серверы Google спокойно выдают устройству ключи подписи. Сам ключ из StrongBox не вытащить, но попросить Titan M2 подписать произвольные данные рут может.
Проверял автор на Pixel 8a и 9a, рут брал одноклик-эксплойтом CVE-2026-43499, который на полностью обновлённых Pixel всё ещё работает. Приложение Pixel Camera при этом имеет Assurance Level 2 — высший из определённых сейчас уровней программы соответствия C2PA.
Google закрыла отчёт как «Won't fix (infeasible)», выплатила 7500 долларов, а плашка у ролика после публикации исчезла — автор считает, что её сняли руками.
@prog_stuff
Тип
24 августа PR из восемнадцати коммитов влили в
Помимо самой стабилизации в патче ещё три вещи. Fallback никогда-типа теперь
Речь про nightly; в стабильную ветку изменение приедет обычным циклом релизов.
Сам автор описал ощущение от финала так: «Чувствую себя… пустым. Прямо как never type».
@prog_stuff
! в Rust обозначает значение, которого не бывает: его «возвращает» функция, которая не возвращается никогда. Нестабильным он пробыл десять лет.24 августа PR из восемнадцати коммитов влили в
rust-lang/rust:main. Автор под ником WaffleLapkin пишет, что занимался стабилизацией больше двух лет, а до него было пять неудавшихся попыток.Помимо самой стабилизации в патче ещё три вещи. Fallback никогда-типа теперь
! во всех редакциях, и это ломающее изменение — под него гоняли Crater по экосистеме. std․convert․Infallible стал псевдонимом !, то есть из pub enum превратился в pub type. Линт dependency_on_unit_never_type_fallback удалён: подсказывать больше не о чем.Речь про nightly; в стабильную ветку изменение приедет обычным циклом релизов.
Сам автор описал ощущение от финала так: «Чувствую себя… пустым. Прямо как never type».
@prog_stuff
Отладочная сборка Firefox линкуется у lld за 4,44 секунды, у mold — за 0,89. Разница видна на графике: mold почти всю линковку держит занятыми 32 ядра, а lld преимущественно работает на одном ядре, изредка выходя в многоядерные всплески.
Руи Уэяма, автор mold, разобрал устройство своего линкера в статье от 24 августа. Ускоряли не отдельные проходы, а весь конвейер: разбор всех входных файлов, включая каждый элемент архивов, разрешение символов отдельным проходом через атомарный compare-and-swap, сборка мусора по секциям, слияние строк и запись результата. На девяти больших проектах mold быстрее lld в 2,4–16,1 раза и до 112 раз — GNU ld.
Одним проходом ускорение не объясняется: оставить последовательными копирование вывода и применение релокаций — и время линковки растёт на 542 процента.
Цена — эвристика: порядок разрешения конфликтов символов между общими библиотеками стандарт не описывает, mold выбирает его сам. Проверяли сборкой всего Gentoo: из 19 000 с лишним пакетов не собрались два.
@prog_stuff
Руи Уэяма, автор mold, разобрал устройство своего линкера в статье от 24 августа. Ускоряли не отдельные проходы, а весь конвейер: разбор всех входных файлов, включая каждый элемент архивов, разрешение символов отдельным проходом через атомарный compare-and-swap, сборка мусора по секциям, слияние строк и запись результата. На девяти больших проектах mold быстрее lld в 2,4–16,1 раза и до 112 раз — GNU ld.
Одним проходом ускорение не объясняется: оставить последовательными копирование вывода и применение релокаций — и время линковки растёт на 542 процента.
Цена — эвристика: порядок разрешения конфликтов символов между общими библиотеками стандарт не описывает, mold выбирает его сам. Проверяли сборкой всего Gentoo: из 19 000 с лишним пакетов не собрались два.
@prog_stuff
Венсан Берна собрал введение в spanning tree, где схемы не нарисованы, а работают. В браузере крутится настоящий демон MSTPD, скомпилированный в WebAssembly через emscripten: код, который обычно говорит с ядром Linux, заменён на C API — он заводит мосты и порты, отдаёт состояние в JSON и двигает время детерминированно.
Дальше можно ронять кабели и смотреть по шагам, вперёд и назад, как дерево пересобирается и какой порт уходит в блокировку. Чтобы понять, сошлась ли топология, автор после каждого шага сохраняет снимок памяти симуляции, проигрывает пятьдесят секунд модельного времени и откатывается к снимку.
Сорок юнит-тестов на эту обвязку проходят за 396 миллисекунд.
Чтения на тридцать шесть минут, и RSS-читалка не подойдёт: примеры живут только на странице.
@prog_stuff
Дальше можно ронять кабели и смотреть по шагам, вперёд и назад, как дерево пересобирается и какой порт уходит в блокировку. Чтобы понять, сошлась ли топология, автор после каждого шага сохраняет снимок памяти симуляции, проигрывает пятьдесят секунд модельного времени и откатывается к снимку.
Сорок юнит-тестов на эту обвязку проходят за 396 миллисекунд.
Чтения на тридцать шесть минут, и RSS-читалка не подойдёт: примеры живут только на странице.
@prog_stuff
❤1👍1
«x86 выполняет обращения к памяти строго по порядку, а ARM и RISC-V переставляют их как хотят, поэтому слабая модель памяти масштабируется лучше». Фабиан Гизен объясняет, почему эта формула ошибочна с обеих сторон.
За исключением совсем маленьких ядер и микроконтроллеров без кэша, процессоры вообще не соблюдают собственную модель памяти на каждом обращении. Они обещают вести себя так, как если бы соблюдали, и разница здесь принципиальная. Реализуют это оптимистично: считают, что данные никто параллельно не менял и что запись никем не оспаривается, выполняют обращения в удобном порядке, а рядом держат ровно столько метаданных, чтобы задним числом заметить нарушение порядка. Заметили — инструкция не фиксируется, состояние откатывается на момент до её выполнения, дальше повтор.
Так устроены все, независимо от модели памяти. Разница в другом: сколько метаданных нужно хранить для каждой обращающейся к памяти инструкции в полёте и какие порядки разрешено фиксировать при конфликте. Сильная модель чаще признаёт конфликт и уходит на повтор, слабая допускает больше законных порядков для расслабленных чтений и записей. При этом конфликт — медленный случай на любой архитектуре.
Часто цитируемые 7 процентов на аппаратный TSO у Apple Silicon Гизен отдельно снабжает оговоркой: это цена конкретной реализации, где TSO включается ради Rosetta и не является основным режимом ядра, спроектированного под AArch64.
Личное правило автора для многопоточного кода: конкурировать за общие данные реже, а не быстрее.
@prog_stuff
За исключением совсем маленьких ядер и микроконтроллеров без кэша, процессоры вообще не соблюдают собственную модель памяти на каждом обращении. Они обещают вести себя так, как если бы соблюдали, и разница здесь принципиальная. Реализуют это оптимистично: считают, что данные никто параллельно не менял и что запись никем не оспаривается, выполняют обращения в удобном порядке, а рядом держат ровно столько метаданных, чтобы задним числом заметить нарушение порядка. Заметили — инструкция не фиксируется, состояние откатывается на момент до её выполнения, дальше повтор.
Так устроены все, независимо от модели памяти. Разница в другом: сколько метаданных нужно хранить для каждой обращающейся к памяти инструкции в полёте и какие порядки разрешено фиксировать при конфликте. Сильная модель чаще признаёт конфликт и уходит на повтор, слабая допускает больше законных порядков для расслабленных чтений и записей. При этом конфликт — медленный случай на любой архитектуре.
Часто цитируемые 7 процентов на аппаратный TSO у Apple Silicon Гизен отдельно снабжает оговоркой: это цена конкретной реализации, где TSO включается ради Rosetta и не является основным режимом ядра, спроектированного под AArch64.
Личное правило автора для многопоточного кода: конкурировать за общие данные реже, а не быстрее.
@prog_stuff
Big Pineapple — платформа, на которой у Cloudflare работают 1.1.1.1, Gateway DNS, DNS Firewall и AS112, — держит в памяти больше 250 миллиардов записей кэша. Пять правок в том, как одна запись там лежит, вернули компании около 100 терабайт: столько оперативной памяти стоит примерно в 130 серверах их тринадцатого поколения.
Компания разобрала все пять по порядку.
@prog_stuff
Компания разобрала все пять по порядку.
Vec и String заменили на Box<[T]> и Box<str>: поле capacity бесполезно там, где запись после создания уже не меняется, а это 8 байт на поле и 64 байта на запись. Три списка DNS-секций свернули в один список с двумя смещениями по u16 — минус ещё 28 байт. Крупные варианты enum убрали в кучу, чтобы размер записи не диктовал самый жирный из них.@prog_stuff
Крейт из одной строчки показал, что Rustdoc делает лишнюю работу на каждой сборке
Перед каждым стабильным релизом Rust команда прогоняет Crater — инструмент, который собирает новой версией компилятора всю публичную экосистему. В прошлом месяце Crater нашёл, что бета-Rustdoc падает на крейте
Rustc такой код компилирует спокойно. Rustdoc падает с «reached the configured maximum number of stack frames», разбирая внутренний трейт
Формально это не регресс: число кадров стека не входит в гарантии стабильности. Но Ноа Лев из команды Rustdoc зацепился за другое — с какой стати почти пустому крейту вообще инлайнить документацию трейта из
За неделю разбора и серии PR среднее время работы упало на 25%, то есть Rustdoc стал быстрее на 33%. На реальных крейтах вроде
Автор прошёл весь путь по шагам: от странного сообщения на Zulip до профилирования и правок, попутно объясняя, как Rustdoc устроен изнутри и почему он так тесно завязан на внутренние API компилятора.
@prog_stuff
Перед каждым стабильным релизом Rust команда прогоняет Crater — инструмент, который собирает новой версией компилятора всю публичную экосистему. В прошлом месяце Crater нашёл, что бета-Rustdoc падает на крейте
indented-blocks. Весь крейт — одна строчка #![recursion_limit = "8"], ничего больше.Rustc такой код компилирует спокойно. Rustdoc падает с «reached the configured maximum number of stack frames», разбирая внутренний трейт
NumBufferTrait из core::fmt.Формально это не регресс: число кадров стека не входит в гарантии стабильности. Но Ноа Лев из команды Rustdoc зацепился за другое — с какой стати почти пустому крейту вообще инлайнить документацию трейта из
core::fmt, который никто не переэкспортирует. Логи подтвердили, что Rustdoc действительно лезет за ним.За неделю разбора и серии PR среднее время работы упало на 25%, то есть Rustdoc стал быстрее на 33%. На реальных крейтах вроде
hyper и bitmaps выигрыш доходит до 40%, на микробенчмарках вроде helloworld — до 60%.Автор прошёл весь путь по шагам: от странного сообщения на Zulip до профилирования и правок, попутно объясняя, как Rustdoc устроен изнутри и почему он так тесно завязан на внутренние API компилятора.
@prog_stuff
❤🔥2
«TUI лучше, потому что с клавиатуры» — аргумент, который держится на плохих GUI
На Hacker News неделю назад обсуждали призыв перестать делать текстовые интерфейсы в терминале и делать графические. Спор вышел живой, и в защиту TUI регулярно звучало одно и то же: их предпочитают, потому что они управляются с клавиатуры.
Хараламбос Кардарис разбирает именно этот довод. Наблюдение он не оспаривает: возьмите наугад графическое приложение и терминальное, второе с большей вероятностью окажется полностью клавиатурным. Но отсюда не следует, что делать надо TUI. Следует, что клавиатурная навигация во многих GUI сделана плохо.
Ничто не мешает графическому приложению управляться с клавиатуры так же полно, как терминальному, и лучше. Руководства по интерфейсам это прямо требуют: в GNOME Human Interface Guidelines написано, что всякое действие, выполнимое указателем, должно быть выполнимо и с клавиатуры, и что по любой части интерфейса нужно уметь пройти без мыши. Рекомендация есть, соблюдают её выборочно.
Сам автор — тяжёлый пользователь терминала и от TUI не отговаривает. Его претензия к рассуждению: клавиатурность зависит от того, как написана программа, и средой не задаётся.
@prog_stuff
На Hacker News неделю назад обсуждали призыв перестать делать текстовые интерфейсы в терминале и делать графические. Спор вышел живой, и в защиту TUI регулярно звучало одно и то же: их предпочитают, потому что они управляются с клавиатуры.
Хараламбос Кардарис разбирает именно этот довод. Наблюдение он не оспаривает: возьмите наугад графическое приложение и терминальное, второе с большей вероятностью окажется полностью клавиатурным. Но отсюда не следует, что делать надо TUI. Следует, что клавиатурная навигация во многих GUI сделана плохо.
Ничто не мешает графическому приложению управляться с клавиатуры так же полно, как терминальному, и лучше. Руководства по интерфейсам это прямо требуют: в GNOME Human Interface Guidelines написано, что всякое действие, выполнимое указателем, должно быть выполнимо и с клавиатуры, и что по любой части интерфейса нужно уметь пройти без мыши. Рекомендация есть, соблюдают её выборочно.
Сам автор — тяжёлый пользователь терминала и от TUI не отговаривает. Его претензия к рассуждению: клавиатурность зависит от того, как написана программа, и средой не задаётся.
@prog_stuff
Переписать с нуля — один из семи вариантов, и обычно худший
Легаси-сервис годами просто работает, потом одна старая зависимость тянет за собой другую, тесты начинают падать, и мелкий баг кладёт всё приложение. Первый порыв всегда один: переписать. Итог порыва тоже известен — месяцы без новых функций и никакой гарантии, что новая версия окажется лучше старой.
В разборе семь стратегий модернизации и ситуации под каждую: оставить как есть, заранее договорившись, какое событие станет сигналом к переделке; вывести ненужный модуль из эксплуатации; обновить стек без смены архитектуры; перенести на другую платформу; заменить готовым продуктом; рефакторить по частям; переписывать постепенно по схеме Strangler Fig, когда новая система оплетает монолит и забирает его задачи модуль за модулем.
Главная мысль: одной системе не обязан подходить один подход. Стабильный модуль не трогают, забытую интеграцию удаляют, авторизацию выносят постепенно. Перед тем как предлагать переписывание, каждый кусок сверяют по шести критериям: как часто меняется, сколько ест поддержки, от чего зависит, есть ли тесты, сколько может лежать и остались ли люди, которые его понимают.
В нашем канале Tproger разобрали подробнее.
@prog_stuff
Легаси-сервис годами просто работает, потом одна старая зависимость тянет за собой другую, тесты начинают падать, и мелкий баг кладёт всё приложение. Первый порыв всегда один: переписать. Итог порыва тоже известен — месяцы без новых функций и никакой гарантии, что новая версия окажется лучше старой.
В разборе семь стратегий модернизации и ситуации под каждую: оставить как есть, заранее договорившись, какое событие станет сигналом к переделке; вывести ненужный модуль из эксплуатации; обновить стек без смены архитектуры; перенести на другую платформу; заменить готовым продуктом; рефакторить по частям; переписывать постепенно по схеме Strangler Fig, когда новая система оплетает монолит и забирает его задачи модуль за модулем.
Главная мысль: одной системе не обязан подходить один подход. Стабильный модуль не трогают, забытую интеграцию удаляют, авторизацию выносят постепенно. Перед тем как предлагать переписывание, каждый кусок сверяют по шести критериям: как часто меняется, сколько ест поддержки, от чего зависит, есть ли тесты, сколько может лежать и остались ли люди, которые его понимают.
В нашем канале Tproger разобрали подробнее.
@prog_stuff
Samsung встроила вычислительные блоки прямо в LPDDR5X
Samsung продолжила линию Processing-in-Memory: в
Устройство напоминает жёстко ограниченный SIMD: одна операция и один операнд распространяются на все 16 банков. Их суммарная внутренняя пропускная способность достигает 614 ГБ/с, тогда как обычное обращение к памяти через внешнюю шину упирается в 76,8 ГБ/с.
Каждый PIM-блок держит четыре операции MAC в INT8 или FP8 за такт данных, то есть восемь за такт без учёта удвоенной передачи. На четырёхбитных весах пропускная способность удваивается, и пакет выдаёт 2,4 TOPS. Восемь чипов дают 9,6 INT8 TOPS, как NPU Intel Meteor Lake, и требуют 128 ГБ системной памяти. Архитектуру разобрали по материалам Hot Chips 2026.
@prog_stuff
Samsung продолжила линию Processing-in-Memory: в
LPDDR5X-9600 у каждого из 16 банков появился PIM-блок с MAC-деревом, регистрами инструкций и векторов активаций. Память выполняет часть вычислений там, где лежат данные, и работает через стандартный протокол LPDDR5X. Особые адреса строк включают режимы по принципу MMIO-регистров.Устройство напоминает жёстко ограниченный SIMD: одна операция и один операнд распространяются на все 16 банков. Их суммарная внутренняя пропускная способность достигает 614 ГБ/с, тогда как обычное обращение к памяти через внешнюю шину упирается в 76,8 ГБ/с.
Каждый PIM-блок держит четыре операции MAC в INT8 или FP8 за такт данных, то есть восемь за такт без учёта удвоенной передачи. На четырёхбитных весах пропускная способность удваивается, и пакет выдаёт 2,4 TOPS. Восемь чипов дают 9,6 INT8 TOPS, как NPU Intel Meteor Lake, и требуют 128 ГБ системной памяти. Архитектуру разобрали по материалам Hot Chips 2026.
@prog_stuff
🤯1
OpenOffice не печатал по вторникам, и виноват был Erlang
В багтрекере Ubuntu годами висела жалоба: печать из OpenOffice иногда не работает. Пользователи спорили, чей это баг, потому что из других программ печаталось нормально. Один снёс и переставил пакет, отчитался в четверг, что помогло — и через две недели, во вторник, написал, что не помогло.
Через четыре месяца жена одного из разработчиков Ubuntu сформулировала точно: OpenOffice не печатает по вторникам. Показать мужу она этого не могла, потому что была среда.
Разгадка оказалась в утилите
В базе сигнатур лежало правило для Erlang JAM-файла:
Пробелы в образце не экранированы, поэтому сравнивались только первые три символа. Правильная запись —
Правил в
@prog_stuff
В багтрекере Ubuntu годами висела жалоба: печать из OpenOffice иногда не работает. Пользователи спорили, чей это баг, потому что из других программ печаталось нормально. Один снёс и переставил пакет, отчитался в четверг, что помогло — и через две недели, во вторник, написал, что не помогло.
Через четыре месяца жена одного из разработчиков Ubuntu сформулировала точно: OpenOffice не печатает по вторникам. Показать мужу она этого не могла, потому что была среда.
Разгадка оказалась в утилите
file, которая определяет тип файла по сигнатурам в начале. OpenOffice записывает в PostScript дату создания, и по вторникам она принимает вид %%CreationDate: (Tue MMM D hh:mm:...).В базе сигнатур лежало правило для Erlang JAM-файла:
4 string Tue Jan 22 14:32:44 MET 1991 Erlang JAM file - version 4.2Пробелы в образце не экранированы, поэтому сравнивались только первые три символа. Правильная запись —
4 string Tue\ Jan\ 22\ 14:32:44\ MET\ 1991. По вторникам PostScript опознавался как Erlang JAM и до принтера не доезжал.Правил в
file больше 1600, и порядок проверки решает: ложное совпадение с Erlang случалось раньше, чем проверка на PostScript. История целиком — в собрании курьёзных багов.@prog_stuff
😁1
Одна JSON-колонка в SQLite вместо спроектированной заранее схемы
David Leadbeater показал приём, который сохраняет смысл спустя годы: документ целиком лежит в одной колонке SQLite, а востребованные поля постепенно становятся частью схемы. Заранее перечислять всю структуру JSON не требуется.
Поле извлекается через
Generated columns есть в SQLite начиная с версии 3.31. Leadbeater разбирает варианты
Границы у приёма явные. Колонку
@prog_stuff
David Leadbeater показал приём, который сохраняет смысл спустя годы: документ целиком лежит в одной колонке SQLite, а востребованные поля постепенно становятся частью схемы. Заранее перечислять всю структуру JSON не требуется.
Поле извлекается через
json_extract внутри generated column. Виртуальную колонку можно индексировать обычным CREATE INDEX, после чего запрос использует индекс как для привычного столбца. Когда появляется новый способ поиска, схема расширяется через ALTER TABLE; в статье план запроса проверяется командой EXPLAIN QUERY PLAN.Generated columns есть в SQLite начиная с версии 3.31. Leadbeater разбирает варианты
VIRTUAL и STORED, ограничение NOT NULL и индексы.Границы у приёма явные. Колонку
STORED таким способом через ALTER TABLE добавить нельзя, а некорректный JSON ломает вставку. Получается постепенная схема: исходный документ остаётся целым, а наружу выходят только поля, которым действительно понадобились ограничения или быстрый поиск.@prog_stuff
Писать код и строить систему — разные работы
Эссе, которое разбирают на Hacker News, начинается с наблюдения: перевести идею в инструкции для машины и решить, какие инструкции вообще должны существовать, — два разных занятия. Пример автора: «обрабатывать входящие события и обновлять данные». Синхронно или через очередь? Ровно один раз или хотя бы один? Что делать, если потребитель лежал три часа? Ни один из вопросов не про синтаксис.
Главный тезис: каждая оптимизация тратит сложность где-то ещё. Кеш даёт задержку и забирает инвалидацией, микросервисы дают независимые деплои и приносят распределённые отказы. Работа инженера — решать, где этой сложности место.
В нашем канале «Tproger» разобрали подробнее.
@prog_stuff
Эссе, которое разбирают на Hacker News, начинается с наблюдения: перевести идею в инструкции для машины и решить, какие инструкции вообще должны существовать, — два разных занятия. Пример автора: «обрабатывать входящие события и обновлять данные». Синхронно или через очередь? Ровно один раз или хотя бы один? Что делать, если потребитель лежал три часа? Ни один из вопросов не про синтаксис.
Главный тезис: каждая оптимизация тратит сложность где-то ещё. Кеш даёт задержку и забирает инвалидацией, микросервисы дают независимые деплои и приносят распределённые отказы. Работа инженера — решать, где этой сложности место.
В нашем канале «Tproger» разобрали подробнее.
@prog_stuff
Почтовый CSV Японии рвёт строки посередине слова — и парсить его приходится всей стране
Пол О'Лири МакКанн, автор питоновской библиотеки posuto, разобрал ken_all.csv — файл, в котором Почта Японии раздаёт базу всех почтовых индексов. Формат легендарный: о нём регулярно ругаются в соцсетях, а один твит описывает грешников, которых в аду заставляют парсить этот файл вечно.
Внутри: если название района длиннее 38 символов, строка разрезается на несколько — в случайном месте, не по границе слова, — а остальные поля дублируются в каждой. В поле названия встречаются скобочные примечания «для читателя», ссылающиеся на порядок строк, — в формате, где строки должны быть самодостаточны. Поля не квотируются. На один индекс может приходиться до 66 строк.
Причину разрезания никто не объяснил; автор предполагает буфер фиксированной длины в системе тридцатилетней давности. Урок переживёт сам файл: данные, которые готовили для человеческого глаза, мстят машинному парсеру.
Статья — Parsing the Infamous Japanese Postal CSV
@prog_stuff
Пол О'Лири МакКанн, автор питоновской библиотеки posuto, разобрал ken_all.csv — файл, в котором Почта Японии раздаёт базу всех почтовых индексов. Формат легендарный: о нём регулярно ругаются в соцсетях, а один твит описывает грешников, которых в аду заставляют парсить этот файл вечно.
Внутри: если название района длиннее 38 символов, строка разрезается на несколько — в случайном месте, не по границе слова, — а остальные поля дублируются в каждой. В поле названия встречаются скобочные примечания «для читателя», ссылающиеся на порядок строк, — в формате, где строки должны быть самодостаточны. Поля не квотируются. На один индекс может приходиться до 66 строк.
Причину разрезания никто не объяснил; автор предполагает буфер фиксированной длины в системе тридцатилетней давности. Урок переживёт сам файл: данные, которые готовили для человеческого глаза, мстят машинному парсеру.
Статья — Parsing the Infamous Japanese Postal CSV
@prog_stuff
Как разобрать чужой бинарный формат: полный проход от файла сохранения до готовой схемы
Вам достался файл без спецификации: двоичный файл настроек прибора, сохранение игры, кеш программы. Автор ImHex — бесплатного открытого hex-редактора — годами отвечал на этот вопрос одной фразой «посмотри декомпилированный код того, кто его пишет», и наконец разобрал процесс целиком на файле сохранения игры FEZ.
Первый взгляд в hex-редактор уже даёт три вывода: в файле видны читаемые строки вроде
Остаток разбора — перенос этого порядка в Pattern Language, встроенный язык описания форматов ImHex:
Общий рецепт автор в конце сводит к четырём шагам: проверить, не известен ли формат (magic-детект ImHex,
@prog_stuff
Вам достался файл без спецификации: двоичный файл настроек прибора, сохранение игры, кеш программы. Автор ImHex — бесплатного открытого hex-редактора — годами отвечал на этот вопрос одной фразой «посмотри декомпилированный код того, кто его пишет», и наконец разобрал процесс целиком на файле сохранения игры FEZ.
Первый взгляд в hex-редактор уже даёт три вывода: в файле видны читаемые строки вроде
DOT_LOCKED_DOOR_A, значит он не сжат и не зашифрован; в начале нет сигнатуры, значит по ней формат не опознать. Дальше автор идёт к тому, кто файл пишет. FEZ написана на C#, её сборки декомпилируются почти в исходник; в EasyStorage находится класс PCSaveDevice, а в нём строка "SaveSlot" + index — то самое имя файла. Рядом метод Save, который заводит буфер на 40 960 байт и заполняет его через BinaryWriter. Порядок вызовов записи и есть структура файла.Остаток разбора — перенос этого порядка в Pattern Language, встроенный язык описания форматов ImHex:
struct с полями, размещение по адресу через оператор @, отдельные типы под строки, списки и перечисления. Схема одновременно и парсит файл, и документирует находки, и проверяет их: ошиблись в поле — данные перестанут сходиться.Общий рецепт автор в конце сводит к четырём шагам: проверить, не известен ли формат (magic-детект ImHex,
binwalk); найти код, который файл читает или пишет; опознать в нём привычные кирпичи — числа, строки, булевы значения, структуры; записать всё это схемой. Для .NET декомпилятор — Rider, для нативного кода — Ghidra, IDA или Binary Ninja, для JVM — Recaf.@prog_stuff
👍2
Ваш бинарник в Alpine может быть на 26% медленнее из-за libc, а не из-за кода
musl — лёгкая libc, на которой собраны образы Alpine и самодостаточные статические бинарники «один файл — и работает». Джонатан Эллис, сооснователь DataStax и многолетний глава проекта Apache Cassandra, замерил цену этого удобства на своей рабочей нагрузке.
Со штатным аллокатором musl проигрывает разгромно, причём на обычных четырёхъядерных машинах, а не только под высокой конкурентностью. Замена на mimalloc убрала большую часть разрыва, но 26% остались: профилирование указало на базовые процедуры работы с памятью внутри самой libc.
В нашем канале «Tproger» разобрали подробнее, включая то, что автор оставил для musl.
musl — лёгкая libc, на которой собраны образы Alpine и самодостаточные статические бинарники «один файл — и работает». Джонатан Эллис, сооснователь DataStax и многолетний глава проекта Apache Cassandra, замерил цену этого удобства на своей рабочей нагрузке.
Со штатным аллокатором musl проигрывает разгромно, причём на обычных четырёхъядерных машинах, а не только под высокой конкурентностью. Замена на mimalloc убрала большую часть разрыва, но 26% остались: профилирование указало на базовые процедуры работы с памятью внутри самой libc.
В нашем канале «Tproger» разобрали подробнее, включая то, что автор оставил для musl.
METR разобрала, как у неё украли API-ключ: приложение, написанное с ИИ, при сбое проверки прав пускало всех
Лаборатория, которая тестирует модели для крупных разработчиков, опубликовала отчёт о двух инцидентах. В марте исследователь поднял на личном EC2-инстансе маленькое веб-приложение за входом через Google. В коде была ошибка fail-open: если проверка авторизации не срабатывала, приложение считало пользователя допущенным. Инстанс несколько дней смотрел в интернет, атакующий вытащил ключ к моделям, добавил свой SSH-ключ и три недели гонял чужие запросы.
Заметить было трудно: за кредиты METR не платила деньгами, так что счёт не рос, а внутренняя панель METR не показывала отклонённые по лимитам запросы. В мае пришла вторая волна: сканирование, перебор паролей, попытки через OAuth-токены и ошибка в публичном просмотрщике транскриптов с read-only SQL.
Выводы для любой команды: ключи только в секрет-хранилище, приложения с доступом к ключам делать fail-closed, на каждый ключ лимит и алерт по числу запросов, а не только по деньгам. Полный разбор цепочки на сайте.
@prog_stuff
Лаборатория, которая тестирует модели для крупных разработчиков, опубликовала отчёт о двух инцидентах. В марте исследователь поднял на личном EC2-инстансе маленькое веб-приложение за входом через Google. В коде была ошибка fail-open: если проверка авторизации не срабатывала, приложение считало пользователя допущенным. Инстанс несколько дней смотрел в интернет, атакующий вытащил ключ к моделям, добавил свой SSH-ключ и три недели гонял чужие запросы.
Заметить было трудно: за кредиты METR не платила деньгами, так что счёт не рос, а внутренняя панель METR не показывала отклонённые по лимитам запросы. В мае пришла вторая волна: сканирование, перебор паролей, попытки через OAuth-токены и ошибка в публичном просмотрщике транскриптов с read-only SQL.
Выводы для любой команды: ключи только в секрет-хранилище, приложения с доступом к ключам делать fail-closed, на каждый ключ лимит и алерт по числу запросов, а не только по деньгам. Полный разбор цепочки на сайте.
@prog_stuff
Один параметр readahead сократил обращения к диску в 12 раз, а io_uring тут ни при чём
Фернандо Симойнс разбирал, почему его встраиваемая СУБД на io_uring не выигрывала у обычного чтения на сканах. Тест: запрос Q6 из TPC-H по таблице в 1,2 GiB, файл открыт с
Без упреждающего чтения база отправила 195 тысяч запросов по 4 KiB, и почти столько же дошло до устройства: ядру нечего было склеивать. С окном readahead в 32 страницы запросов в очереди стало даже больше, 218 тысяч, но до диска добралось около 16 тысяч. Ядро объединило 93% соседних чтений, средний запрос вырос с 4,37 до 56,53 KiB.
Цена тоже есть: поток
@prog_stuff
Фернандо Симойнс разбирал, почему его встраиваемая СУБД на io_uring не выигрывала у обычного чтения на сканах. Тест: запрос Q6 из TPC-H по таблице в 1,2 GiB, файл открыт с
O_DIRECT, запросы на чтение уходят в очередь io_uring.Без упреждающего чтения база отправила 195 тысяч запросов по 4 KiB, и почти столько же дошло до устройства: ядру нечего было склеивать. С окном readahead в 32 страницы запросов в очереди стало даже больше, 218 тысяч, но до диска добралось около 16 тысяч. Ядро объединило 93% соседних чтений, средний запрос вырос с 4,37 до 56,53 KiB.
Цена тоже есть: поток
sqpoll, который опрашивает очередь вместо системных вызовов, съел 65% циклов процессора. Вывод автора в том, что io_uring не ускоряет сам по себе, а только даёт очередь, и без прогрева этой очереди последовательными чтениями выигрыша нет.@prog_stuff
Посмотрите, как выглядят 128 килобайт, если каждый бит — отдельное ферритовое колечко
Spacelab — европейская лаборатория, которую возили в грузовом отсеке шаттла. Компьютеры NASA туда не поставили: программа была европейской, и внутри работали три одинаковых французских миникомпьютера Mitra 125 MS. Один вёл саму лабораторию, второй эксперименты, третий стоял резервом.
Памяти в таком компьютере 128 килобайт, и собрана она на магнитных сердечниках: каждый бит — крошечное ферритовое кольцо на пересечении проводов, а значение бита — направление его намагниченности. На фото блок из семи плат, занимающий примерно треть корпуса. Боковая панель снимается вместе с ним: тепло здесь отводится через плотный контакт с этой панелью, без всякого обдува.
Кен Ширрифф разобрал модуль до отдельных проводов: как устроены плоскости сердечников, что делает плата драйверов и почему чтение здесь стирает прочитанное значение, так что его каждый раз приходится записывать обратно.
@prog_stuff
Spacelab — европейская лаборатория, которую возили в грузовом отсеке шаттла. Компьютеры NASA туда не поставили: программа была европейской, и внутри работали три одинаковых французских миникомпьютера Mitra 125 MS. Один вёл саму лабораторию, второй эксперименты, третий стоял резервом.
Памяти в таком компьютере 128 килобайт, и собрана она на магнитных сердечниках: каждый бит — крошечное ферритовое кольцо на пересечении проводов, а значение бита — направление его намагниченности. На фото блок из семи плат, занимающий примерно треть корпуса. Боковая панель снимается вместе с ним: тепло здесь отводится через плотный контакт с этой панелью, без всякого обдува.
Кен Ширрифф разобрал модуль до отдельных проводов: как устроены плоскости сердечников, что делает плата драйверов и почему чтение здесь стирает прочитанное значение, так что его каждый раз приходится записывать обратно.
@prog_stuff
👍2❤1
JetBrains не пропатчила собственный TeamCity, и через него вынесли бэкап сервиса Cadence, AWS-учётки и файлы из S3
Компания обновила отчёт об инциденте. Cadence, облачный сервис для запуска вычислений из PyCharm, использовал TeamCity для оркестрации задач. В нём была CVE-2026-63077 с выполнением команд без аутентификации, и с 8 по 24 августа атакующие сидели на
Что утекло: логины, имена, почта и IP пользователей; полный бэкап сервера за 2024 год; AWS IAM-пользователи с учётными данными; файлы в S3-бакетах JetBrains. Мог быть доступен исходный код, который пользователи синхронизировали из PyCharm. Затронуты ли бакеты клиентов, компания пока не установила.
Рекомендация JetBrains тем, кто подключал Cadence: считать скомпрометированным всё, к чему у сервиса был доступ, от ключей облаков до SSH и ключей подписи. Хронологию и список секретов на замену разобрали на сайте.
@prog_stuff
Компания обновила отчёт об инциденте. Cadence, облачный сервис для запуска вычислений из PyCharm, использовал TeamCity для оркестрации задач. В нём была CVE-2026-63077 с выполнением команд без аутентификации, и с 8 по 24 августа атакующие сидели на
api.cadence.jetbrains.com. Обнаружили 23-го, отключили 24-го. Формулировка JetBrains: «сервер должен был быть пропатчен, но не был».Что утекло: логины, имена, почта и IP пользователей; полный бэкап сервера за 2024 год; AWS IAM-пользователи с учётными данными; файлы в S3-бакетах JetBrains. Мог быть доступен исходный код, который пользователи синхронизировали из PyCharm. Затронуты ли бакеты клиентов, компания пока не установила.
Рекомендация JetBrains тем, кто подключал Cadence: считать скомпрометированным всё, к чему у сервиса был доступ, от ключей облаков до SSH и ключей подписи. Хронологию и список секретов на замену разобрали на сайте.
@prog_stuff
🙈2