LINUX.ORG.RU

Конкатенация во что? А то:

char s[3] = {0};
s[0] = c1;
s[1] = c2;

theos ★★★
()

char a = 'A';
char b = 'B';
char buf[3] = { a, b, 0 };

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

>Не канает - ты учитываешь портабельность между low & big endian?

и того, что в високосных байтах девять бит, он тоже не учитывает

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

>и того, что в високосных байтах девять бит

o_O
low & big endian оба встречаются часто. Про високосные байты не слышал %)

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

>(c1<<8)|c2
>Не канает - ты учитываешь портабельность между low & big endian?


"слышал звон" ? в данном случае никакой разницы нет - le или be - полюбому фигня нарисована :)

imhotep
()

Читаем маны про strcat и strncat.

Прочёл? Теперь забудь навсегда. Лучше взять strlcat из *BSD. Аналогично и про strcpy/strncpy.

kemm
()
Ответ на: комментарий от kemm

>Лучше взять strlcat из *BSD.

С одной поправкой - если программируешь под *BSD ибо к счастью они были благополучно посланы найух сообществом потому что порождают на порядок больше трудно обнаружимых ошибок.

imhotep
()
Ответ на: комментарий от imhotep

> если программируешь под *BSD

Если программируешь по-человечески, а не windows^Wlinux-only

> были благополучно посланы найух сообществом

Сообществом красноглазых линуксоидов? Ой, вейли-вейли-вейли, беда-беда-беда... 8))) Ну хотят радостно жрать кактус -- флаг в руки.

> потому что порождают на порядок больше трудно обнаружимых ошибок

Угу, например? Не дают сделать переполнение буфера? Ужас какой, а? Или дают возможность спокойно проверить, а не обрезан ли результат? Вообще кошмар, да?

strn?(cat|cpy) -- defective by design. Только идиот может сделать их ещё более defective, как было с успехом проделано в glibc.

kemm
()
Ответ на: комментарий от kemm

>дают возможность спокойно проверить, а не обрезан ли результат

А кто тебя лишил возможности спокойно проверить достаточно ли длины буфера для результата перед вызовом стандартных ф-ий ?

imhotep
()
Ответ на: комментарий от imhotep

> А кто тебя лишил возможности спокойно проверить достаточно ли длины буфера для результата перед вызовом стандартных ф-ий ?

Как? strlen 1-2 раза вызвать? Офигеть прямое и красивое решение, два раза по одной строке бегать... И это оправдание генетической кривизны strcat/strncat вообще, и дважды кривизны реализации в glibc? С ума сойти...

И я всё-таки жду примеров "на порядок больше трудно обнаружимых ошибок".

kemm
()
Ответ на: комментарий от kemm

>Как? strlen 1-2 раза вызвать? Офигеть прямое и красивое решение

Ты бы хоть на исходники своего активно пропагандируемого "прямого" решения глянул прежде чем газифицировать

/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;

ничем тебе это strlen не напоминает ?

>И я всё-таки жду примеров "на порядок больше трудно обнаружимых ошибок"


когда ты забудешь сделать проверку на усечение результата твой код благополучно проглотит потенциальный баг - что он породит дальше зависит от ситуации, в лучшем случае твоя программа выведет hello wo на экране :) в более крупных проектах баг может быть не таким очевидным.

imhotep
()
Ответ на: комментарий от kemm

> Как? strlen 1-2 раза вызвать? Офигеть прямое и красивое решение, два раза по одной строке бегать.

коряво это выполнить strlcat, а потом узнать, что оказывается для результата нет места и мы получили ненужный огрызок, при этом потратив время, а результат от strlen прекрасно можно использовать для более быстрого объединения строк:

size_t len1 = strlen( buf1 );
size_t len2 = strlen( buf2 );
if( len1 + len2 < sizeof( buf1 ) - 1 )
    memcpy( buf1 + len1, buf2, len2 + 1 );
else
    ...

Unknown
()
Ответ на: комментарий от imhotep

