Здравствуйте, Аноним, Вы писали:
А>Есть ли у кого-нибудь кросплатформеный сабж?
Поясните, что Вы подразумеваете под безопасностью: корректно обрабатывать NULL на входе? Позволять накладывать ограничение на максимальную длину измеряемой строки? М.б. потокобезопасность? Или... ? Тут можно много ещё чего напридумать можно под слово "безопасность" — что именно нужно Вам?
Здравствуйте, e-garin, Вы писали:
EG>Здравствуйте, Аноним, Вы писали:
А>>Есть ли у кого-нибудь кросплатформеный сабж? EG>Поясните, что Вы подразумеваете под безопасностью: корректно обрабатывать NULL на входе? Позволять накладывать ограничение на максимальную длину измеряемой строки? М.б. потокобезопасность? Или... ? Тут можно много ещё чего напридумать можно под слово "безопасность" — что именно нужно Вам?
Позволять накладывать ограничение на максимальную длину измеряемой строки. Чтобы не вызвать переполнение буффера.
Хотелось бы что-нибудь типа strnlen.
В виндах эта функция уже есть, под моей платформой(ОС2000) — нет.
STL-ные и прочие другие реализации тоже не интересуют — нужна функция на чистом ANSI С.
Я нашел в сети такую реализацию strlen.
size_t
strlen(str)
const char *str;
{
const char *s;
for (s = str; (*s); ++s);
return(s — str);
}
Соответственно переработанная функция будет примерно такая.
for (s = str; (*s) && (i >= (size -1)); ++s, i++);
return(s — str);
}
То же самое с функцией sprintf. Функции snprintf тоже нет
Я попробовал реализовать её с учетом моей strlen,
чтобы хотя бы можно было отловить переполнение буффера.
Здравствуйте, Аноним, Вы писали:
А>Позволять накладывать ограничение на максимальную длину измеряемой строки. Чтобы не вызвать переполнение буффера.
Извините, конечно, но то, что вы хотите по меньшей мере странно.
strlen не может вызвать переполнение буфера по определению — т.к. в буфер не пишет.
Да, он может вызвать segfault, но от этого указанием максимальной длины строки не спастись.
__________
16.There is no cause so right that one cannot find a fool following it.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, e-garin, Вы писали:
EG>>Здравствуйте, Аноним, Вы писали:
А>>>Есть ли у кого-нибудь кросплатформеный сабж? EG>>Поясните, что Вы подразумеваете под безопасностью: корректно обрабатывать NULL на входе? Позволять накладывать ограничение на максимальную длину измеряемой строки? М.б. потокобезопасность? Или... ? Тут можно много ещё чего напридумать можно под слово "безопасность" — что именно нужно Вам?
А>Позволять накладывать ограничение на максимальную длину измеряемой строки. Чтобы не вызвать переполнение буффера. А>Хотелось бы что-нибудь типа strnlen. А>В виндах эта функция уже есть, под моей платформой(ОС2000) — нет. А>STL-ные и прочие другие реализации тоже не интересуют — нужна функция на чистом ANSI С.
memchr(str, '\0', n)
Re[4]: Безопасный аналог strlen
От:
Аноним
Дата:
21.01.08 16:59
Оценка:
Здравствуйте, sokel, Вы писали:
S>Здравствуйте, Аноним, Вы писали:
А>>int snprintf(char *buf, size_t size, const char *fmt, ...) А>>{ А>> size_t n; А>> va_list ap;
А>> va_start(ap, fmt); А>> (void)vsprintf(buf, fmt, ap); А>> va_end(ap); А>> n = strnlen(buf,size); А>> return(n);
А>>}
S>а как это может защитить от переполнения буфера?
Я считаю что функция strnlen должна будет вернуть -1, по этому значению можно будет отловить переполнение буффера.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, sokel, Вы писали:
S>>Здравствуйте, Аноним, Вы писали:
А>>>int snprintf(char *buf, size_t size, const char *fmt, ...) А>>>{ А>>> size_t n; А>>> va_list ap;
А>>> va_start(ap, fmt); А>>> (void)vsprintf(buf, fmt, ap); А>>> va_end(ap); А>>> n = strnlen(buf,size); А>>> return(n);
А>>>}
S>>а как это может защитить от переполнения буфера? А>Я считаю что функция strnlen должна будет вернуть -1, по этому значению можно будет отловить переполнение буффера.
но ты же через vsprintf уже понаписал в буфер чорт знает докуда
Здравствуйте, Аноним, Вы писали:
А>>В виндах эта функция уже есть, под моей платформой(ОС2000) — нет. А>>STL-ные и прочие другие реализации тоже не интересуют — нужна функция на чистом ANSI С. А>memchr(str, '\0', n)
+1. Только надо возвращаемое значение переделать, примерно так:
Здравствуйте, Аноним, Вы писали:
А>Хотелось бы что-нибудь типа strnlen. А>В виндах эта функция уже есть, под моей платформой(ОС2000) — нет.
М-да.
А>То же самое с функцией sprintf. Функции snprintf тоже нет:(
Проблема известная. Есть несколько вариантов решения. Например, парсить форматную строку самому, определяя максимальный размер каждой части (не слишком сложно). Или писать в файл:) а потом считать сколько записали (однако дорогой метод). Если используемое stdio достаточно умное и знает аналоги funopen() или fopencookie() — применить их (BSD'шный snprintf именно так и устроен, за исключением того, что вместо funopen() сам заполняет структуру FILE).
А> va_start(ap, fmt); А> (void)vsprintf(buf, fmt, ap); А> va_end(ap); А> n = strnlen(buf,size); А> return(n);
От переполнения буфера все эти хаки не спасут. Надо менять подложку. Я бы рекомендовал попинать разработчиков ОС2000 на тему переделки stdio с обучением его замыканиям (те же funopen() или fopencookie()).
А>Хотелось бы узнать ваше мнение об этом. Насколько оправдано использование таких функций.
Однозначно лучше использовать их, если они есть, чем опасные варианты вроде sprintf.