LINUX.ORG.RU

Уязвимость в Rust-библиотеках для формата TAR, приводящая к распаковке файлов из вложенного архива

 , ,

Уязвимость в Rust-библиотеках для формата TAR, приводящая к распаковке файлов из вложенного архива

0

7

В написанной на языке Rust библиотеке async-tar, предоставляющей функции для чтения и записи tar-архивов, выявлена уязвимость (CVE-2025-62518, кодовое имя TARmageddon), позволяющая при распаковке специально оформленного tar-архива не только извлечь размещённые в нём файлы, но и файлы, содержащиеся во вложенном tar-архиве. Уязвимость может быть использована для обхода систем верификации архивов и распаковки файлов, для которых не выполнялась проверка.

Уязвимость также проявляется в форках библиотеки async-tar, таких как tokio-tar, krata-tokio-tar и astral-tokio-tar, а также в утилитах на их основе, например, в пакетном менеджере uv, развиваемом в качестве высокопроизводительной замены «pip» для проектов на языке Python. Из популярных проектов, использующих уязвимые библиотеки, также отмечаются инструментарий testcontainers для запуска docker-контейнеров и WebAssembly runtime wasmCloud. В репозитории crates.is за последние 90 дней библиотека async-tar насчитывает 1.3 млн загрузок, tokio-tar - 2.2 млн, testcontainers - 2.9 млн.

Уязвимость вызвана некорректным выбором позиции при разборе разных значений размера в заголовках ustar и PAX. В tar-архивах в формате PAX для каждого файла внутри архива указываются два заголовка - классический ustar и расширенный PAX. Проблема вызвана тем, что уязвимые библиотеки при распаковке файлов вместо вычисления смещения на основе размера из расширенного заголовка PAX, брали размер из устаревшего заголовка ustar. При нулевом значении размера в заголовке ustar, идущее за ним содержимое файла обрабатывалось как корректный блок TAR-заголовков для следующего файла.

Для совершения атаки достаточно создать TAR-архив, в котором в ustar-заголовке указан нулевой размер, а в заголовке для формата PAX актуальный размер, из-за чего содержимое файла с другим tar-архивом будет обработано как часть основного архива. Пример кода для создания подобных архивов размещён на GitHub. Уязвимость устранена в выпусках tokio-tar 0.5.6 и uv 0.9.5. Для остальных библиотек исправления пока не опубликованы, но для astral-tokio-tar, async-tar и krata-tokio-tar отдельно подготовлены патчи.

Уязвимости в библиотеках присвоен уровень опасности 8.1 из 10, так как проблема может использоваться для перезаписи распаковываемых файлов (в уязвимых реализациях будут распакованы не те файлы, что были видны в архиве). При этом уязвимость в пакетном менеджере uv отмечена как неопасная, так как если атакующий может влиять на содержимое исходного архива, нет смысла усложнять атаку и эксплуатировать уязвимость через вложенный архив, когда можно добиться выполнения кода через сборочные сценарии в основном архиве.

Выявившие уязвимость исследователи предложили несколько гипотетических сценариев атак, позволяющих обойти проверки безопасности и добиться выполнения кода через замену файлов конфигурации или вмешательство в сборочный процесс. Подразумевается, что присланный архив сможет пройти автоматизированную проверку сканером безопасности и ручной аудит, в ходе которого проверяющий не обратит внимание на странный вложенный архив с другими файлами, после чего при распаковке при помощи Rust-библиотек из архива будет извлечено иное содержимое, чем ожидалось.

Например, атакующий может загрузить модифицированный архив в репозиторий PyPI, который пройдёт проверку на основе анализа содержимого основного архива, содержащего легитимный файл pyproject.toml. При обработке данного пакета при помощи утилиты uv легитимный pyproject.toml будет заменён на вредоносный вариант из вложенного архива, содержащий команды, которые будут выполнены при сборке на компьютере разработчика или в системе непрерывной интеграции. Аналогично, можно организовать перезапись файлов контейнера при извлечении образа контейнера при помощи инструментария testcontainers.

>>> Подробности на OpenNET

★★★★★

Проверено: dataman ()
Последнее исправление: dataman (всего исправлений: 2)
Ответ на: комментарий от andalevor

Мне не ясно что за отношения такое к икслючениям. Нужно понимать разницу между критическими ошибками и нет. Если кто-то там не понимает и юзают исключениям там, где надо возвращать коды - то это его проблемы, не исключений. Для понимающих эту разницу исключения предлагают механизм, который чист и элегантен, он освобождает от необходимости протаскивать говно по стеку вызовов до самого верха, это очень большая плюшка.

Вот хотел ты взять данные с датчика, вызвал функцию - а тебе в ответ: «датчик не подключен», какой тебе толк от такого кода возврата? Что ты там исправишь? Тут может быть только одно действие - передать управление наверх, и вот ты будешь тягать все это говно в своем расте, а скорее всего просто абортнишься, как делают это многие растаманы не жалая париться. Или какая-то васянка возвращает тебе ошибку -1, и чего? Что ты с этим будешь делать? Запись в лог: «васянка барахлит» - самое оно в данной ситуации.

kvpfs_2
()
Ответ на: комментарий от kvpfs_2

Какое отношение? Выше товарищ правильно указал объективный недостаток реализации исключений в плюсах и некоторых других языках. Если нужно грепать исходники библиотеки чтобы понять кидает ли она исключения и какие, то это не самый удобный подход.

где надо возвращать коды

В плюсах нет проверки компилятора, что вызывающий код обработал код возврата.

тебе в ответ: «датчик не подключен», какой тебе толк от такого кода возврата?

Зависит от ситуации. Может покажу окошко «Вася, подключи датчик» и буду ждать пока не подключит.

передать управление наверх

В расте тоже можно прикинуть ошибку наверх. Только это будет явно через «?» и компилятор заставит наверху обработать эту ошибку. Иначе код не соберётся.

Или какая-то васянка возвращает тебе ошибку -1

На сишке так и будет. А в расте будет enum с конкретным значением варианта. И можно будет в лог записать не просто, что васянка барахлит. А конкретную причину почему она барахлит. А скорее всего, зная заранее причины почему васянка может барахлить, я смогу придумать как обработать на месте и не надо будет логов и слёз пользователя.

andalevor ★★★
()
Последнее исправление: andalevor (всего исправлений: 1)
Ответ на: комментарий от andalevor

Какое отношение? Выше товарищ правильно указал объективный недостаток реализации исключений в плюсах и некоторых других языках. Если нужно грепать исходники библиотеки чтобы понять кидает ли она исключения и какие, то это не самый удобный подход.

Ничего он правильно не указал. Во-первых, либы обычно не кидают исключений, исключения живут внутри модуля и за его пределы не выходят. Даже если там плюсовое сердце в либе, интерфейс скорее всего будет чисто сишным. Во-вторых, если исключения правильно используются, тот нет никакой проблемы даже если они вылетают из либы. Они не летят по ерунде, они летят в случае критических ошибок, перехватывать или нет - сам решай, если софтина простенькая, то нет никакого смысла, получишь корку и разберешься в проблеме основательно.

Unwrap’ы же в растовых либах - вот это действительно беда. Это ты уже не обойдешь и не перехватишь (ведь раст вей не рекомендует). И может так получиться, что заюзаешь такую либу в своем «важном» проекте, который упадет из-за этого говна в самый неподходящий момент. Вот растовые либы нужно действительно грепать с лупой в руках на предмет такого говна. Распространенность данной практики я привел на живом примере дав ссылку на почти первый поисковый запрос, и это не маргинальщина какая-то, а либа с несколькими десятками тысяч лайков. И это все при том, что товарищ «мамой клялся», что в растовых либах unwrap’ов нет.

В плюсах нет проверки компилятора, что вызывающий код обработал код возврата.

Кто тебе такое сказал? Смотри:

enum E {
    a, b, c
};

E f() { return c; }

int main() {
    switch (f()) {
    case a: break;
    case b: break;
    }
}

