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)
Ответ на: комментарий от Somebody

Но перечисленное тобой как-то не очень похоже на «вменяемое»

Это только с твоей точки зрения, а так то производители mcu предоставляют first class поддержку sdk на микропитоне и расте не просто так.

Но ты оказался банальный „мир“-дверь»-«мяч».

Утипути, какашечками мы умеем кидаться. Из детского садика ещё не вырос? Ну ничего, у тебя ещё всё впереди.

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

На твой 8-битный PIC просто ещё не успели портировать раст. Но тот же раст на микроконтроллерах - это не голословное утверждение, есть работающая экосистема, у espressive даже first class поддержка для раст сдк. Звиздишь по-ходу ты, если это отрицаешь.

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

Это только с твоей точки зрения, а так то производители mcu предоставляют first class поддержку sdk на микропитоне и расте не просто так.

Ну, производитель упомянутого мной семейства RISC-V микроконтроллеров тоже «предоставляет»... Но на С, на который ты ругаешься... :)

Утипути, какашечками мы умеем кидаться. Из детского садика ещё не вырос? Ну ничего, у тебя ещё всё впереди.

«Хамишь, парниша!» ©

Впрочем, я вижу, у тебя это обычная манера «общения». И нет, хам, до того, что у меня «впереди», ты, с такой-то манерой общения, ещё дожить сумей. :)

В общем, не знаешь ты на самом деле ничего «вменяемого» и, говоря о «вменяемом», просто пустоболил... А жаль, я-то уж понадеялся, что подскажешь что путное... Жаль, жаль... Правда, жаль. :)

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

assert_eq! - а чо не assert_eq!!!!!!1111адинадинадин

всратейший синтаксис, придуманый шизоидами обдолбаными окамлом.

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

Да-да, #define _ASSERT_H конечно намного лучше.

всратейший синтаксис, придуманый шизоидами обдолбаными окамлом.

Глупышка, растовый синтакс на ~80% совпадает сишным, а на остальные ~20% скопирован из других языков для фич, которых в сях нет. Если что-то и придумано, то это мизерная доля %.

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

Очевидно же раст, что за дурацкий вопрос. Да, RISC-V поддерживается. Вот всякие там сишки уже давно невменяемый инструмент, ни для чего. Она, даже, в этот самый «низкий уровень» не особо-то умеет.

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

Да ладно тебе, чё ты реально как сишная обиженка. Стучишь модерам, смайлики по всем темам побежал ставить. Спокойнее нужно быть.

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

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

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

Только это не он придумал, а те, кто форсируют переписывание с Си на Раст

Ну и где эти «те»? Мне кажется, что про повышение безопасности с помощью переписанных на раст утилит кудахчут разве что дефективные манагеры, которые берут Раст версии утилит чтобы впихнуть их в свой васян дистр. А сами переписыватели могут переписывать по разным причинам. Может устали в сях контейнеры вручную писать или надоело вручную ресурсы освобождать, а может просто по фану для себя.

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

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

Конечно, не понимаю. Чем критическая ошибка отличается от некритической и почему критическая не должна быть отражена в сигнатуре функции? Почему при вызове int a() я должен гадать, какие критические ошибки нужно ловить и какие действия можно предпринять?

сишный код остается чистым

Угу, чистый код - это когда нужно ознакомиться со всей программой, чтобы понять, каким может быть результат работы функции. Если ошибёшься - в лучшем случае аборт.

Если же программист достаточно умелый (внимание, исключения не для школьников), с умом задизайнил архитектуру софтины, то он может перехватывать упавшие задачи

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

Если сишник решает, … он просто даёт возможность отработать штатному обработчику исключений

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

if (return_code) - это вообще из другой оперы

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

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

Ага, но экспердное мнение, как обычно, имеешь.

Это кто вам такое сказал. Я имею свое мнение а для кого оно правильное а для кого нет решать уже не мне.

Ладно все таки я хочу узнать, от вас лично:

  1. unwarp - средство отладки программы.
  2. unwarp - средство обработки исключений.

Выберите 1 или 2.

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

Идиоматическая обработка ошибок в Rust - это оператор вопроса, который приводит к возврату ошибки если предыдущий вызов функции вернулся с ошибкой. И да, это там, где в C обычно приходится обмазываться лапшой из if-ов и местами goto-хами из-за отсутствия RAII (что, к примеру, часто можно лицезреть в исходниках Linux).

