Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
V750. BSTR string becomes invalid. Noti…
menu mobile close menu
Проверка проектов
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Микрооптимизации (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Реализовано по запросам пользователей (C++)
Cтандарт MISRA
Стандарт AUTOSAR
Стандарт OWASP (C++)
Стандарт OWASP (C#)
Проблемы при работе анализатора кода
Дополнительная информация
toggle menu Оглавление

V750. BSTR string becomes invalid. Notice that BSTR strings store their length before start of the text.

19 Янв 2016

Анализатор обнаружил, что над указателем на строку в формате BSTR выполняются недопустимые операции. Указатель типа BSTR всегда должен ссылаться на первый символ строки. Если мы сдвинем указатель хотя бы на один символ, то получим некорректную BSTR строку.

Имеется ввиду, что вот такой код крайне опасен:

BSTR str = foo();
str++;

Теперь 'str' нельзя использовать как BSTR строку. Если нужно пропустить один символ, следует написать следующий код:

BSTR str = foo();
BSTR newStr = SysAllocString(str + 1);

Если вам не нужна BSTR строка, то можно написать следующий код:

BSTR str = foo();
const wchar_t *newStr = str;
newStr++;

Или так:

BSTR str = foo();
const wchar_t *newStr = str + 1;

Чтобы понять, почему недопустимо менять значение указателя типа BSTR, процитируем статью с сайта MSDN.

typedef wchar_t OLECHAR;
typedef OLECHAR * BSTR;

BSTR (basic string или binary string) – это строковый тип данных, который используется в COM, Automation и Interop функциях. Тип BSTR следует использовать во всех интерфейсах. Представление BSTR:

  • Префикс длины. Целое число размером 4 байта, которое отображает длину следующей за ним строки в байтах. Префикс длины указывается непосредственно перед первым символом строки и не учитывает символ-ограничитель.
  • Строка данных. Строка символов в кодировке Unicode. Может содержат множественные вложенные нулевые символы.
  • Ограничитель. Два нулевых символа.

Тип BSTR является указателем, который указывает на первый символ строки, а не на префикс длины.

Память для BSTR-строк выделяется с помощью функций выделения памяти COM, поэтому они могут возвращаться методами без необходимости контроля над выделением памяти.

Представленный ниже код является неправильным:

BSTR MyBstr = L"I am a happy BSTR";

Данный пример собирается (компилируется и линкуется) успешно, но не будет работать должным образом, поскольку у строки отсутствует префикс длины. Если проверить расположение в памяти данной переменной с помощью отладчика, он покажет отсутствие префикса длины размером 4 байта перед началом строки данных.

Правильный вариант кода должен выглядеть так:

BSTR MyBstr = SysAllocString(L"I am a happy BSTR");

Теперь отладчик покажет наличие префикса длины, который равен значению 34. Оно соответствует 17 символам, которые приводится к wide-character строке с помощью строкового модификатора "L". Отладчик также покажет двухбайтовый символ-ограничитель (0x0000) в конце строки.

Если передать простую Unicode-строку в качестве аргумента функции COM, которая ожидает BSTR-строку, произойдет сбой в работе этой функции.

Надеемся, что процитированного фрагмента MSDN достаточно, чтобы понять, почему нельзя просто так взять и изменить указатель типа BSTR.

Когда мы пишем код:

BSTR str = foo();
str += 3;

Мы портим BSTR строку. Указатель ссылается не на начало строки, а куда-то в середину. Соответственно, если мы попытаемся взять длину строки по отрицательному смещению, то мы прочитаем случайное значение. Вернее, предыдущие символы будут интерпретированы как длина строки.

Дополнительные ссылки:

close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам