Google переписала библиотеку giflib с C на Rust и опубликовала результат как открытый проект giflib-rs. Библиотека задумана как эталонная реализация для команд, которые оценивают автоматизированные переходы между языками для базовых утилит.
Перевод выполнялся не вручную: логику C-библиотеки перенесла модель Gemini, а корректность проверялась непрерывным сравнением двух реализаций. Отдельный результат проверки — найденная в исходном C-коде внутренняя запись за границы, внесённая более ранним патчем.
Что именно изменилось
Переписывалась giflib — библиотека обработки изображений объёмом около 3000 строк кода. Чтобы новая реализация заменяла существующий shared objectразделяемая библиотека, которую подгружают исполняемые файлы во время запуска прозрачно, инженеры сохранили исходные экспортируемые символы и определения структур. Это делает giflib-rs ABI-совместимой заменойсовместимость на уровне двоичного интерфейса: вызывающий код не перекомпилируется.
Совместимость с C-вызовами обеспечивается тем, что экспортируемая функция помечена атрибутом #[no_mangle] — он запрещает компилятору менять имя символа, поэтому C-код находит функцию по прежнему имени, — и объявлена как pub unsafe extern "C" — соглашение о вызовах C, без которого вызывающий код не смог бы передать аргументы так, как ожидает функция. Внутри сырой указатель проверяется на null, и из него восстанавливается безопасный Rust-дескриптор: Box::from_raw забирает владение памятью, выделенной под структуру, обратно в Rust, чтобы дальше работать с ней как с обычным значением, а не как с сырым указателем. Так FFIинтерфейс вызова функций между разными языками, здесь — между C и Rust-обёртка не допускает undefined behaviourнеопределённое поведение, при котором компилятор вправе предполагать, что такого случая в программе не бывает при передаче указателей через границу C.
Предыстория
Вместо многолетних ручных преобразований или полной опоры на проверку границ во время выполнения инженеры Google применили трёхэтапный автоматизированный процесс миграциипроцесс из трёх шагов: сначала однократный промпт к Gemini переносит всю логику C-библиотеки в Rust, затем эксперты вручную уточняют небезопасную семантику сырых указателей в FFI, а в конце автоматическое дифференциальное тестирование находит расхождения и возвращает трассировки сбоев модели для итеративного синтеза патчей, построенный вокруг автономного цикла обратной связи.
В обсуждениях на r/rust и Hacker News участники противопоставляли подходу Google с одноразовым переводом идею детерминированных транспайлеров, таких как c2rustтранспайлер, который переводит C-код в Rust механически, по фиксированным правилам, без участия ИИ — в отличие от подхода Google, где перевод всей логики выполняет модель Gemini однократным промптом, с последующим AI-рефакторингом в безопасный идиоматичный Rust.
Отдельная линия предыстории — OSS-Fuzz, описанный как непрерывный фаззинг для open-source ПО. По состоянию на май 2025 года он помог выявить и исправить более 13 000 уязвимостей и 50 000 багов в 1 000 проектов.
Почему это сделали
Задача формулируется как устранение унаследованных уязвимостей памяти в старой инфраструктуре: повреждения памяти составляют около 70% серьёзных уязвимостей в зрелых стеках C и C++. Целевая библиотека показательна тем, что часто декодирует недоверенный пользовательский ввод без песочницы.
Конвейер проверки выявил необработанный крайний случай в LZW-декомпрессореалгоритм распаковки данных, используемый в формате GIF и внутреннюю унаследованную запись за границы, внесённую более ранним внутренним патчем в исходный C-код. Команда также сообщает, что нейтрализовала неустранённую heap write zero-day до её публичной каталогизации как CVE-2026-26740. Позже внешний исследователь обнаружил запись за границы кучи в upstream giflib, каталогизированную под тем же номером, а продакшн-узлы на скомпилированной Rust-замене оказались структурно невосприимчивы к дефекту до публичного раскрытия.
Как проверяли эквивалентность
Семантическую эквивалентность устанавливали против исторической реализации на C тремя способами.
Массовое регрессионное декодирование более 30 миллионов реальных GIF-файлов проверяло побитовое совпадение рендеринга. Параллельно автоматический дифференциальный фаззеринструмент, который подаёт одинаковые входные данные двум реализациям и сравнивает их поведение непрерывно прогонял обе среды бок о бок шесть дней и набрал 200 миллионов итераций без функциональных отклонений. Дополнительно в набор тестов входили состязательные промпты для LLMспециально составленные задания для языковой модели: она разбирает исходный код обеих реализаций — старой на C и новой на Rust — и ищет в них скрытые различия в поведении, которые не проявились при обычном прогоне тестов.
Именно автоматические движки дифференциального тестирования находили расхождения и передавали трассировки сбоев обратно модели для итеративного синтеза патчей.
Роль ИИ и роль человека
Первый этап — однократный промпт к Gemini для переноса всей логики C-библиотеки в Rust. Дальше начинается то, что автоматизировать не удалось: моделирование FFI изначально вносило небезопасную семантику сырых указателей, и экспертам-людям пришлось проверять и уточнять инварианты владения указателями и времени жизниправила, по которым код отвечает за освобождение памяти и не обращается к ней после освобождения; их нарушение ведёт к утечкам памяти и обращениям к уже освобождённым данным. Обёртки FFI, по признанию авторов, всё ещё требуют человеческой предметной экспертизы, чтобы предотвратить утечки времени жизни и сохранить инварианты потокобезопасности.
Что это меняет на практике
Для разработчиков, использующих giflib, миграция не требует изменения кода: ABI-совместимая замена сохраняет исходные экспортируемые символы и определения структур, поэтому существующие вызовы C-функций продолжают работать без перекомпиляции.
Телеметрия продакшена глобальных кластеров декодирования изображений подтвердила, что Rust-бинарник работал на уровне производительности оригинального C-бинарника. Снятие изоляции процессов дало заметное снижение p99 tail latencyвремя ответа, ниже которого укладывается 99% запросов. Результат опубликован как открытый проект giflib-rs.
Ограничения и открытые вопросы
Авторы подчёркивают, что переводы с помощью ИИ не являются полностью автоматическим решением. Ответвление upstream-зависимостей C в Rust-репозитории создаёт постоянное расхождение в сопровождении при каждом выпуске новых функций или архитектурных изменений upstream.
В обсуждениях участники подробно разбирали подход с одноразовым переводом, отмечая, что человеческие усилия по аудиту тонких семантических регрессий и исправлению небезопасных границ C FFI часто превышают объём самой генерации кода. Высказывалось мнение, что детерминированные транспайлеры вроде c2rust с последующим ИИ-рефакторингом в безопасный идиоматичный Rust могут оказаться надёжнее по мере роста библиотек за пределы простых самодостаточных целей вроде giflib.