
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.96] |
![]() |
|
![]() |
|
|
// определения:
![]() ![]() char *strtok_s( char *strToken, const char *strDelimit, char **context ); wchar_t *wcstok_s( wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context ); // реализация здесь crt_strtok_s.c, либо где-то в библиотеке CRT "болтается" Вопрос: что будет, если 3-й аргумент будем устанавливать в NULL ? обе функции безопасный аналог strtok и wcstok, но с дополнительными костылями в виде 3-го, на мой взгляд не нужного аргумента. Во всяком случае, могли бы его запихнуть внутрь функции, а не делать дополнительный параметр. Мелочь, но всё равно раздражает ![]() |
Сообщ.
#2
,
|
|
|
Специально для тебя в MSDN есть табличка: http://msdn.microsoft.com/en-us/library/ftsafwz3%28v=vs.80%29.aspx
Третий параметр нужен для потокобезопасности в многопоточном приложении. |
Сообщ.
#3
,
|
|
|
А как же сильно начинают раздражать методы, которые не умеют в принципе работать многопоточно и приходится их засовывать в обертки, прикручивать мутексы и так далее.
![]() |
Сообщ.
#4
,
|
|
|
На самом деле это нужно даже не для потокобезопасности.
Обычная strtok использует статический указатель, поэтому не позволяет производить разбор двух и более строк в параллель (даже в одном потоке). |
Сообщ.
#5
,
|
|
|
В принципе да, но в одном потоке это по крайней мере вручную контролировать можно.
А с несколькими потоками проблемы серьёзные будут. |
Сообщ.
#6
,
|
|
|
Всё что написано выше в этой теме истинная правда.
Но в большинстве случаев всё таки не требуется производнить разбор 2-х и более строк, также как справедливо утвреждение, что не каждое создаваемое приложение будет многопоточным. Поэтому я лично в большинстве случаев использовал бы strtok и wcstok, вместо strtok_s и wcstok_s. Только вот при их использовании, компилятор начинает ругаться и выдавать предупреждения, а отключать их принудительно лень. Создаётся ощущение, что компилятор от Microsoft как бы намекает программисту, что он не знает что делает и творит. Что вызывает большие сомнения. Вообще это касается не только данного случая. Программисты от индусско-китайского Микрософта любят создавать по 10 аналогов одной и той же функции - на все случаи жизни, вместо того чтобы просто изначально писать 1 универсальную, работоспособную и при любых ситуациях. |
![]() |
Сообщ.
#7
,
|
|
Программисты от Микрософта в первую очередь пекуться о соответствии своих библиотек Стандарту, а так же об индусско-китайских кодерах, которые то и дело забывают о безопасности. Если тебя не надо предупреждать о потенциально опасных Стандартных функциях, прими мои поздравления, ибо подавляющее большинство грамотных программистов продолжают писать код типа
![]() ![]() int *pArray = malloc(numElements * sizeof(int)); |
Сообщ.
#8
,
|
|
|
Кстати, а какая тут может быть ошибка?
Кроме уже имеющегося отсутствия приведения типа? Хотя надо сказать, явное приведение может замаскировать куда более опасные ошибки. |
Сообщ.
#9
,
|
|
|
Цитата Qraizer @ и при этом уверены, что тут ошибки нет и быть не может Я может чего не понял... А где тут ошибка? За исключением того что malloc() void* возвращает, т.е. приведение типов не помешает (хотя для Си не обязательно). |
Сообщ.
#10
,
|
|
|
если бы два потока одновремен но вызывали функцию malloc, куча могла бы быть повреждена. Если я правильно понял =)
|
Сообщ.
#11
,
|
|
|
С чего бы это?
|
![]() |
Сообщ.
#12
,
|
|
Цитата amk @ В С это не ошибка, а в Плюсах граммотные программисты не будут использовать malloc().Кроме уже имеющегося отсутствия приведения типа? Ошибка в другом. Кстати, эту ошибку эксплуатировали эксплойты в Adobe Flash Player. |
Сообщ.
#13
,
|
|
|
хех.. идея ясна и если вы её повернули таким углом, то конечно сложно не согласиться.
Но. Лучше сделать изначально безопасную функцию, чем: А) 1 безопасную Б) 2-ю опасную В) 3-ю для однобайтовых символов Г) 4-ю для 2-х байтовых символов, это ещё кстати от Оси зависеть Д) 5-ю для так называемых широких символов, с поддеркжой Unicode Е) 6-ю как знать для OLE строк ![]() З) 8-ю как знать для чего ещё И) у меня уже просто заканчиваются буквы )) Цитата в новом Стандарте будут объявлены устравшими. объявлены может и будут, но это не значит, что они будут их нельзя будет использовать и дальше. Это всего лишь означает, что следующая версия Visual Studio будет вас об этом предупреждать. Кстати, на почве этой темы даже "холи-вар" может случиться. Если это произойдёт, думаю модераторы позаботятся о том, чтобы перенести её в соответствующий раздел. Если же по существу. То тема себя исчерпала, ответы даны. Спасибо всем участникам дискуссии! |
Сообщ.
#14
,
|
|
|
Цитата zzz7net @ С чего бы это? Я прочитал это у Рихтера в Создание эффективных WIN32-приложений с учётом специфики 64-разрядной версии Windows в 6 ой Главе. Но объяснения так и не нашел ![]() Добавлено Цитата: Цитата Многопоточная версия библиотеки С/С++, кроме того, "обёртывает" некоторые функции синхронизирующими примитивами. Ведь если бы два потока одновременно вызывали функцию malloc, куча могла бы быть повреждена. Поэтому в многопоточной версии библиотеки потоки не могут одновременно выделять память из кучи. Второй поток она заставляет ждать до тех пор, пока первый не выйдет из функции malloc, и лишь тогда второй поток получает доступ к malloc. (Подробнее о синхронизации потоков мы поговорим в главах 8, 9 и 10.) |
![]() |
Сообщ.
#15
,
|
|
zzz7net, с твоими доводами не согласны ни Комитет по стандартизации языка, тем более, что реально букв вдвое меньше, ни сопроводители унаследованного кода, ни пользователи специализированных платформ, типа той же OLE, которая языконезависима. Ну и три буквы ты сам себе выдумал. Поверь, в мире писатели под только одну платформу и зарабатывающие на этом составляют подавляющее меньшинство. К примеру, выходящие параллельно на нескольких платформах игры давно никого не удивляют. Как думаешь, сколько кода они специализируют под разные порты, а сколько универсального?
like-nix, конкретно с небезопасными к мультипоточному окружению функции RTL сама разбирается. И malloc()/free() тут не исключение. Сабжевые же wcstok() и strtok() небезопасны в пределах одного потока, и в этом большая разница. Как раз с многопоточносью они разберутся не хуже других функций. Можно сколько угодно раз сколько угодно большими буквами как только можно ярко произвольной жирности болдом писать в документации, что wcstok() и strtok() не могут работать одновременно с более чем одной строкой, обязательно время от времени кто-нибудь будет жутко материться, вылезая из отладчика. Потому что не все считают обязательным читать документацию. Потому что некоторые считают это даже ниже своего достоинства, ибо они по определению лучше всех всё знают, и не надо их учить, как правильно и почему. Потому что человеческий фактор, в конце концов. Типичный пример - рекурсивный обход дерева каталогов с поиском имён файлов по маске. М-м? Насторожило бы, если б не эта тема, и я в ней не привёл этот пример с рекурсией? Особенно учитывая Цитата zzz7net @ Привык к отсутствию проблем, забыл об ограничении, не полез в документацию, на автомате набыдлокодил. Вуаля.Но в большинстве случаев всё таки не требуется производнить разбор 2-х и более строк, ... Неспроста эти все _s(). Конкретно о том примере с потенциальным эксплойтом. Дело в переполнении. Простом целочисленном. Достаточно передать через сокет заголовок пакета с numElements немногим более 1Г, и на 32-битной машине умножение на 4 приводит в малому положительному объёму, который malloc() успешно найдёт. Затем передать через тот же сокет в том же пакете немногим более полученного малого объёма, и мы трём блок хипа следом за вернутым, а то и не один. Рвём соединение со своей стороны, пакет отвергается, блок освобождается, не дожидаясь размера в 1Г интов. Никто ничего не заметил, кроме юзера, у которого ютубный ролик просто не проигрался. Обидно, но не сильно. Вот если б он знал бы, что затёртый блок в хипе уже содержит код эксплойта, и плейером используется под некую структуру с указателем на функцию, который указывает уже далеко не на ту функцию, а на эксплоит, ему было бы обиднее куда сильнее. Ну да, ещё DEP есть. Вот только честно: у кого он стоит в положении OptOut? Да даже OptIn, если только браузер не IE. Комбинация факторов, мягко говоря, маловероятна, не спорю. Однако ютуб очень посещаемый ресурс. |
Сообщ.
#16
,
|
|
|
Похоже тема оказалась несколько шире заданных вначале рамок 2 конкретных функций.
Вы их развдинули. Хотите продолжить? оk, с удовольствием. Предположим вы компания производящая антивирусное ПО, как это делает Symantec и вы входите в вышеупомянутый совет по стандартизации языка. Тогда идеальным языком для вас, точнее то каким бы вы его хотели видеть для остальных пользователей, был бы обернутый в 3 простыни с пожаробезопасным составом и режимом read only язык самого высокого уровня. И чтоб ниже опускаться могли только вы, но никак не потребители вашего ПО. Ясен пень вы будете со многим не согласны. Если вы компания Мелкийсофт, которая даже своё внутреннее устройство документирует весьма скромно и с опаской, и у которой концепция OpenSource до сих пор как кость в горле, в отличии от Никсов, то да. Не трудно догадаться, как вы будете голосовать на Совете. Думаю ещё не забыта эта курьёзная история с поддержкой RAW Sockets, когда её в "форточках" 2000 реализовали полностью. Затем в икспях ограничили. Причём с каждым сервис паком всё больше и больше. А в Viste и 7-ке полностью заблокировали, навечно поставиви печать "Вселенская Ось Зла", фактически опустив их на один уровень c Win95 ft. Win98 По поводу мультиплатформенности. Сейчас получило бурное развитие концепция Виртуализации и это 2-я кость в горле, наряду с OpenSource у компании Мелкосовт. Так как даёт вам возможность, наряду с прочими прыгать с одной Оси на другую, и не быть так жёстко привязанным к одной из них. И в будущих версиях языка и сопутствующих библиотек вас будут стараться ограничить и в этом. Мелкософт кстати уже давно активно продвигает свой обёрнутый в классы язык C#sharp, так как видимо MFC не оправдал всех надежд в плане задуманного. И это всё таки всего лишь библиотека, а реализовать сами ограничения можно только на уровне самого языка. При данных условиях сомнительно, что компания будет поддерживать С++ в ущерб Сsharp. Цитата Если тебя не надо предупреждать о потенциально опасных Стандартных функциях, прими мои поздравления 80% всей библиотеки CRT небезопасна, загляни в реализацию функций, практически всё реализовано с помощью одних указателей и базовых типов. Больше половины CRT уже одели в безопасные обёртки с префиксом _s. (по теме: пример ещё одного костыля wcsncpy_s). Может быть уже проще тогда всю библотеку запретить по этой причине, и не ломать свой моск прикрываясь фальшивой заботой о кодерах? Давайте в придачу ещё и Assembler запретим, ведь он на 100% небезопасен и все без исключения сядем программировать за "решёткой" C# ! Мы ведь такие опасные, нам место только там. (๏̯͡๏) ̿̿ ̿̿ '\\з= ![]() Цитата Неспроста эти все _s(). К слову сказать, потом нас могут выпустить по амнистии. Но не раньше чем сделают безопасные аналоги инструкций: ![]() ![]() push_s dy; dx mov_s hInst, eax_s call_s безопасная_Функ. За пример эксплойта отдельное спасибо ) не часто встретишь такого откровенного человека. P.S. По поводу С++ и нового страндарта. Обычно о данном языке говорят: плюсов много, но и минусов не мало. Жаль, что минусов в последнее время становиться всё больше и больше. |
![]() |
Сообщ.
#17
,
|
|
Цитата zzz7net @ Ты прав. Эти функции тесно касаются безопасного программирования, и в этом контексте я не хотел заостряться только на них. Ибо тем вообще касающихся безопасного программирования мало. Кроме того, эти функции весьма необычны своей опасностью.Похоже тема оказалась несколько шире заданных вначале рамок 2 конкретных функций. Вы их развдинули. Хотите продолжить? оk, с удовольствием. К моему сожалению конструктивных ответов от тебя не было и нет. Дальше идёт оффтоп, надеюсь, последний в этой теме. Могу перетащить в холивары, там можно разговаривать, не особо заморачиваясь фактами. Но совсем без фактов всё равно не долго. По поводу компаний, производящих антивирусное ПО, у тебя там чушь написана. Их мало заботят возможности языков программирования. Если язык Тьюринг-полный, он подходит для создания зловредов. По поводу MS у тебя информация 15-летней давности. Компания MS уважает OpenSource, и у неё хватает открытых продуктов. Тот факт, что она не желает открывать сырцы на все свои продукты, не более чем ставит её на один уровень, например, с автокорпорациями, также озабочеными своими патентами. А уж качество её проприетарных продуктов дадут фору многим открытым. Это факт, достаточно сравнить количество выпускаемых ею заплаток для своих продуктов и объёмы баг-треков для типичных открытых и соотнести хоть с объёмами на диске, хоть с количеством строк в сырцах. (К слову. ИМХО. Я не люблю OpenSource, потому что он способствует выпускать некачественные продукты, ибо зарабатывает на поддержке. Проприетарные вещи поддерживаются бесплатно, а значит закрытый код выгодно выпускать качественным.) Касательно всего остального... но комментс. Боюсь, спорить с человеком, совершенно не знакомого с предметом спора, у меня желания не будет. Начни хотя бы с осмысления того, что использование "сырых" указателей не есть небезопасное программирование. Или с того, что MFC - это библиотека, а .NET - платформа. У тебя какой-то слишком узкий взляд на технологии проектирования. |
Сообщ.
#18
,
|
|
|
Мин такой сценарий в голову как-то не пришел, просто потому, что я уже привык проверять все входящие извне данные. Если сказанл, что размер записи должен быть, скажем, не более 1К слов, значит если придет 1К+1, это ошибка во входных данных.
|
![]() |
Сообщ.
#19
,
|
|
amk, я к тому, что уязвимости могут запросто выплыть откуда не ждали. Человеческий фактор - он такой, что 322 раза напишешь правильно, а в 323-й глаз возьми да и замылься, и разумеется именно этот билд окажется в релизе.
Так что наличие _sекьюрных функции недооценивать не стоит, у компилятора с глазами всё в порядке. |