$ g++ 1.cpp -Wall
1.cpp: In function ‘int main()’:
1.cpp:9:16: warning: enumeration value ‘c’ not handled in switch [-Wswitch]
    9 |         switch (f()) {
      |                ^

Зависит от ситуации. Может покажу окошко «Вася, подключи датчик» и буду ждать пока не подключит.

Не будешь ты ничего ждать. В общем случае показывать какие-то там окошки может только главный поток, чем станет твой код в будущем и каким потоком выполняться ты точно не знаешь. Плюс к тому блокать софтину - нельзя, на верхнем уровне у потока могут быть и другие задачи. Архитектурно неверно делать как ты хочешь, ошибку нужно передавать наверх. А ещё представляешь, я ведь могу и не кидать исключение, а обработать ошибку на месте, все на мое усмотрение, но у меня есть такая опция

В расте тоже можно прикинуть ошибку наверх. Только это будет явно через «?» и компилятор заставит наверху обработать эту ошибку. Иначе код не соберётся.

Я прекрасно знаю, что ошибку можно передать, её можно и передать в плюсах. Но тут есть масса неудобства, главная из которых - ты засираешь код обработкой не штатных путей исполнения, а исключительных, которых может быть бесконечно много. Как показывают наблюдения, растаманы об этом догадываются и шлепают unwrap даже в либах, дабы не париться с этим. Исключения же тебе дают возможность не морочить себе голову, они делают все сами, чисто, отдельно от основной логики программы.

На сишке так и будет. А в расте будет enum с конкретным значением варианта. И можно будет в лог записать не просто, что васянка барахлит. А конкретную причину почему она барахлит.

Ты думаешь, что я через исключение не передам контекст ошибки? Да могу передать колл стек с параметрами вызова васянки для воспроизведения проблемы.

А скорее всего, зная заранее причины почему васянка может барахлить, я смогу придумать как обработать на месте и не надо будет логов и слёз пользователя.

Ни хрена ты знать не будешь, пока не получишь в лог данную ошибку с контекстом, повторишь её и разберешься, вот тогда ты её сможешь (возможно) пофиксишь на месте. Вот и я как разберусь перестану кидать исключение здесь. Только для меня цена переброса ошибки в виде исключения == около нуля, для тебя же == боль с правкой основного кода программы, который отлажен.

kvpfs_2
()
Ответ на: комментарий от kvpfs_2

либы обычно не кидают исключений

Но ведь может. И чтобы узнает кидает или нет тебе придётся изучать исходники или скрестить пальцы и надеяться.

исключения живут внутри модуля и за его пределы не выходят

Это гарантия языка?

перехватывать или нет - сам решай

Ты раз за разом пишешь одно и тоже, но не отвечаешь на поставленный вопрос. Как в плюсах по сигнатуре функции понять тип исключения если я таки хочу перехватить?

Это ты уже не обойдешь и не перехватишь (ведь раст вей не рекомендует)

Почему не перехвачу? Раст не рекомендует использовать панику как исключения в плюсах. Это верно.

Кто тебе такое сказал? Смотри:

Смотрю:

enum E { a, b, c };

E f() { return c; }

int main() { f(); }

$ g++ main.cpp -Wall

Никаких предупреждений даже не говоря о том чтобы отказаться такое компилировать.

чем станет твой код в будущем

Ты на бегу придумываешь дополнительные условия и героически показываешь как ты решаешь тобою же выдуманные гипотетические проблемы. Это всё не очень интересно. Тебе чётко пишут, что в расте паника это метод обработки ошибок. Для обработки ошибки есть штатный метод, при чём в отличии от плюсов, в расте нельзя «забыть» обработать ошибку. А в плюсах легко. Хоть код возврата (выше показал), хоть исключение. Компилятор никак не гарантирует что код обрабатывает ошибки.

её можно и передать в плюсах

Можно передать, а можно потерять. При этом в плюсах код как раз будет засран if (err) return.... А в расте постарались минимизировать этот шум, но при этом всё ещё видно в коде что куда прокидывает.

Ни хрена ты знать не будешь

В расте я явно увижу в сигнатуре функции может ли она вернуть ошибку или нет и если да, то какие есть варианты. И могу на каждый вараинт написать обработчик сразу, ещё до запуска. А в плюсах скорее всего да, придётся ловить на верхнем уровне и читать логи.

andalevor ★★★
()
Ответ на: комментарий от snake266

Ну, хорошо хоть в 17м добавили. Правда надо теперь не забывать обмазывать всё этим атрибутом. Всё же логичнее наоборот делать. Чтобы по умолчанию было поведение nodiscard и атрибут для того чтобы в единичных случаях допускать отбрасывание значения.

andalevor ★★★
()
Ответ на: комментарий от andalevor

Всё же логичнее наоборот делать. Чтобы по умолчанию было поведение nodiscard и атрибут для того чтобы в единичных случаях допускать отбрасывание значения.

Плюсовики бы взвыли от того, что им сломают обратную совместимость, да и комитет бы такое сам не допустил.

snake266 ★★★
()
Ответ на: комментарий от andalevor

Но ведь может. И чтобы узнает кидает или нет тебе придётся изучать исходники или скрестить пальцы и надеяться. Ты раз за разом пишешь одно и тоже, но не отвечаешь на поставленный вопрос. Как в плюсах по сигнатуре функции понять тип исключения если я таки хочу перехватить?

Почему тебе раз за разом надо объяснять одно и тоже? В своей софтине ты и сам прекрасно знаешь типы исключений, заведи там хидер exceptions.hpp. Если либа внешняя и не твоя, кидает исключения (что маловероятно), ну лови через catch(…), в чем проблема то? Там же можешь выяснить тип (нестандартно), ну и если тебе так хочется, то выяснив тип написать catch конкретно под это исключение. Ну или просто оставить это исключение на дефолтный обработчик, получишь корку и тип.

Вся эта дрочь с указыванием типов возможных исключение - всё это проходили, было, окончательно депрекейтнули. В этом и плюс, что мне не надо ничего править в коде, критические живут в сторонке.

Почему не перехвачу? Раст не рекомендует использовать панику как исключения в плюсах. Это верно.

Поэтому и не перехватишь? В чем ты возражаешь-то? Коллеги говорили против перехвата, в сети не рекомендует данный метод, дефолтно раст собирает конфигурацию, которая безусловно абортится независимо от наличия std::panic::catch_unwind. Вот именно поэтому рандомный растоман может конкретно так ткнуться в дерьмо и уронить свой софт, который не дай бог чем-то важным управляет.

Можно передать, а можно потерять. При этом в плюсах код как раз будет засран if (err) return…. А в расте постарались минимизировать этот шум, но при этом всё ещё видно в коде что куда прокидывает.

Ты сектант, ты вообще не воспринимаешь аргументы. То, во что превращается код на расте я показал выше, как несколько плюсовых строк превращаются в многословную портянку на расте

Тебе чётко пишут, что в расте паника это метод обработки ошибок.

Ты наркоман?

По остальному: ты придумываешь какие-то проблемы, которые героически вызвался решать раст. Я тебе ещё раз пишу - критические ошибки в плюсах не мешаются с основным кодом, они отдельно, ничего не засирают как в расте. Я ничего там не забываю, в коде я занимаюсь штатными путями выполнения, а не дрочусь с исключительными кейсами. Понимаешь? Хватит писать какую-то чушь про то что чего-то там забыть, если я не проверяю код возврата, значит мне оно не надо, критических ошибок там нет. Сам придумал проблему, которую должен решить раст. Мне абсолютно плевать, что там написано в твоей методичке

kvpfs_2
()
Ответ на: комментарий от kvpfs_2

всё это проходили, было, окончательно депрекейтнули. В этом и плюс, что мне не надо ничего править в коде, критические живут в сторонке.

Сектант здесь похоже ты, и довольно-таки воинствующий.

Если ниже по коду гарантированно не будет выбрасываться исключений, то компиллятор может вырезать все места со stack unwinding. Лет 10 назад об фиче noexept твердили из каждого утюга. И в то же время из каждого утюга говорили о сум-типах и монадическом подходе обработки результата работы функции. И про nodiscard из каждого утюга.

Там в С++ комитете все сыты по горло исключениями и проблемами, которые они несут. Навскидку, исключениями в прости-господи асинхронных корутинах.

И тут в младоязыках предлагается сильно более лучший подход к обработке ошибок.

sarumeister
()
Ответ на: комментарий от sarumeister

Если ниже по коду гарантированно не будет выбрасываться исключений, то компиллятор может вырезать все места со stack unwinding. Лет 10 назад об фиче noexept твердили из каждого утюга. И в то же время из каждого утюга говорили о сум-типах и монадическом подходе обработки результата работы функции. И про nodiscard из каждого утюга.

Ты это к чему? Ты знаешь где нужен noexcept?

Там в С++ комитете все сыты по горло исключениями и проблемами, которые они несут. Навскидку, исключениями в прости-господи асинхронных корутинах.

А тебе кто-то уполномочивал говорить от имени комитета? У них есть какое-то согласованное мнение? Чего они фичи-исключения подкидывают в новых стандартах, ведь голосуют за них как-то? Или ты один из неосилляторов, который прочел пару статей от других неосилляторов?

И тут в младоязыках предлагается сильно более лучший подход к обработке ошибок.

Нет

kvpfs_2
()
Ответ на: комментарий от kvpfs_2

Или ты один из неосилляторов, который прочел пару статей от других неосилляторов?

Видимо так. Как там комитет сыт по горло своими исключениями, так я сыт комитетом. Теперь мои проекты если на стероидах, то или на С++98 с вкраплениями auto/noexcept/nodiscard, или на зиге.

sarumeister
()
Ответ на: комментарий от sarumeister

Теперь мои проекты если на стероидах, то или на С++98 с вкраплениями auto/noexcept/nodiscard, или на зиге.

Да я не против, дело личное. Но говорить за комитет - это слишком. Если у них там и правда сложилось мнение, что вот мол исключения - говно, то это аргумент, который сложно не принять. Но ведь ты это придумал.

kvpfs_2
()
Ответ на: комментарий от sarumeister

Всё так кроме «младо», монадическая обработка ошибок давно зародилась просто, в основном, в функциональщине обитала

zurg
()
Последнее исправление: zurg (всего исправлений: 2)
Ответ на: комментарий от kvpfs_2

Там же можешь выяснить тип (нестандартно), ну и если тебе так хочется, то выяснив тип написать catch конкретно под это исключение.

Это работает ровно до момента, когда библиотека будет обновлена. Изменился АПИ или нет, ты узнаешь только проделав всю эту работу заново и сверившись с тем, как используется библиотека в твоей программе. Такой подход совершенно нежизнеспособен в большой программе с многими зависимостями, поддерживаемой разными людьми на протяжении многих лет.

unC0Rr ★★★★★
()
Ответ на: комментарий от sarumeister

Как раз поэтому существует такой пропозал «Zero-overhead deterministic exceptions».

вообще связи нет. Это не пропозал про выкорчевать исключения, а просто о деталях реализации всё тех же исключений.

kvpfs_2
()
Ответ на: комментарий от unC0Rr

Это работает ровно до момента, когда библиотека будет обновлена. Изменился АПИ или нет, ты узнаешь только проделав всю эту работу заново и сверившись с тем, как используется библиотека в твоей программе. Такой подход совершенно нежизнеспособен в большой программе с многими зависимостями, поддерживаемой разными людьми на протяжении многих лет.

Давай ещё раз отметим то, что либа вряд ли вообще кидает исключения (это не норма, обычно такого нет, либы скорее всего имеют чисто сишный интерфейс). Ок, соглашусь с тем, что если мы будем писать софт для управления ядерным реактором, то пусть либа имеет Си интерфейс, пусть автор поставит noexcept на функциях точках входа в либу. Все внутренние исключения либы, её автор пусть сам перехватывает и отправляет соответствующий код возврата. А если мне в своей софтине будет надо, то я это исключение rethrow своими внутренними типом (получив от функции из либы соответствующий код возврата). Если либа действует как-то иначе, то мы её не возьмем. Одобряешь, все ведь по уму? Ну а то, что исключения более удобны пердолинга с кодами возвратов (а enum’ы ещё и несовместимы из разных либ) я уже обосновал.

То ли дело растовый unwrap внутри либ, прелесть.

kvpfs_2
()
Последнее исправление: kvpfs_2 (всего исправлений: 1)
Ответ на: комментарий от kvpfs_2

пусть автор поставит noexcept на функциях точках входа в либу.

А ещё лучше - на всякий случай сделаем обертку на необходимыми функциями либы, которая будет перехватывать все исключения и возвращать какой-нибудь unexpected_error. Если мы получаем unexpected_error, то знаем, что автор мудак, и делаем throw Author_is_asshole__throw_out_the_library(«name»). Ну а чего, ядерный реактор ведь, все должно быть надежно

kvpfs_2
()
Ответ на: комментарий от kvpfs_2

выяснив тип написать catch конкретно под это исключение

Что за магия такая. Как написать обработку исключения когда не знаешь что стало его причиной?

Поэтому и не перехватишь? В чем ты возражаешь-то?

Перехватить можно? Факт. Не рекомендуется? Факт. Есть другой способ обработки ошибок? Факт. Не понимаю с чем ты споришь и почему так носишься с этими паниками. Тебе уже ткнули что часто unwrap в библиотеках если и используется, то в тех случаях, когда оно не может привести к панике. Как например уже показывали с парсингом статической строки.

Ты сектант, ты вообще не воспринимаешь аргументы.

Смешно такое читать от того, кто уже не первую страницу пытается всех убедить, что исключений не бывает в библиотечном коде, что ловить исключения не надо… Мощные у тебя аргументы. Только вот доказывают они не твою правоту, увы.

Ты наркоман?

Писал рано утром, потерялось «не». Вообще из контекста это видно. Но, видать, ты не на столько умён, как хочешь казаться.

ты придумываешь какие-то проблемы, которые героически вызвался решать раст

Ничего я не придумывал. Раст просто более приятный язык потому что дизайнился на опыте от применения других языков, но без необходимости тянуть тяжкий крест обратной совместимости. В отличие от другого языка, которые появился как нагромождение костылей на сишке и продолжает свою эволюцию в таком же ключе.

Я тебе ещё раз пишу - критические ошибки в плюсах не мешаются с основным кодом

В расте тоже можно пробрасывать ошибку хоть на самый верхний уровень и никакого загромождения кодом не будет. Ну считать же «?» загромождением. Зато аварийный путь будет чётко прослеживаться в коде. В отличие от.

если я не проверяю код возврата, значит мне оно не надо

А, ну раз тебе не надо, то никому не может быть надо. Дураки какие-то добавили в 17й стандарт nodiscard.

andalevor ★★★
()
Ответ на: комментарий от andalevor

Друг, чувствуется, что об исключениях ты знаешь лишь по каким-то рассказам, если говоришь что-то: «а как обрабатывать». Ты видел всякие сниппеты идиотов, которые оборачивают каждый вызов функции в try{}, вот примерно все, что знаешь про исключения.

unwrap его не страшит))), мол оно используется «когда оно не может привести к панике». Ты откуда знаешь? Ты проверял всё? Я бы отказался от либы, где нашел любой unwrap, пусть даже в примерах. Как отказался бы и от плюсовой васянки, где автор юзает голое new. А самое страшное - в вашем сообществе укореняется мысль, что unwrap - это нормально. Это грабли для все растаманов, на которые вы ещё не раз наступите. А причина всему этому - ваша система обработки критических ошибок ущербна и неудобна, поэтому и unwrap’ите.