> Ты бы хоть на исходники своего активно пропагандируемого "прямого" решения глянул прежде чем газифицировать

Вылезь из анабиоза, посмотри в код твоей любимой кривизны, и лезь в биореактор. Потому что там примерно то же самое. Потому что реализовать strcat, не вычисляя длину dst, невозможно. А я говорил про strlen(src).

> когда ты забудешь сделать проверку на усечение результата твой код благополучно проглотит потенциальный баг

Твой код с strcat породит SIGSEGV в лучшем случае, с strncat -- породит тот же SIGSEGV в том же лучшем случае (если, как и для всего остального, не столь альтернативно-одарённо спроектированного, ты напишешь strncat(dst, src, sizeof(dst)), тривиально забыв, что альтернативно-одарённым функциям размер надо передавать как sizeof() - 1), плюс точно такое же обрезание результата, как и в strlcat, плюс совершенно неведомую фигню там, где не гарантируется завершение dst нулём в случае переполнения (это про strncpy).

Думай дальше, я подожду.

kemm
()
Ответ на: комментарий от Unknown

> мы получили ненужный огрызок, при этом потратив время

Это если огрызок не нужен. Как вариант -- можно взять strl(cat|cpy) из солярки, там поведение как раз нужное тебе.

> а результат от strlen прекрасно можно использовать для более быстрого объединения строк

А будет ли оно заметно быстрее, бенчмарки есть?

Один хрен, использовать strn?(cat|cpy) -- диверсия. Дальше каждый выкручивается как хочет, strl-функции -- просто одно из готовых рабочих проверенных решений.

kemm
()
Ответ на: комментарий от kemm

Ты тупишь как и бсдшники которые были посланы найух.

>> strlcpy for gnu libc.


>This is horribly inefficient BSD crap. Using these function only

leads to other errors. Correct string handling means that you always
know how long your strings are and therefore you can you memcpy
(instead of strcpy).

imhotep
()
Ответ на: комментарий от imhotep

Половина уязвимостей как раз связаны с переполнением строк(буферов итп). Поэтому и сделали strlcpy. Она не для тех кто умеет программировать а для тех кто не умеет или же кому такое поведение как раз и нужно.

Кстати, покрывать оппонентов матюгами и называть всё что не linux crap-ом как раз в духе воинствующих линуксойдов :)

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

Так ты пример ошибок, к которым приводят strl-функции, но не приводят strn, покажешь, или будешь бредить общими словами вслед за красноглазиками?

kemm
()
Ответ на: комментарий от kemm

Урлих, как всегда, жжот ) http://sources.redhat.com/ml/libc-alpha/2000-08/msg00053.html

Вот это более предметно: http://sources.redhat.com/ml/libc-alpha/2000-08/msg00061.html

А вообще нафиг оно надо, если оно не посикс и не кроссплатформенное?

Пусть разработчики BSD-only софта развлекаются.

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

>забудешь сделать проверку на усечение
strl(cat|cpy) применяют там, где такая проверка не нужна по определению! (т.е. усечение допускается, потому что имеем дело как раз с выводом "hello world" на экран)
там, где такая проверка была бы необходима, использовать эти функции глупо, прибегают к вычислению необходимого размера буфера заранее и выделяют его динамически.
учись программировать с умом!

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

>Так ты пример ошибок, к которым приводят strl-функции, но не приводят strn, покажешь

http://www.cppreference.com/wiki/c/string/strlcpy

>общими словами вслед за красноглазиками


Ulrich Drepper is a software developer who works for Red Hat. Drepper is the lead contributor to and maintainer of the GNU C Library (glibc). He was also one of the leaders of 86open.

http://sources.redhat.com/ml/libc-alpha/2000-08/msg00053.html

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

imhotep
()
Ответ на: комментарий от true_admin

>Половина уязвимостей как раз связаны с переполнением строк(буферов итп). Поэтому и сделали strlcpy. Она не для тех кто умеет программировать а для тех ... кому такое поведение как раз и нужно.
+1.

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