panic-и по своим свойствам это не совсем то же самое, что abort(), и в тех контекстах, где неожиданный выход из-за сработавшего unwrap()-а может быть проблемой (типа небезызвестного async I/O фреймворка Tokio) успешно ловятся. Но в Rust такой подход к обработке ошибок, за исключением ситуаций когда unwrap() может сработать лишь в случае логической ошибки в коде программы а не из-за каких-то внешних обстоятельств, не считается идиоматическим.

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

Очевидно же раст, что за дурацкий вопрос

О, ещё один «экземпляр класса» «хам обыкновенный», не умеющий разговаривать с людьми вежливо! :))

Какой у тебя ответ, надеюсь, ты сам догадаешься? ;) Вопрос риторический. :)

Ну ладно, давай к делу: раз ты, в отличие от своего «коллеги», хоть что-то конкретное в ответ на мой ему вопрос изрёк — расскажи мне, пожалуйста, что в Rust для микроконтроллеров CH32V003 более «адекватного», как выражается твой «коллега по хамству», в сравнении с С? С учётом того, что контроллеры «мелкие», и «железными» ресурсами «на борту» не богаты.

Что в нем такого-претакого, что может побудить меня изучать новый (для меня) язык?.. Конкретно, пожалуйста, если это возможно и если ты знаешь аргументированный ответ на этот вопрос. А то пустословием меня тут уже твой «коллега» «накормил», а мне бы что-нибудь более полезное узнать...

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

Вот всякие там сишки уже давно невменяемый инструмент, ни для чего.

Обосновать можешь, или так, просто «эмоционируешь»? ;))

Она, даже, в этот самый «низкий уровень» не особо-то умеет.

Поконкретнее, пожалуйста. Что именно, по твоему мнению (и знанию, я надеюсь) С для CH32V003 «не умеет»??.. Расскажи, пожалуйста, а то «А мужики-то не знают!», и продолжают писать на С... :))

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

Не знаю, как там с китайцами но для STM32 есть stm32-rs, когда я тестировал он требовал nightly тулчейн. Точно помню что у меня получилось собрать и запустить код под Cortex-M3, но разницу в размерах с сишной прошивкой я не замерял

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

Чувак утверждает, что для 8-битных микроконтроллеров альтернативы сям нет

Наглая, бессовестная ложь.

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

Я не полез проверять так ли это на самом деле, потому что лень

Однако же ты «набросил», сам об этом ничего не зная, по сути...

потому что почти везде есть более вменяемая альтернатива

Которую ты «заявил», но ничего внятного о ней рассказать не смог.

А вот человек смог, за что ему спасибо. Если он ещё сумеет обосновать «лучшесть» Rust в применении для микроконтроллеров по сравнению с С, я буду ему очень признателен и Rust обязательно попробую.

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

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

совпадает, ага конечно. если посильнее упороться, то и на 180% начнет совпадать.

а орательный знак нужен чтоб выпендриться. и ведь это не единственное «отличие», просто самое дурное.

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

Спасибо, информации тут уже вполне даостаточно дали, поищу-почитаю ещё...

Пока что нашёл для CH32V003 FORTH, который мне издавна знаком, но что выбрать, ещё не решил... :)

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

Но вообще, если работу работать, то надо ориентироваться на рынок, а это C/C++. А лично для себя, в удовольствие, я бы взял какой нибудь лисп – ну так «по приколу». Надо будет поискать может кто то подобное уже сделал.

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

Но вообще, если работу работать, то надо ориентироваться на рынок, а это C/C++.

Так и делал. Лет 12+ тому взад, когда работал «на дядю», писал для PIC контроллеров на Ассемблере, а потом и на С. В 1990-х, когда всё было недоступно, даже кроссассемблер для появившихся в доступе для приобретения PIC16C84 написал на FORTH F-PC, под ДОС, сам программатор разработал и собрал, и софт для него на том же FORTH написал, начитавшись даташитов от Microchip. Такая была тяга к знаниям и творчеству в области автоматизации. :)))

А лично для себя, в удовольствие, я бы взял какой нибудь лисп – ну так «по приколу». Надо будет поискать может кто то подобное уже сделал.

Понимаю. :)

Сам долго подумывал написать Forth, кросскомпилятор для «пиков», но, к счастью, не «раскачался», а там и санкции «выручили»: контроллеры сильно подорожали, а тут и китайцы подоспели с явно более выгодными вариантами, на которые я и решил «переехать»... :)

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

а те, кто форсируют

Это как? Взяли в заложники котёнка и заставили переписать? Или просто разрабы пишут то, что хотят, на том языке, который им нравится, не спрашивая мнение посторонних идиотов?

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