kvpfs_2
()
Последнее исправление: kvpfs_2 (всего исправлений: 1)
Ответ на: комментарий от kvpfs_2

Это не пропозал про выкорчевать исключения

The community are voting with their feet:

• Major coding guidelines ban exceptions, including common modern guidelines endorsed by the world’s top advocates of C++ exceptions. For example, the Google C++ Style Guide [GSG] bans exceptions. The Joint Strike Fighter Air Vehicle C++ Coding Standards (JSF++) [JSF++ 2005] was produced by a group that included Bjarne Stroustrup and is published on Stroustrup’s personal website, and bans exceptions.

• Many projects ban exceptions. In [SC++F 2018], 52% of C++ developers reported that exceptions were banned in part or all of their project code — i.e., most are not allowed to freely use C++’s primary recommended error handling model that is required to use the C++ standard language and library.

• Committee papers such as [P0829R2] and [P0941R0] embrace standard support for disabling exceptions.

• The C++ Core Guidelines’ Guidelines Support Library [GSL] requires exceptions, and cannot be used in such projects. We are already getting requests for a nonthrowing version of GSL, which changes some of its interfaces (e.g., narrow reports errors by throwing narrowing_error and would have to change).

• Non-throwing dialects of the STL and the rest of the standard library proliferate, and C++ implementation vendors continue to receive requests to support those nonstandard dialects.