> strl(cat|cpy) применяют там, где такая проверка не нужна по определению!
> учись программировать с умом!


вы невнимательны, kemm написал, что str(n)cat дефективен и надо использовать Ъ strlсat без всяких оговорок, думаю imhotep не согласен именно с такой точкой зрения

Unknown
()
Ответ на: комментарий от Davidov

> Вот это более предметно: http://sources.redhat.com/ml/libc-alpha/2000-08/msg00061.html

Как обычно. Это ненужно и вредно, потому что я не понимаю, кому это нужно. Причём в качестве альтернативы предлагает использовать нестандартную функцию (mempcpy), маладэц. Причём с тем же косяком, что и strncat -- забить нулём байт, следующий за переданным размером буфера.

Гуру тоже могут ошибаться, ага.

> А вообще нафиг оно надо, если оно не посикс и не кроссплатформенное?

Оно реализовано на чистом С без какой-либо BSD-специфики. Никто не мешает взять реализацию и таскать за собой. Это раз. Если по каким-либо религиозным причинам включать код под BSD лицензией не хочется -- реализация, аналогичная BSD'ишной или соляркиной (в зависимости от требований) пишется за полторы минуты даже без заглядывания в оригинальный код. А идея здравая.

kemm
()
Ответ на: комментарий от Unknown

> вы невнимательны, kemm написал, что str(n)cat дефективен и надо использовать Ъ strlсat без всяких оговорок, думаю imhotep не согласен именно с такой точкой зрения

В случаях, когда используется str(n)cat, надо вместо него использовать strlcat безо всяких оговорок. Это не очевидно? Я не говорил, что всегда надо использовать strlcat. Есть случаи, когда лучше делать так, как было предложено Unknown. str(n)cat -- дефективен _всегда_.

kemm
()
Ответ на: комментарий от kemm

> Причём с тем же косяком, что и strncat

нет тут никакого косяка

> Оно реализовано на чистом С без какой-либо BSD-специфики. Никто не мешает взять реализацию и таскать за собой


оно не нужно, т.к. годится разве-что для корявого вывода на экран, потому-что использование обрезанной строки вместо корректного результата - баг в программе

Unknown
()
Ответ на: комментарий от kemm

>Как обычно. Это ненужно и вредно, потому что я не понимаю, кому это нужно

Вредно не знать длины своих строк, а strlncat это поощряет.

>пишется за полторы минуты

А вот это уже велосипедостроение. Уж если хочется безопасности, лучше g-strconcat или вообще GString; а так полумеры какие-то.

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

>В случаях, когда используется str(n)cat

В этих случаях программист всегда обязан знать длины строк. Если он не знает, он криворукий, и пусть пишет на жаве, strlcat его не спасёт.

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

> нет тут никакого косяка

Да-да-да, это очень естественно, в одни стандартные функции передавать 'sizeof(buffer)', в другие -- 'sizeof(buffer) - 1'... Похапе-way во всей красе, ога.

> оно не нужно, т.к. годится разве-что для корявого вывода на экран, потому-что использование обрезанной строки вместо корректного результата - баг в программе

Ещё один апологет идеи "если мне непонятно, для чего что-то нужно -- значит это что-то не нужно никому". Ещё раз -- простая замена str(n)cat на strlcat даже без проверки возвращаемого значения -- минус дофига потенциально ошибочных мест. Проверка возвращаемого значения из strlcat -- минус все ошибочные места данного типа. Замена strlcat на вычисление размера + memcpy + обнуление последнего байта -- уже оптимизация (?), которая нужна далеко не всегда.

kemm
()
Ответ на: комментарий от Davidov

> Вредно не знать длины своих строк, а strlncat это поощряет.

А с чего это строки мои?

> Уж если хочется безопасности, лучше g-strconcat

Линковаться с glib не всегда удобно. Ну и у g_strconcat совсем другая семантика, если кто не заметил. А то так лучше вообще APR взять с его пулами. 8))

