Данные JavaScript и сценариев плагина NPAPI в Google Chrome

Я создал простой скрипт-плагин npapi. Он отлично работает для передачи строки между JavaScript и плагином в FireFox. Но он будет генерировать дополнительные случайные символы в Google Chrome, если строка содержит символ дефиса (-). Например, в моем коде JavaScript у меня есть

plugin.method("a-b");

в моем коде нпапи, у меня есть

bool ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result) {

  char* outString = args[0].value.stringValue.UTF8Characters;
  char* npOutString = (char *)NPN_MemAlloc(strlen(outString) + 1);
  strcpy(npOutString, outString);
  STRINGZ_TO_NPVARIANT(npOutString, *result);

  return true;
}

В Firefox он возвращает "ab", в Chrome я вижу "ab*[-.." с некоторыми дополнительными случайными символами. Я попытался поместить npplugin.dll в папку "plugins" в Mozilla или использовать руководство по расширению Chrome (http://code.google.com/chrome/extensions/npapi.html), оба способа дали мне одинаковое странное поведение. Код скомпилирован с xulrunner-10.0.2.en-US.win32.sdk, с использованием xulrunner-1.9.0.17.en-US.win32.sdk также имеет такую ​​же проблему.

У кого-нибудь есть какие-нибудь подсказки?

1 ответ

Ваша проблема в том, что вы предполагаете, что это стандартная строка C с нулевым символом в конце. На практике строки NPAPI часто являются строками C и заканчиваются NULL, но нет никакой гарантии, что это будет так. Если вы посмотрите на файл заголовка npruntime.h из проекта npapi-sdk, то увидите, что в NPString есть член UTF8Length; это не только для украшения. Вы всегда должны использовать это для определения длины (в байтах) строки UTF8.

Чтобы повторить то, что smorgan сказал в комментарии ниже, это означает, что вы не можете использовать strcpy, strlen или любую другую строковую функцию C для доступа к ней; NPString - это пара байт + длина, поэтому вам нужно получить к ней доступ, используя методы byte+length.

Например:

bool ScriptablePluginObject::Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result) {

  char* outString = args[0].value.stringValue.UTF8Characters;
  int outLen = args[0].value.stringValue.UTF8Length;
  char* npOutString = (char *)NPN_MemAlloc(outLen + 1);
  memcpy(npOutString, outString, outLen);
  // Make this NULL terminated
  npOutString[outLen] = NULL;
  STRINGZ_TO_NPVARIANT(npOutString, *result);

  return true;
}

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

Другие вопросы по тегам