• Every C++ compiler supports a mode that disables exception handling (e.g., -fno-exceptions). This is an intolerable rift: Large numbers of “C++” projects are not actually using standard C++.

But switching to error codes isn’t the answer either — error codes cannot be used in constructors and operators, are ignored by default, and make it difficult to separate error handling from normal control flow.

2.2 Instead, we’re actively proliferating dual interfaces that do both

“Filesystem library functions often provide two overloads, one that throws an exception to report file system errors, and another that sets an error_code.” — [N3239]

Because we cannot universally recommend either exceptions or error codes, the community and even the committee are proliferating dual error reporting interfaces that support both, by providing throwing and non-throwing alternatives. Worse, the ‘non-throwing’ alternatives in the standard are only non-throwing for some kinds of errors, and still also throw to report other errors from the same function.

For example, the C++17 std::filesystem library supports reporting file system errors (only) as either exceptions or as error codes, often providing a pair of functions, one for each style; both functions still report non-file errors using exceptions.

– (с) Исключения очень хорошие. Замечательные даже.

sarumeister
()
Ответ на: комментарий от kvpfs_2

Друг, чувствуется, что об исключениях ты знаешь лишь по каким-то рассказам

В очередной раз наблюдаем «твои аргументы» вместо фактов которые бы меня размазали.

unwrap его не страшит

Я такого не говорил. Если тебе так интересно, то меня огорчит и unwrap не по делу. Но ты уже и сам писал, что любые использования паники в стиле исключений плюсов в раст сообществе порицаются. А потому столкнутся с таким непотребством шанс невелик. Если кто в утилите натыкал unwrap, значит решил что падение утилиты в этих случаях нормальное поведение и ничего страшного тут нет. А если в либе будет утыкано unwrap’ами, то такую либу все будут обходить стороной. В плюсах же вполне вероятно натолкнуться на исключения потому что это штатный плюсовый способ обработки ошибок. И про проблемы с плюсовыми исключениями тут не я один тебе писал. Но началось всё не с этого. Началось всё с того, что меня умилило твоё желание опорочить рас на ровном месте и сначала ты заявлял, что в плюсах ронять исключением приложение это норма, а в случае с растом заговорил про атомные реакторы. Это просто изумительно!

andalevor ★★★
()
Ответ на: комментарий от sarumeister

Ну цитируешь ты мне какой-то пропозал, который так и не приняли, и? Я с исключениями проблем не вижу, мне не очень хочется прям сейчас досконально изучать что они там предлагают, но в начале позабавило:

§4.1: “C++” projects commonly ban exceptions, because today’s dynamic exception types violate the zerooverhead principle, and do not have statically boundable space and time costs. In particular, throw requires
dynamic allocation and catch of a type requires RTTI.

вот местные растаманы запостили такое:

fn read_file() -> Result<String, Box<dyn Error>> {
    let message: String = fs::read_to_string("message.txt")?;
    Ok(message)
}

Выделение памяти под Error в heap’е. Новомодный эффективный раст, что там про «dynamic allocation»?

PS: а вообще звучит как бред - раз в квартал там «dynamic allocation», не будем пользоваться. Это проблема для кого вообще? Google в chrome беспокоится?

kvpfs_2
()
Последнее исправление: kvpfs_2 (всего исправлений: 1)
Ответ на: комментарий от andalevor

А если в либе будет утыкано unwrap’ами, то такую либу все будут обходить стороной.

Я показал такую либу, и нет, там нет гарантий, что unwrap не сработает. unC0Rr показывал доку, там о подобном говорили, что мол если ошибка, то растаманы скорее всего захотят абортнуться и шлепают unwrap. И эту либу не обходят стороной, на её основе пишут http клиенты и серверы, тоже попсовые с десятками тысяч адептов. Те серверы/клиенты, в свою очередь, скорее всего тоже говнокодят десяток другой unwrap’ов. В итоге это все говно может упасть неожиданно. И на всё это смотрит армия растаманов, которая будет писать точно такое же дерьмо.

