LINUX.ORG.RU

Кто-нибудь из форумчан на практике сталкивался с ошибкой при работе sprintf()?

 


0

1

Вопрос в заголовке. Если да, то распишите подробности. В манах пишут про отрицательное значение при ошибке, но списка errno нет.

Вопрос снят. Судя по ответам в теме и поиску в сети, есть смысл избегать следующих функций в критически важном коде: printf(), fprintf(), dprintf(), sprintf(), snprintf(), vprintf(), vfprintf(), vdprintf(), vsprintf(), vsnprintf(). Эти функции имеют общую man-страницу printf(3) и в ней указано, что эти функции могут завершаться с ошибкой, но при этом не приводится списка возможных ошибок, поэтому невозможно предусмотреть ошибки заранее.

★★

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

Когда при выполнении происходит ошибка.

Да ты прям генерал ясен х*р.

Что на счёт конкретики? У остальных функций есть список errno, который содержит все возможные ошибки.

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

Ну то есть по делу сказать нечего. Ок.

Вы не задали конкретного вопроса.

И, чтобы вы не утруждались:

ты не задал конкретного вопроса

К окулисту загляни на досуге ;)

Не стоит так отвечать, если вы просите о помощи.

raspopov
()

sprintf нормальные люди вообще не используют, потому что это прямой путь к buffer overflow. Нормальные люди используют snprintf, а у него есть как минимум ошибка недостаточного размера буфера как раз.

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

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

Он не возвращает ошибку если буфер маленький, просто тихо обрезает, а потом злоумышленник может это использовать.

#include <stdio.h>

int main() {
    char path[5];
    if (snprintf(path, sizeof(path), "/usr/share/useless-program") < 0)
        return -1;
    printf("rm -rf %s\n", path);
    return 0;
}

Так что нормальные люди не используют strlcat, snprintf. Нормальные люди используют sprintf_s под управлением Microsoft (TM) (C) (Protected) (Patented) .NET CLI/C.

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

Он не возвращает ошибку если буфер маленький, просто тихо обрезает

Он не «тихо обрезает», а возвращает количество байт, которое требуется для результата. Для этого и предназначен. Чтобы сделать malloc() или realloc() под результат и вызвать snprintf повторно.

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

Нормальные люди используют

g_strdup_printf(), при использовании glib2 в проекте.

Или если glib2 не используется, её аналог пишется за 5 минут при помощи того же snprintf.

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

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

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

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

Вот тут ты сильно ошибаешься.

n The number of characters written so far is stored into the integer pointed to by the corresponding argument. That argument shall be an int *

Этой штукой вполне можно перетереть, например, указатель на возврат в стеке.

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

Он не «тихо обрезает», а возвращает количество байт, которое требуется для результата.

Однако стоило ограничить это только на NULL, 0

Чтобы сделать malloc() или realloc() под результат и вызвать snprintf повторно.

А в это время произошла смена локали, поэтому результат не влез!

Нормальные люди используют

g_strdup_printf(), при использовании glib2 в проекте.

Зачем тащить glib? Есть asprintf.

Или если glib2 не используется, её аналог пишется за 5 минут при помощи того же snprintf.

asprintf!

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

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

Конечно приведет. Почти любая неправильная передача va_arg к этому приведет.

MOPKOBKA ★★★★★
()

всё что общается с человеком это глюкодром, даже glibc в кернел паник ядро раняет при работай с локалью на не валидном utf8, сейчас вроде нет, но новость проскакивала что ошибка в php который функцию glib вызывал и он систему ронял. Мне musl в этом плане очень даже ничего в локаль не ползёт, но говорят что медленее (мои тесты показали что нет), и дома на alpine с musl пол года просидел, заколебало весь софт практически пересобирать исходники править.

s-warus ★★★★
()
Ответ на: комментарий от vromanov

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

Нет. При указании «%n» в форматной строке данные будут записаны по указателю в соответствующем аргументе.

Это одна из причин, почему никогда нельзя куски форматной строки брать из пользовательского ввода, тащемта. Можно словить remote code execution.

Ну и плюс тут есть ещё такой нюанс что va_arg. Про это морковка тебе объяснит, мне лень печатать, я и так в двух тредах параллельно тут.

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