Если он ещё сумеет обосновать «лучшесть» Rust в применении для микроконтроллеров по сравнению с С, я буду ему очень признателен и Rust обязательно попробую.

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

Но ты можешь ещё посмотреть на Zig, это более интересный язык для микроконтроллеров.

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

битовых полей

Реализуются библиотекой.

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

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

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

Почему при вызове int a() я должен гадать, какие критические ошибки нужно ловить и какие действия можно предпринять?

Не надо гадать, не лови вовсе, ты получишь вполне адекватное поведение со скидыванием корки (прикинь, это не хуже вашего unwrap()). А автор софтины прекрасно знает какие исключения у него летят, и обработает их где-нибудь на высоком уровне. До исключений нужно дорасти, это про сложный софт, а не хелло ворлды. И на всякий случай - я тут не про летящие из библиотек исключения.

Угу, чистый код - это когда нужно ознакомиться со всей программой, чтобы понять, каким может быть результат работы функции. Если ошибёшься - в лучшем случае аборт.

А чем тебе аборт не нравится? Ты получаешь корку с колл стеком

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

Что ты такое говоришь? Что за ерунда? У тебя корка на руках в случае чего, максимально подробные данные, ты не умеешь запускать отладчик с коркой? Чем корка после исключения хуже корки после растового unwrap()? И нет, исключения - это про сложный софт, это то, что делает код сильно чище и проще. Сцуко, вызывают unwrap() в каждой строке, и что-то ещё говорят про: «а если упадет». Да у вас упасть может на каждом шагу, никаких ошибок наверх вы не передаете, ваш код - падучее говно. При написании хелло ворлдов этого не осознать, но при усложнении задач самые сообразительные растофанатики начнут что-то понимать.

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

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

Абсолютно то же самое. Это ты влез откуда-то со своими исключениями.

Ты начал с середины читать? Ваш растофанатик заявил, что unwrap() - это такой продвинутый if (error) для ошибок, я же ему возразил, что ошибки вообще в if не должны обрабатываться, там только какие-то штатные кейсы, и за неимением исключений вы как в самых детских недоязычках аобортитесь() в любой непонятной ситуации

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

И да, это там, где в C обычно приходится обмазываться лапшой из if-ов и местами goto-хами из-за отсутствия RAII (что, к примеру, часто можно лицезреть в исходниках Linux).

Не все надо писать на чистом Си. Я не знаю почему иногда люди страдают на Си, когда надо взять С++.

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

Ты заявил, что есть «более адекватные» средства, даже для микроконтроллеров, и я тебя спросил, какие именно.

Тебе ответили: раст, микропитон. Смотрим в книгу - видим фигу?

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

Выберите 1 или 2.

Выберите: вилкой в глаз, или в попу раз? Слабо?

unwarp - средство …

unwrap - хелпер метод специальной структуры. В расте нет исключений.

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

поняли, что идея нежизнеспособная

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

в своем расте вы что-то не сильно таскаете критические ошибки через стек вызовов, просто зовете unwrap() и абортитесь

Для приложений это может быть вполне нормальным подходом. В библиотеках никто в своём уме unwrap не пишет.

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

Если ты в процессе тестирования вообще столкнёшься с выбросом исключения в этом code path. Выразить контракт в типе по-любому лучше.

исключения - это про сложный софт

Исключения - это «кто-нибудь там выше по кол-стеку обработает, мне некогда думать», а после написания программы уже никто не заморачивается правильной обработкой, и только и остаётся в огромной гуёвине в main() написать catch() с формой отправки стектрейса разработчику, чтобы его пнуть в сторону правильной обработки конкретно этого исключения.

unwrap() - это такой продвинутый if (error) для ошибок

Так и есть

ошибки вообще в if не должны обрабатываться

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

В целом, ваша аргументация строится на двух постулатах:

  1. В программах на расте типично обрабатывать все ошибки с помощью unwrap(), что не соответствует истине
  2. Нормально иметь неявный, подразумеваемый интерфейс у функций. Если сегодня вызывать метод a() в библиотеке нормально, а завтра внутри метода начали кидать новые исключения, якобы можно заранее сделать правильную обработку этих исключений.
unC0Rr ★★★★★
()
Ответ на: комментарий от zurg

Для микроконтролеров пишут код на том, что рекомендует производитель, для чего выпускает разного рода SDK и примеры. И в 99% случаев это C. Я по крайней мере ни разу не видел ничего другого, а работал я и с STM32 и с Nordic и с китайскими чипами. Везде C. SDK на C. Примеры на C. Поддержка от производителя для этого SDK и примеров.

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

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

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

Я вот сейчас для Nordic пишу. Есть какая-нибудь функция вроде включения SAADC периферии. Ну на первый взгляд ничего особого, записали единичку в нужный бит, оно и включилась, сделали функцию-обёртку для записи этой единички, чтобы читаемо было, все так делают. Такое и на Rust переписать недолго.

Но как-то ненароком проваливаешься в реализацию этой функции. И видишь там кучу ifdef-ов. Для такого-то чипа применять такой-то workaround для этой errata и пишут какой-то мусор по каким-то недокументированным адресам. А без этого мусора твой код на этом чипе работать корректно не будет. И такое сплошь и рядом.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от Somebody
Тебе ответили: раст, микропитон.

Но не ты.

Вот что я ответил:

для 32-битных много чего есть, типа микропитон, embassy, даже wasm рантайм есть

embassy это RTOS на расте, впрочем раст и без него можно использовать. Чего ещё я не ответил?

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

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

s/Rust/C

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

Для микроконтролеров пишут код на том, что рекомендует производитель, для чего выпускает разного рода SDK и примеры. И в 99% случаев это C.

Именно!

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

Всё, ты мне больше не интересен, уймись.

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

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

Проблема micropython:

Yet it is compact enough to fit and run within just 256k of code space and 16k of RAM

256 КБ это уже считаются «жирные» МК, самые ходовые МК обычно 32к – 64к памяти, по моему опыту, потому что дешевле и маленький форм-фактор. Да, использовали МК с 128к потому что надо было хранить много доп данных.

А 256к это как будто прям много – возможно проще и дешевле взять МК поменьше и к нему развести дополнительную микросхему памяти.

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

возможно проще и дешевле взять МК поменьше и к нему развести дополнительную микросхему памяти

Не всякие МК позволяют использовать доп. память... Далеко не...

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

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

Проблема micropython:

Yet it is compact enough to fit and run within just 256k of code space and 16k of RAM

256 КБ это уже считаются «жирные» МК

256k ROM нужно. Естественно, если их нет то микропитон не подойдёт, но всё равно есть раст, если речь идёт об альтернативах для си.

Большинство MCU вендоров предоставляют си SDK, это исторически, но микропитон SDK предоставляют как минимум espressive, STM и raspberry pi, а коммунити порты существуют для целой кучи МК. Для раста поддержка пока не такая широкая, но она быстро растёт. Espressive например предоставляет rust SDK, другие вендоры обещают, что скоро будет, плюс также есть довольно широкий коммунити саппорт. Так что утверждение, что альтернатива сям на МК есть, совсем не голословное.

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

У тебя какое-то неправильное представление об исключениях. Да, исключения протаскиваются через жирные слои апи, в этом и прелесть, что мне не надо заморачиваться и что-то там декларировать у функций в середине этого пирога. На нижнем уровне я сегодня кидаю лишь struct that_shit{}, а завтра начну ещё в добавок кидать this_shit{}, и ничего мне не надо править. У алгоритма есть несколько ожидаемых путей выполнения и потенциально бесконечное множество «что-то пошло не так, васянская либа, барахлит или ещё чего». Каждое новое непредсказуемое состояние - потенциально новый тип исключения, что-то там декларировать у функций - унылая дрочь. На верхнем уровне можешь написать catch(…), если для тебя важно отловить всё. Напиши там в лог тип исключения, грепни, разберись.

И не нужно оборачивать каждый вызов в try catch, это самое тупое что можно сделать. Юзкейс должен быть другим - например, у софтины есть гуйня с кнопочками, их 10, юзер клацает по одной из них, вызов обработчика этого событий мы оборачиваем в try, где-то там глубоко в колл стеке что-то пошло не так, летит исключение, сообщаем, попытка провалилась. Десять try блоков на всю софтину, чистый код без проверки и дрочева в if’ах с исключительными состояниями. Ты же в своем расте будешь вынужден всегда думать об исключительных состояниях и протаскивать их через колл стек и дрочиться с проверкой всего этого говна в if’ах, на выходе грязный и многословный код

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

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

и прелесть, что мне не надо заморачиваться и что-то там декларировать у функций в середине этого пирога

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

сегодня кидаю лишь struct that_shit{}, а завтра начну ещё в добавок кидать this_shit{}, и ничего мне не надо править

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

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

… втихую ломающее API, поломка не ловится компилятором и статическими анализаторами

декларировать у функций - унылая дрочь

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

На верхнем уровне можешь написать catch(…)

На верхнем уровне уже поздно, толку мало.

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

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

будешь вынужден всегда думать об исключительных состояниях