Началось всё с того, что меня умилило твоё желание опорочить рас на ровном месте и сначала ты заявлял, что в плюсах ронять исключением приложение это норма, а в случае с растом заговорил про атомные реакторы. Это просто изумительно!

Я в последний раз попытаюсь объяснить. Есть большАя разница между unwrap’ами раста и исключениями. Первые приводят к падению всей софтины, вряд ли это то, что хочется в ответственном софте. Сценарий использования исключений иной - если софт достаточно сложный и тем более ответственный, каждый обработчик каких-то событий будет обернут в свой try/catch, и любые исключения мы перехватим. В данном случае у софтины может отвалится какая-то функция, сделаем запись в лог, попробуем перезапускать периодически, может заведется, может нет, но софтина будет работать и что-то делать. Это надежней, чем unwrap и аборт в расте.

Если у тебя там ядерный реактор, то выше я предложил обернуть все вызовы, которые идут в библиотеку, если ты ловишь из либы исключение этой оберткой, то отправляешь свое (внутресофтовое) исключение с колл стеком и аргументами при вызове. В итоге - ты защищен от неизвестных тебе исключений из других либ, ты получишь в логе запись вида: «libtatata; call stack: …; args …». И идешь разбираться с этой проблемой.

Все ведь как мы любим?

kvpfs_2
()
Последнее исправление: kvpfs_2 (всего исправлений: 1)
Ответ на: комментарий от kvpfs_2

Я в последний раз попытаюсь объяснить. Есть большАя разница между unwrap’ами раста и исключениями.

Я весь внимание. Но ты так и не пояснил почему в плюсах можно подозрительную либу обернуть в try-catch, а в расте нельзя обернуть в catch_unwind.

andalevor ★★★
()
Ответ на: комментарий от andalevor

Странные вы ребята, только ленивый здесь и в инете не говорил, что мол это bad practice. У вас компиль, если я не ошибаюсь, дефолтно не поддерживает размотку стека, надо давать опцию. Вот так вы завезли в раст исключения, которых у вас нет)))

Ну т.е. ты признаешь, что проблем с непонятными исключениями из других либ в плюсах нет? Вопрос решаем тривиальной оберткой, а если мне не нужны подробности, то тупо catch(…) на верхнем уровне, если туда никогда не попадем, то и париться незачем и обертки не нужны. Ведь это был ваш главный аргумент против исключений.

А если учесть, что исключения вычищают код от говна и протаскивание его по стеку, то исключения хороши

kvpfs_2
()
Последнее исправление: kvpfs_2 (всего исправлений: 2)

Короче я не знаю, что вы спорите вот вам свежая статья на хабре из которой ясно следует несколько мыслей:

  • не тянет rust на язык высокого уровня, нет сахара, нет высокоурожайных абстракций типа ООП и слишком он многословный.

  • а в качестве языка «низкого» уровня замены Си пригоден он только для корпоратов, которым по каким-то причинам нужна безопасная работа с памятью.

Всё это разумеется ИМХО.

Ygor ★★★★★
() автор топика
Ответ на: комментарий от Ygor

Да ну, это тупой наброс. Напишем неидеоматичный закат солнца вручную, видите как странно и неудобно получилось? Значит раст говно.

unC0Rr ★★★★★
()
Ответ на: комментарий от Ygor

нет сахара,

лол что, а внимательно смотрел?

нет высокоурожайных абстракций типа ООП

дважды лол, ООП? высокоурожайный ??

zurg
()
Ответ на: комментарий от zurg

лол что, а внимательно смотрел?

Для сахарка уж слишком многословно со множеством закорючек.

дважды лол, ООП? высокоурожайный ??

Это совсем лолец тут согласен.

Ygor ★★★★★
() автор топика
Последнее исправление: Ygor (всего исправлений: 1)
Ответ на: комментарий от unC0Rr

Да ну, это тупой наброс. Напишем неидеоматичный закат солнца вручную, видите как странно и неудобно получилось? Значит раст говно.

Может и тупой наброс, но только чего-то дельного кроме очередных переписей консольных утилит ничего и не видно.

Ygor ★★★★★
() автор топика
Ответ на: комментарий от Ygor

Для сахарка уж слишком многословно со множеством закорючек.

Он же там специально наворотил чтобы пострашнее выглядело

Может и тупой наброс, но только чего-то дельного кроме очередных переписей консольных утилит ничего и не видно.

Ну реально, такие низкопробные заявы из методички начинающего растохейтера уже лет 5 назад было неприлично предъявлять.

zurg
()
Ответ на: комментарий от zurg

низкопробные заявы

Сорян, братан, но проектов уровня электрон/гсс/шланг/куте на расте не видать. А потому какие проекты - такие заявы.

Ygor ★★★★★
() автор топика
Ответ на: комментарий от apt_install_lrzsz

найден баг в софте на си растеры: ахаха, фуу, диды, шерето, дырявое, закопать!

найден баг в софте на расте растеры: не надо судить так строго, и вообще давайте забудем старую вражду, какое мы вам плохое зло сделали, да и вообще это не баг а фича

muzykantov
()
Ответ на: комментарий от Ygor

проектов уровня электрон

Какая-то странная предъява языку, который был создан в процессе написания нового браузерного движка с нуля.

unC0Rr ★★★★★
()
Ответ на: комментарий от kvpfs_2

Странные вы ребята, только ленивый здесь и в инете не говорил, что мол это bad practice

Делать panic! и unwrap? Да. bad practice

У вас компиль, если я не ошибаюсь, дефолтно не поддерживает размотку стека, надо давать опцию.

fn main() {
    let v = vec![1, 2, 3];
    let panics = std::panic::catch_unwind(|| v[99]).is_err();
    assert!(panics);
    println!("Hello, World");
}

