Про "похожее по смыслу" не соглашусь. Тут именно штурм Капитолия, в протестах участвовало сильно больше, и их никто не судил. В протестах против Трампа сотни тысяч участвовали, и тоже ничего.
В Белоруси же просто факт нахождения в протестном чате — уже повод.
Справедливости ради, в большинстве случаев заставляют выплатить "пожертвование", чтобы не привлекать к ответственности за то, что участвовал в протестах или состоял не в тех чатах. Или принуждают к сотрудничеству.
Если считать и такие случаи, то могут и десятки тысяч набраться. Но да, не сидят. Тоже так себе, но разница большая.
Мы с вами в двух параллельных вселенных живём. Я говорю о том, как сейчас писать программы так, чтобы ошибок было меньше. Разбиение на независимые части и строгие контракты API этих частей как раз уменьшают сложность системы в целом. И это только один из инструментов, есть и другие. Вы же о том, что авторы должны доказывать, что в их программах нет ошибок. Математически доказывать корректность программ, по крайней мере сейчас, очень долго и дорого и экономически не оправдано. И да, требует применения других языков программирования.
Отвечая про переполнение int'а — используйте Rust и safe-функции, переполнение вызовет panic, а не неопределённое поведение. При желании такие функции и в c++ можно реализовать. Да, будет runtime cost.
Также можно делать type safe обёртки с семантикой, например, "это float в границах [0; 1]". И тогда проверка нужна только при создании значений. А, скажем, при перемножении таких чисел уже можно не проверять.
Вы увели дискуссию в сторону от моей оригинальной мысли о том, что std::filesystem не надо использовать напрямую (и, если уж на то пошло, и chrono, и iostream/fstream). Я не пытался раскрыть тему как писать безопасные программы.
Буквально "WinRAR позволял добавлять в архивы пути с ..". Т.е. ровно то, о чём я говорю. И описанный выше способ работы с файлами от таких ошибок полностью спасает.
Не понимаю. Вот, скажем, в моей подсистеме есть ошибка, и специально созданный архив может модифицировать путь. Но я оперирую относительными путями, а мои интерфейсы каталогов не обрабатывают пути "..". И всё, несмотря на ошибку, создать файл где угодно уже не получится. Почему меня это не спасёт, и нужна криптография? И как криптография тут поможет?
Нельзя защититься от всего, но можно проектировать приложения так, чтобы вероятность ошибки была меньше.
Если ты открываешь свои ресурсы, делай это не через ФС, а специальными классами, соответствующими этим ресурсам.
Это утверждение противоречит статье, т.к. мы хотим делать обобщённый код как для вшитых в приложение, так и для реальных файлов. Ну и код работы с ФС мы точно хотим отделить от классов "текстура" и "меш".
Вы, возможно, меня неправильно поняли. Внутри реализации наших интерфейсов мы пользуемся абсолютными путями, но интерфейс каталога никогда не позволяет выходить за его пределы.
Я привёл пример с уязвимостью в WinRAR. Если бы наша подсистема распаковки не могла выходить за пределы каталога, куда мы распаковываем, то и уязвимости бы не было.
То же относится к кэшам, настройкам, ротации логов, которые всегда живут по определённым путям. Но это не только про создание и удаление файлов — даже если мы открываем каталог на чтение, мы ме должны позволять подсистемам читать данные за его пределами.
Также лучше отделить логику про разное местоположение рабочих каталогов на разных ФС от реальной логики работы, а для этого нам опять нужен интерфейс "каталог" и относительные пути. Плюс не надо думать, в каком виде представлять абсолютный путь в Windows.
Но даже первого достаточно, т.к. если мы можем открыть как реальное дерево с файловой системы, так и архив, то абсолютного пути у нас просто нет.
P.S. А ещё относительные пути производительнее, не надо обрабатывать .. и .
Про то, что std::filesystem можно использовать, я бы поспорил. В небольших утилитах — да, пожалуйста. Но вот в чём-то большем лучше скрыть за специальным интерфейсом-обёрткой. Во-первых, такой интерфейс позволит работать с разными реализациями. Хоть с реальной ФС, хоть со временной в памяти, хоть с zip-архивами. Во-вторых, он позволит проще писать unit-тесты, с нормальными mock'ами и без медленного похода на реальную ФС. В-третьих, этот интерфейс должен позволять компоненту обращаться к файлам и каталогам только по относительному пути, не позволяя выйти за ограничения, заданные вызывающим кодом, и увеличивая безопасность приложения в целом (тут можно вспомнить WinRAR и недавний CVE-2025-6218). Реализация для реальных ФС может быть сделана и поверх std::filesystem, но она не будет самой эффективной. Возможно, правильнее потратить пару недель и сделать несколько реализаций для нужных ОС.
Что по идее должно привлекать внимание к тому, сколько налогов вы платите, и способствовать более осознанному отношению к тратам государства и выборам.
Про "похожее по смыслу" не соглашусь. Тут именно штурм Капитолия, в протестах участвовало сильно больше, и их никто не судил. В протестах против Трампа сотни тысяч участвовали, и тоже ничего.
В Белоруси же просто факт нахождения в протестном чате — уже повод.
Справедливости ради, в большинстве случаев заставляют выплатить "пожертвование", чтобы не привлекать к ответственности за то, что участвовал в протестах или состоял не в тех чатах. Или принуждают к сотрудничеству.
Если считать и такие случаи, то могут и десятки тысяч набраться. Но да, не сидят. Тоже так себе, но разница большая.
А вы занизили, т.к. сажают до сих пор. Белорусы-коллеги говорят, что возвращаться и проходить границу — лотерея, и у каждого есть сидящий знакомый.
И мы усложняем код только для того, чтобы переменные были фиксированные. Убрали сложность в одном месте, но добавили в другом (и, ИМХО, больше).
Из какого города? В Хельсинки вполне себе чистят.
Весной убирают
А в чём отличие? Полностью идентичный код.
Я репортил баг в версии 0.3 в начале 2008 года. Удивлён, что сейчас только версия 0.7.
Мы с вами в двух параллельных вселенных живём. Я говорю о том, как сейчас писать программы так, чтобы ошибок было меньше. Разбиение на независимые части и строгие контракты API этих частей как раз уменьшают сложность системы в целом. И это только один из инструментов, есть и другие. Вы же о том, что авторы должны доказывать, что в их программах нет ошибок. Математически доказывать корректность программ, по крайней мере сейчас, очень долго и дорого и экономически не оправдано. И да, требует применения других языков программирования.
Отвечая про переполнение int'а — используйте Rust и safe-функции, переполнение вызовет panic, а не неопределённое поведение. При желании такие функции и в c++ можно реализовать. Да, будет runtime cost.
Также можно делать type safe обёртки с семантикой, например, "это float в границах [0; 1]". И тогда проверка нужна только при создании значений. А, скажем, при перемножении таких чисел уже можно не проверять.
Вы увели дискуссию в сторону от моей оригинальной мысли о том, что std::filesystem не надо использовать напрямую (и, если уж на то пошло, и chrono, и iostream/fstream). Я не пытался раскрыть тему как писать безопасные программы.
https://github.com/absholi7ly/CVE-2025-6218-WinRAR-Directory-Traversal-RCE?tab=readme-ov-file#2-root-cause-explanation
Буквально "WinRAR позволял добавлять в архивы пути с ..". Т.е. ровно то, о чём я говорю. И описанный выше способ работы с файлами от таких ошибок полностью спасает.
Не понимаю. Вот, скажем, в моей подсистеме есть ошибка, и специально созданный архив может модифицировать путь. Но я оперирую относительными путями, а мои интерфейсы каталогов не обрабатывают пути "..". И всё, несмотря на ошибку, создать файл где угодно уже не получится. Почему меня это не спасёт, и нужна криптография? И как криптография тут поможет?
Нельзя защититься от всего, но можно проектировать приложения так, чтобы вероятность ошибки была меньше.
Это утверждение противоречит статье, т.к. мы хотим делать обобщённый код как для вшитых в приложение, так и для реальных файлов. Ну и код работы с ФС мы точно хотим отделить от классов "текстура" и "меш".
Вы, возможно, меня неправильно поняли. Внутри реализации наших интерфейсов мы пользуемся абсолютными путями, но интерфейс каталога никогда не позволяет выходить за его пределы.
Я привёл пример с уязвимостью в WinRAR. Если бы наша подсистема распаковки не могла выходить за пределы каталога, куда мы распаковываем, то и уязвимости бы не было.
То же относится к кэшам, настройкам, ротации логов, которые всегда живут по определённым путям. Но это не только про создание и удаление файлов — даже если мы открываем каталог на чтение, мы ме должны позволять подсистемам читать данные за его пределами.
Также лучше отделить логику про разное местоположение рабочих каталогов на разных ФС от реальной логики работы, а для этого нам опять нужен интерфейс "каталог" и относительные пути. Плюс не надо думать, в каком виде представлять абсолютный путь в Windows.
Но даже первого достаточно, т.к. если мы можем открыть как реальное дерево с файловой системы, так и архив, то абсолютного пути у нас просто нет.
P.S. А ещё относительные пути производительнее, не надо обрабатывать .. и .
Нам может быть нужно больше всего — мапить в память, создавать и удалять файлы, смещать файловые указатели. Стримы очень ограниченные.
Про то, что std::filesystem можно использовать, я бы поспорил. В небольших утилитах — да, пожалуйста. Но вот в чём-то большем лучше скрыть за специальным интерфейсом-обёрткой.
Во-первых, такой интерфейс позволит работать с разными реализациями. Хоть с реальной ФС, хоть со временной в памяти, хоть с zip-архивами.
Во-вторых, он позволит проще писать unit-тесты, с нормальными mock'ами и без медленного похода на реальную ФС.
В-третьих, этот интерфейс должен позволять компоненту обращаться к файлам и каталогам только по относительному пути, не позволяя выйти за ограничения, заданные вызывающим кодом, и увеличивая безопасность приложения в целом (тут можно вспомнить WinRAR и недавний CVE-2025-6218).
Реализация для реальных ФС может быть сделана и поверх std::filesystem, но она не будет самой эффективной. Возможно, правильнее потратить пару недель и сделать несколько реализаций для нужных ОС.
В C++ это explicit конструкторы типов, которые потом не позволят одно к другому неявно привести.
Или, если не позволяет,
bank.transfer(SenderId(1), ReceiverId(2), Amount(1200), Fee(1.2));Я их бризером пользовался, он вполне норм. До него вечно была проблема, что окно откроешь, а кто-то снизу решил закурить.
>Вы не замечали, что после отпуска ваш СО2 сенсор показывает какие-то нехорошие большие значения и только со временем они становятся нормальными?
Не замечал.
Я лично замечаю даже тысячу, стабильно начинает болеть голова. Стараюсь всегда держать меньше 800.
В плане автоматизации не самое дешёвое, но простое решение — взять Тион с их MagicAir и настроить граничный уровень.
Что по идее должно привлекать внимание к тому, сколько налогов вы платите, и способствовать более осознанному отношению к тратам государства и выборам.