Безопасный аналог strlen
От: Аноним  
Дата: 15.01.08 08:12
Оценка: :)
Есть ли у кого-нибудь кросплатформеный сабж?
Re: Безопасный аналог strlen
От: i-maverick Россия  
Дата: 15.01.08 08:17
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть ли у кого-нибудь кросплатформеный сабж?


strnlen
Re: Безопасный аналог strlen
От: e-garin Россия  
Дата: 15.01.08 08:32
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Есть ли у кого-нибудь кросплатформеный сабж?

Поясните, что Вы подразумеваете под безопасностью: корректно обрабатывать NULL на входе? Позволять накладывать ограничение на максимальную длину измеряемой строки? М.б. потокобезопасность? Или... ? Тут можно много ещё чего напридумать можно под слово "безопасность" — что именно нужно Вам?
А мне нравится жить :).
Re: Безопасный аналог strlen
От: Ужас бухгалтера  
Дата: 15.01.08 11:29
Оценка:
std::string::size
Re[2]: Безопасный аналог strlen
От: Аноним  
Дата: 16.01.08 08:18
Оценка:
Здравствуйте, 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);
}

Соответственно переработанная функция будет примерно такая.

size_t
strnlen(str, size)
const char *str;
const size_t size;
{
const char *s;
size_t i = 0;

for (s = str; *s; ++s);
{
if(i >= (size -1))
{
return — 1;
}
i++;
}
return(s — str);
}

Или такая:

size_t
strnlen(str, size)
const char *str;
const size_t size;
{
const char *s;
size_t i = 0;

for (s = str; (*s) && (i >= (size -1)); ++s, i++);
return(s — str);
}

То же самое с функцией sprintf. Функции snprintf тоже нет
Я попробовал реализовать её с учетом моей strlen,
чтобы хотя бы можно было отловить переполнение буффера.

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);

}

Хотелось бы узнать ваше мнение об этом. Насколько оправдано использование таких функций.
Re[3]: Безопасный аналог strlen
От: 0xDEADBEEF Ниоткуда  
Дата: 16.01.08 08:29
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>Позволять накладывать ограничение на максимальную длину измеряемой строки. Чтобы не вызвать переполнение буффера.

Извините, конечно, но то, что вы хотите по меньшей мере странно.
strlen не может вызвать переполнение буфера по определению — т.к. в буфер не пишет.
Да, он может вызвать segfault, но от этого указанием максимальной длины строки не спастись.
__________
16.There is no cause so right that one cannot find a fool following it.
Re[3]: Безопасный аналог strlen
От: sokel Россия  
Дата: 16.01.08 08:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>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);

А>}


а как это может защитить от переполнения буфера?
Re[3]: Безопасный аналог strlen
От: Аноним  
Дата: 16.01.08 12:10
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, 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, по этому значению можно будет отловить переполнение буффера.
Re[5]: Безопасный аналог strlen
От: sokel Россия  
Дата: 23.01.08 08:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, 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 уже понаписал в буфер чорт знает докуда
Re[4]: Безопасный аналог strlen
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 27.01.08 16:44
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>В виндах эта функция уже есть, под моей платформой(ОС2000) — нет.

А>>STL-ные и прочие другие реализации тоже не интересуют — нужна функция на чистом ANSI С.
А>memchr(str, '\0', n)

+1. Только надо возвращаемое значение переделать, примерно так:

size_t strnlen(const char* buf, size_t bufsize)
{
  const char* p = memchr(buf, '\0', bufsize);
  return (p == NULL) ? bufsize : (p - buf);
}
The God is real, unless declared integer.
Re[3]: Безопасный аналог strlen
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 27.01.08 16:53
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Хотелось бы что-нибудь типа 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.
The God is real, unless declared integer.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.