компилится без ключей

Вот так вы завезли в раст исключения, которых у вас нет

Истории из серии «я познаю мир». Ты реально только недавно узнал, что в расте паники это по сути те же механизмы, что и исключения? Только разница в том паника не для обработки ошибок. Но это уже тут тебе 100 раз писали.

Ну т.е. ты признаешь, что проблем с непонятными исключениями из других либ в плюсах нет?

Я не знаю что тут признавать. «Аргументы», которыми ты меня «фанатика» пытаешься впечатлить, звучат весьма сомнительно. Ты по кругу повторяешь, что ронять программу исключениями это норма и куда лучше чем знать какой тип откуда может вылететь и обрабатывать эти ситуации так близко к месту возникновения, как можно. Или преподносишь как абсолютную истину вещи, которые не находят отражения в реальном мире. По типу что в либах никогда-никогда не используют исключения или что исключения всегда-всегда локализованы в единице трансляции.

А если учесть, что исключения вычищают код от говна и протаскивание его по стеку

Я уже в который раз пытаюсь понять, это «?» ты называешь говном, которым, видимо, заполнен код без исключений? Ну серьёзно. Я ж говорю, раст это не плюсцы в которых ты будешь писать if (err) return на каждом уровне. И это ещё мы не вспоминаем, что для того чтобы имитировать растовский result в плюсцах тоже придётся поприседать.

В общем, ты меня убедил только в одном. Любая проблема в плюсцах для тебя это «мелочь», «ерунда», «можно обойти», «нам так даже больше нравится!». Любая незначительная мелочь в расте для тебя это «ужос», «кашмар», «уронили мне ядерный реактор!». Но фанатик это я. Думаю, я хорошо понял твою точку зрения.

andalevor ★★★
()
Ответ на: комментарий от unC0Rr

Какая-то странная предъява языку, который был создан в процессе написания нового браузерного движка с нуля.

движок так и не заработал и был сдан в кунцкамеру.

А что странного?

Ygor ★★★★★
() автор топика
Ответ на: комментарий от andalevor

Делать panic! и unwrap? Да. bad practice
Истории из серии «я познаю мир». Ты реально только недавно узнал, что в расте паники это по сути те же механизмы, что и исключения? Только разница в том паника не для обработки ошибок. Но это уже тут тебе 100 раз писали.

Трусы или крестик. Чего ты как уж на сковородке? Исключения противоречат вашим ржавым концепциям, но и без них вы не можете, иначе любая либа уронит ваши хеллоу воролды, потому как каждый первый растаман нещадно юзает unwrap. Ты можешь называть это как угодно, но по факту - перехват и обработка ошибок. И у меня есть большие сомнения, насколько средний растоман-сектант осилит не наговнокодить здесь и сохранить инварианты. Вы фанатики, вместо логики у вас вера в безопасность своего язычка. И все мы будем иметь удовольствие лицезреть ещё одну пачку CVE, для которых не нужен никакой unsafe. Именно поэтому исключения у вас bad practice, ваши духовные лидеры не верят, что паства осилит

Я не знаю что тут признавать. «Аргументы», которыми ты меня «фанатика» пытаешься впечатлить, звучат весьма сомнительно. Ты по кругу повторяешь, что ронять программу исключениями это норма и куда лучше чем знать какой тип откуда может вылететь и обрабатывать эти ситуации так близко к месту возникновения, как можно. Или преподносишь как абсолютную истину вещи, которые не находят отражения в реальном мире. По типу что в либах никогда-никогда не используют исключения или что исключения всегда-всегда локализованы в единице трансляции.

Я достаточно объяснил. Больше не хочу на это тратить энергию. А твоё «так близко к месту возникновения, как можно» наталкивает на мысль, что в исключениях ты как свинья в апельсинах.

Я уже в который раз пытаюсь понять, это «?» ты называешь говном, которым, видимо, заполнен код без исключений? Ну серьёзно. Я ж говорю, раст это не плюсцы в которых ты будешь писать if (err) return на каждом уровне. И это ещё мы не вспоминаем, что для того чтобы имитировать растовский result в плюсцах тоже придётся поприседать.

Во-первых, в сотый раз повторяю - if (err) не является плюсовым подходом с исключениями. Код от этого избавлен, в нем ТОЛЬКО штатные пути выполнения. Второе - я уже писал почему коды ошибок неудобны, у меня нет желания много повторять, если кратко - начинаешь проект, не паришься, unwrap’ишь - ну а чего пусть падает в случае чего (норм стратегия для простого софта). В какой-то момент падать - больше не устраивает, хочешь передавать ошибки наверх. И с этого момента ты обречен переписать и заново разобраться во всем в своем коде. Исключения не имеют этого недостатка, они отдельны от основного кода.

Тут ты, наверняка, начнешь и дальше спорить, ну я уже вряд ли отвечу, слишком много времени это отнимает.

kvpfs_2
()
Последнее исправление: kvpfs_2 (всего исправлений: 1)
Ответ на: комментарий от kvpfs_2

Исключения противоречат вашим ржавым концепциям

Ага. В процитированном мною пропозале написано, что исключения точно так же противоречат с++ концепциям. Если убрать конструкторы и операторы – там без исключений никак.

sarumeister
()
Ответ на: комментарий от sarumeister

Если убрать [.....] операторы – там без исключений никак

А в каком языке программирования будет «как», если операторы из него убрать??.. ;))

Даже с исключениями... :))

Somebody ★★★★
()
Последнее исправление: Somebody (всего исправлений: 2)
Ответ на: комментарий от Somebody

А в каком языке программирования будет «как», если операторы из него убрать[/i??.. ;))

pub fn myDiv(a: anytype, b: @TypeOf(a)) !@TypeOf(a) {
    if (b == 0) return error.DivideByZero;
    return a / b;
}

