Pull to refresh

Comments 17

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

Пипец какой-то.

Тут не про строки, тут про то, как сознательно убиться головой об стену.

100% защиты от дурака не существует - найдет лазейку и любую обойдет.

Использовать Rust /sarkasm off/

Я не понял, как третий пример (с `std::string`) решает проблему ловушки 1.

Если вы про пример со strncopy, то третьим параметром там передаётся размер целевого буфера, а не строки. Зачем там substring магической длины правда непонятно.

Видимо, чтобы потом получить null-terminated c-строку с 10 значимыми символами после метода c_str(). И все равно не скопировать нуль в конце!

Привет Хабр! Меня зовут Владислав Столяров. Я аналитик безопасности продуктов в компании МойОфис.

Оффтопик, но зачем это нужно в статье? Как же бесят эти шаблонные куски у определенного подмножества авторов

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

QString вполне себе развивается. Входит в состав Qt Framework.

Юзайте std::string и не юзайте си наследие в виде printf, strcpy и т.д

И да прибудут с вами, новые стандарты С++.

У меня есть своя специфическая ошибка: в одной программе значение поля из результата запроса SQL преобразовывалось в std::string без проверки на нулевой указатель. Мы знали: если программа на старте падает, значит таблица сломалась, и из неё читаются значения NULL.

Что за ловушки? Кого они ловят?

4 примера говнокода, которые были актуальны 20 лет назад? Ну ок.

Для начала, в 2024 году надо прекратить писать статьи про C++, приводя внутри чисто сишный код. Потом можно задуматься о том, что строки в плюсах бывают разными. А ещё можно не высасывать примеры из одного места. Функция поиска не может возвращать бул, она может возвращать индекс, итератор, но не бул. Как функция поиска может возвращать что-то другое? Логика вышла из чата.

В случае неудачи, функции возвращают статическую константу npos.

Когда хотел написать что-то умное, а получилось... Функция возвращает индекс, а если вхождение не найдено, то возвращает -1, он же npos в виде unsigned. Интуитивно понятно, и не надо пытаться высасывать примеры.

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

В исправленном коде ... Также мы увеличили размер буфера на 1 и установили
нуль-терминатор в конце буфера, чтобы гарантировать корректное
завершение строки.

В третьем примере буфер не увеличили на 1, как был buffer[10], так и остался. И нулевого символа в конце все равно не будет.

А если говорить вообще, то смешивать С и С++ код - плохая практика.

Еще можно добавить, что strlen(NULL), вызывает SEGFAULT, хотя этого в мане не описано

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

Что должно подаваться на вход strlen()? Указатель на строку. Это в мане написано. Что такое строка в С? Массив символов (возможно, пустой), терминированный нулевым символом. Каким образом NULL является указателем на строку? Никаким. Annex J стандарта информирует, что поведение компилятора в таких случаях не определено. А ты ничем не отличаешься от тех суровых сибирских мужиков из анекдота, которые продемонстрировали, что японская лесопилка — отстой, засунув в неё стальной лом.

Мне лет 20 назад один программист из Индии продемонстрировал ещё одну похожую уязвимость: char* a = strdup(NULL);

Он так пустую строку создавал :-) Это я к тому, что главный способ обезопасить код - это не допускать к его написанию неграмотных программеров и писать unit test'ы. Что до серьёзных уязвимостей в том же С - есть специальные многостраничные документы, выпущенные на этот счёт серьёзными людьми. Всё приведённое в статье, отлавливается PVSC, например. Ну и всегда указывать в опциях компилятора wall...

Нулевой символ в С строке точно называется EOL?))

В современном C++ советуют использовать везде где можно string_view вместо const char*. Но и с ним возможен прострел ноги.

void Foo(std::string_view s)
{
  std::printf("s is %s", s.data());
}

Sign up to leave a comment.