А вот есть ещё g_strl(cat|cpy) -- ни на какие мысли не наводит? 8))))

kemm
()
Ответ на: комментарий от kemm

> Да-да-да, это очень естественно, в одни стандартные функции передавать 'sizeof(buffer)', в другие -- 'sizeof(buffer) - 1'... Похапе-way во всей красе, ога.

наоборот - пишешь на С, значит должен понимать, что происходит

> Ещё раз -- простая замена str(n)cat на strlcat даже без проверки возвращаемого значения -- минус дофига потенциально ошибочных мест.


как уже писали - если человек не проверяет размеры строк, то это его проблемы, и при "strlcat даже без проверки" - да креша не будет, будут более веселые и трудно отлавливаемые баги - "случайное" удаление не тех данных, мусор в данных, порча содержимого файлов и т.д.

Unknown
()
Ответ на: комментарий от Unknown

> наоборот - пишешь на С, значит должен понимать, что происходит

Что "наоборот"? Либо везде передаём sizeof(buffer), либо везде передаём sizeof(buffer) - 1. Любой другой вариант (тут передаём одно, там -- другое) дефективен по определению. Это похапе-way.

> как уже писали - если человек не проверяет размеры строк, то это его проблемы

Ещё раз -- есть случаи (и их довольно много), когда обрезание строки не фатально. И когда в таких случаях вместо обрезания строки происходит работа str(n)cat/str(n)cpy -- вылезают дыры в безопасности. Причём это не высосано из пальца, а ровно такая дырка где-то была года два назад -- в формировании строки для лога. Если ты этого не понимаешь -- это твои проблемы, str(n)-семейство менее дефективным от этого не становится.

kemm
()
Ответ на: комментарий от Unknown

> через strlen, если strlcat не гнушается сначала взять длину строки - почему нас это должно смущать

Ещё один не способен читать код на языке C. Там вычисляется длина только dst до копирования. Смотри на функцию внимательнее.

kemm
()
Ответ на: комментарий от kemm

>Через libastral?

Ну если строки появились из libastral, то да, но, как правило, строки из ниоткуда не берутся; и про них многое известно. Если имеет место переполнение, то не тупо забивай буфер мусором, а будь добр, прореагируй как-нибудь; до того, как начать бездумное копирование.

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

> Ну если строки появились из libastral, то да

Строки могут появляться из генератора псевдослучайных последовательностей aka "пользователь". Ему, например, можно предложить выбор -- ввести строку заново или использовать обрезанный вариант (предварительно его показав, ага). Со strlcat/strlcpy это сделать проще. 8))

kemm
()
Ответ на: комментарий от kemm

> Что "наоборот"? Либо везде передаём sizeof(buffer), либо везде передаём sizeof(buffer) - 1. Любой другой вариант (тут передаём одно, там -- другое) дефективен по определению. Это похапе-way.

лучшего варианта нет

> Ещё раз -- есть случаи (и их довольно много), когда обрезание строки не фатально.


вы не хотите читать, такие "случаи" - это вывод текста для чтения человеком, я же писал про работу с данными, или вы всегда ограничиваетесь "hello, world"?

Unknown
()
Ответ на: комментарий от Unknown

> лучшего варианта нет

Лучший вариант -- это всегда передавать sizeof(buffer). Такое откровение в голову не приходило?

> я же писал про работу с данными

Мне наплевать, про что вы писали. Я писал про то, что str(n)cat использовать может только камикадзе. В тех случаях, когда применимо использование этих функций, ВСЕГДА лучше вместо них использовать strlcat. Учитесь читать то, на что вы отвечаете.

kemm
()
Ответ на: комментарий от kemm

> Ещё один не способен читать код на языке C. Там вычисляется длина только dst до копирования. Смотри на функцию внимательнее.

Ещё один не способен читать. Где я написал, что в том коде два раза вычисляется конец строки? да - один раз, зато потом идет побайтовое копирование, которое не эффективно - всегда быстрее копировать блок памяти

Unknown
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.