Вообще никто не парится.

sarumeister
()
Ответ на: комментарий от kvpfs_2

Трусы или крестик. Чего ты как уж на сковородке?

У тебя проблемы с логикой. При чём серьёзные. В расте паника есть, но её не рекомендуют использовать для обработки ошибок на манер исключений в плюсах. Где ты тут видишь противоречие?

потому как каждый первый растаман нещадно юзает unwrap

Ты пока только громко кричишь, но ещё ни одного кейса не разобрал с доказательствами что конкретный unwrap лишний в какой-нить популярной раст библиотеке.

лицезреть ещё одну пачку CVE, для которых не нужен никакой unsafe

CVE есть даже в языках, где нет никакого unsafe и доступа к сырым указателям. Хочешь открыть всем глаза, что раст это не серебряная пуля?

Я достаточно объяснил. Больше не хочу на это тратить энергию.

У тебя пока только пустые возгласы. Которые к тому же часто противоречат другим твоим возгласам. Вместо конкретного кода и аргументов пока только вопли про фанатиков и сектантов. Но энергию ты, конечно, тратить не хочешь.

Во-первых, в сотый раз повторяю - if (err) не является плюсовым подходом с исключениями

Ты писал, что в расте весь код засран обработкой ошибок, но это не так. Потому что есть сахарок, но при этом явный. А если обрабатывать коды возврата в плюсах, то будет засран. Если же использовать исключения, то не будет засран, но в коде будут пути выполнения, которые не считываются напрямую. Но тебе тоже про это 100 раз писали. Я уже понял, что тебе на это плевать и для тебя норм в любой ситуации делать catch(…) наверху и валить приложуху.

начнешь и дальше спорить, ну я уже вряд ли отвечу, слишком много времени это отнимает.

Спорить это громкое название для того, что ты тут развёл. 0 аргументов в виде разбора кода. Только лозунги про unwrap, unsafe, фанатиков и сектантов. Если ты не хочешь приводить конкретных примеров, то лучше и правда не отвечай. Тут и так впору модераторов просить подчистить эту ветку в силу её бессмысленности.

andalevor ★★★
()
Ответ на: комментарий от kvpfs_2

да пусть убьются об стену, зачем им мешать. надо наоборот поддакивать и говорить что так и надо.

ckotctvo
()
Ответ на: комментарий от Somebody

Так операторы не убраны…

SupaDupaFloatingPoint operator/(const SupaDupaFloatingPoint& a, const SupaDupaFloatingPoint& b) {
    if (0 == b) {
        throw std::runtime_error("Division by zero in SupaDupaFloatingPoint");
    }
    return /* supa-dupa math */;
}

Убран перегруженный оператор как вот здесь ^^^^ в С++ коде.

sarumeister
()
Последнее исправление: sarumeister (всего исправлений: 1)
Ответ на: комментарий от sarumeister

Убран перегруженный оператор как вот здесь ^^^^ в С++ коде.

Так речь-то шла не об одном, а о множестве: «Если убрать конструкторы и операторы – там без исключений никак.»

То есть, «мухлюете»... :)

Somebody ★★★★
()
Ответ на: комментарий от zurg

Ну давай

Ну, на. :)

рассмотрим мифическую «близость к железу»

Ты явно не читаешь того, на что отвечаешь... Я ни слова не писал ни о какой «близости к железу», не говоря уже о каких-то там «мифах»...

Не умеете вы «в аргументированный спор», больно уж любите «убегать в сторону» от «основной сюжетной линии» и слишком даёте волю своей фантазии...

типичный сишник не верит официальной документации

«Набрасываешь», грубо и откровенно... Мне это говорит об отсутствии у тебя аргументов «по существу заданных ранее вопросов»..

в которой прямо написано что Це высокоуровневый язык с абстрактной машиной.

И что с того?? Это не имеет никакого отношения к тому, на что ты тут, якобы, отвечаешь.

Если сколько-нибудь осмысленно определять эту самую близость и не свалиться в сравнение синтаксиса ассемблерных вставок то это, примерно, возможности языка влиять на детали собственной реализации.

Бред какой-то. Ты отвечаешь не мне, а, видимо, своей буйной фантазии... На мои вопросы, заданные в комментарии, на который ты «вот этим вот всем», якобы, «отвечал», я ответа так и не увидел...

Итак.

И не так. :)

Дальнейшее твоё «сочинение на вольную тему» ни цитировать, ни комментировать смысла не вижу, ибо: «на мои вопросы, заданные в комментарии, на который ты „вот этим вот всем“, якобы, „отвечал“, я ответа так и не увидел» и, думаю, так никогда и не увижу, ибо нечего вам сказать, кроме общих фраз откровенно не в тему...

И это только про «низкоуровневые» фичи, и далеко не всё

Которых в твоём тексте я так и не увидел...

полноценный язык удобный для человеков есть в отличии от…

И снова откровенный наброс в сторону нелюбимых вами «сишников»... Не надо больше такого, пожалуйста...

если не будет лень распишу и про это.

Будет лень и не распишешь. :) Уже не «расписал», поскольку времени прошло много, а от тебя больше ни слова, ни буквы по теме...

Ну и ладно, не надо: решение я принял, и не в пользу Rust и Zig, поскольку «поиграться"с ними на МК, может, и забавно, но за С большой объём уже сделанных наработок, примеров и документации, так что вернусь-ка я „на С“... Уже вернулся. :)

Спасибо всем, принявшим участие (здесь, и не только) словом и советами по выбору языка разработки для китайских микроконтроллеров!..

Всех читал, кое-что попробовал, но выбрал „старый, добрый“ С. :))

Somebody ★★★★
()
Последнее исправление: Somebody (всего исправлений: 1)
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.
Тема будет перемещена в архив .