Greetings.
Занятную проблему нашел я себе на задницу. Такую:
Пишу интерфейс на VC++ 7.0 для базы данных, находящейся под MySQL 4.0.15a. С базой контактирую используя ODBC. В одну из таблиц надо грузить картинки (*.jpg, *.gif). Вскочил вопрос — cock? Шить к проге библиотеку libmySQL.dll ради одной единственной функции mysql_escape_string() не хочется. Да и пришьется ли она? Полез на
www.mysql.com, скачал исходник Мускула и нашел в нем реализацию упомянутой функции. Служит она, как Вы наверное знаете, для экранирования в буфере опасных символов, перед отправкой его содержимого в BLOB-поле таблицы. Вот она:
ulong STDCALL mysql_escape_string(char* to, const char* from, ulong length)
{
return mysql_sub_escape_string(default_charset_info, to, from, length);
}
static ulong mysql_sub_escape_string(CHARSET_INFO* charset_info, char* to,
const char* from, ulong length)
{
const char* to_start = to;
const char* end;
#ifdef USE_MB
my_bool use_mb_flag = use_mb(charset_info); /* TRUE если в текущем наборе символов есть многобайтовые. */
#endif
/* До тех пор, пока не будет достигнут байт, следующий за последним байтом буфера. */
for (end = from + length; from != end; from++)
{
#ifdef USE_MB
int l;
/* Если байт, на который указывает from, есть часть многобайтового символа,
вернуть в переменную l общее число байт этого символа. */
if (use_mb_flag && (l = my_ismbchar(charset_info, from, end)))
{
while (l--)
*to++ = *from++; /* Сохранить в to все байты многобайтового символа. */
from--; /* Вернуть указатель на 1 байт назад.Т.е. на первый байт символа, следующего сразу за многобайтовым */
continue; /* Покинуть текущую итерацию цикла for */
}
#endif
switch (*from)
{
case 0:
/* Must be escaped for 'mysql' */
*to++ = '\\';
*to++ = '0';
break;
case '\n':
/* Must be escaped for logs */
*to++ = '\\';
*to++ = 'n';
break;
case '\r':
*to++ = '\\';
*to++ = 'r';
break;
case '\\':
*to++ = '\\';
*to++ = '\\';
break;
case '\'':
/* Апостроф */
*to++ = '\\';
*to++ = '\'';
break;
case '"': // Кавычка
*to++ = '\\';
*to++ = '"';
break;
case '\032':
/* Ctrl-Z. This gives problems on Win32 */
*to++ = '\\';
*to++ = 'Z';
break;
default:
*to++ = *from; /* Любой неопасный символ */
}
}
*to = 0; /* Последним ставится разрыв строки */
return (ulong) (to - to_start); /* Длина to за вычетом разрыва строки */
}
Прежде всего, функция работает прекрасно. Но кое-что в ее реализации меня настораживает. А именно:
1. Зачем может понадобиться в каждой итерации цикла for узнавать значение флага use_mb_flag ?
if (use_mb_flag && (l = my_ismbchar(charset_info, from, end)))
Он устанавливается один раз в начале функции и значения больше не меняет.
2. Почему не прослешиваются многобайтовые символы? Что если частью многобайтового символа окажется \0 или \ или ' и т.п. ?
Это, собственно, еще не проблема. Проблема будет позже

Сначала, мне хотелось бы услышать Ваше мнение по этим двум вопросам.
Здравствуйте, Xavante, Вы писали:
X>Это, собственно, еще не проблема. Проблема будет позже
Сначала, мне хотелось бы услышать Ваше мнение по этим двум вопросам.
ИМХО
явный глюк.. не парься.. вроде как совсем крутую работу со всеми кодировкамт в том числе и многобайтными обещают только в 4.1.. лучше отпиши его на bugs.mysql.com, а еще лучше с исправлениями.. на то он и opensource

вот код ты уже передрал.. а ведь это подпадает под лицензию как производный продукт.. то есть можно использовать только под GPL..
Здравствуйте, vvaizh, Вы писали:
V>вот код ты уже передрал.. а ведь это подпадает под лицензию как производный продукт.. то есть можно использовать только под GPL.
А я пока еще никому ничего не продавал

. Кроме того, у меня есть собственный аналог этой функции, который значительно шустрее Мускульного. Правда, он пока не фурычит

Я скоро его выложу, чтобы все тут харашенька его раскритиковали.
Еще 1 вопросец вдогонку: Можно ли наткнуться на многобайтовый символ в jpg или gif файле? Т.е., они в принципе там могут встретиться или нет?