А где не буду вынужден? Там, где в логах нужно копаться?

проверкой всего этого говна в if’ах

Зависит от того, что ты хочешь сделать. Прокидывание выше пишется одним символом. Обработка по-разному, иногда достаточно unwrap_or_default()

у алгоритма штаные пути выполнения

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

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

Так если бы писали новое – вопросов бы не было. А так ведь переписывают то, что уже работает, под флагом того, что оно будет безопаснее от самого факта переписывания на Расте.

идиотов

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

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

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

Инициализация. В си: или «жри что дают» и без вариантов автоматическое зануление глобальных статиков, или раздолбайское (через УБ) «как повезёт» для всего остального. Т.е. самый нелепый расклад для системного-то языка. В расте норм: по дефолту - инициализируем всё иначе ошибка компиляции, а где надо особо делаем особо, специально предназначеным формализованным мощным инструментом https://doc.rust-lang.org/std/mem/union.MaybeUninit.html.

Указатели. В си: обвешанное самыми странными и дикими УБ и костылями нечто, давно никакое не «это просто такое число». И это не избежно, в языке просто больше нихрена нет для работы с косвенностью и поэтому они вот такие и этим приходиться обмазывать всю программу и интерфейсы. В расте: в большинстве случаев(как и должно быть) используются удобные, максимально эффективные и безопасные ссылки. Но и к сырым указателям тоже основательно подошли. Действия с памятью через них огорожены ансейфом и обложены типизацией, количество УБ сильно меньше и более очевидны. Плюс, с недавних пор, появилось апи для провенанса https://doc.rust-lang.org/std/ptr/index.html#provenance. Эта та штука, из-за которой указатель не только и не столько адрес(один и тот же указатель может иметь разные адреса и наоборот), и появилась из-за особенностей работы современного оптимизирующего компилятора. Что там накрутит с этим провенансом сишный(и плюсишный) компилятор можно только гадать и надеяться на лучшее.

Арифметика (c учётом железячных особенностей). В си худо-бедно завезли checked арифметику с диагностикой переполнения, правда это в самом распоследнем стандарте, не прошло и 50 лет, а до этого расброд шатания и УБ-шные приключения со знаковыми. Арифметику с насыщением, уже, скорее всего, не дождёмся. В рачте же полный контроль и сервис над арифметикой, и добавляют ещё.

Ну и вообще, системность это про строгую умную типизацию и управление ресурсами с тонким контролем владения и времёни жизни, что в расте из коробки и by design, этакая осовремененная ADA.

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

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

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

Я не знаю, зачем ты так заморачиваешься, честно, чего ты там хочешь увидеть, всего не предусмотреть и не надо парить себе мозг. Есть функция int get_sensor_value() либо она возвращет значение, либо по каким-то причинам не может (датчика нет, например, или данные некорректны), и не надо эти пути выполнения предусматривать, кидаешь исключение с описанием, а на верхнем уровне пишешь в лог: «замени датчик». Степень исключительности сам выбираешь.

Ладно, красоту исключений дано понять не всем, видимо. Для меня это абсолютно точно полезный инструмент, который делает код проще и чище.

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

возможно проще и дешевле взять МК поменьше и к нему развести дополнительную микросхему памяти

Тут меня увело в сторону и уже имел ввиду не памяти для кода, а памяти для данных и тут любой МК умеет тягать данные по I2C или SPI.

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

Так что утверждение, что альтернатива сям на МК есть, совсем не голословное.

Да я в общем то такого и не говорил, я сам в этом топике скинул stm32-rs и ссылку на zig embedded group.

Другое дело что эти решения еще мало опробованы массово и не факт, что являются production ready. Тут уже правильно заметили что важна поддержка официального SDK, потому что community SDK могут не учитывать errata и другие незадокументированные «приколы» МК.

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

zig embedded group

Там нигде еще и конь не валялся. Ниже четвертого тира. https://ziglang.org/download/0.15.1/release-notes.html#Support-Table

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

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

либо она возвращет значение, либо по каким-то причинам не может (датчика нет, например, или данные некорректны), и не надо эти пути выполнения предусматривать

Я работал какое-то время с исключениями. И заимел о них мнение. Ты неправ. Для прототипирования исключения ок. Для нормальной работы надо делать нормальные контракты и нормальное возвращение ошибок.

И что самое плохое в исключениях – они навязывают стиль кода. То, что я бы назвал «harness вокруг бизнес-логики». Очень мешает портировать код с одного языка на другой, да собственно и на одном языке между разными проектами с разными harness.

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