| Index: src/plugin/PluginUserSettings.cpp |
| =================================================================== |
| --- a/src/plugin/PluginUserSettings.cpp |
| +++ b/src/plugin/PluginUserSettings.cpp |
| @@ -1,6 +1,7 @@ |
| #include "PluginStdAfx.h" |
| #include "PluginUserSettings.h" |
| #include <algorithm> |
| +#include "COM_Value.h" |
| #include "PluginSettings.h" |
| #include "PluginClient.h" |
| #include "../shared/Dictionary.h" |
| @@ -130,23 +131,29 @@ |
| if (dispidMember < 0 || dispidMember >= countof(s_Methods)) |
| return DISP_E_BADINDEX; |
| + /* |
| + * See Issue #1163. |
| + * TODO: Rewrite this linear sequence of string comparisons as a switch statement. |
| + * TODO: Add a try-catch block at the top level of the switch body to rationalize argument checking etc. |
| + */ |
| const CString& method = s_Methods[dispidMember]; |
| - |
| if (s_GetMessage == method) |
| { |
| - if (2 != pDispparams->cArgs) |
| - return DISP_E_BADPARAMCOUNT; |
| - |
| - if (VT_BSTR != pDispparams->rgvarg[0].vt) |
| - return DISP_E_TYPEMISMATCH; |
| - if (VT_BSTR != pDispparams->rgvarg[1].vt) |
| - return DISP_E_TYPEMISMATCH; |
| - |
| + /* |
| + * If the caller ignores the value, we can elide the body since it has no side-effects. |
| + */ |
| if (pVarResult) |
| { |
| - CComBSTR key = pDispparams->rgvarg[0].bstrVal; |
| - CComBSTR section = pDispparams->rgvarg[1].bstrVal; |
| - CStringW message = sGetMessage((BSTR)section, (BSTR)key); |
| + if (2 != pDispparams->cArgs) |
| + return DISP_E_BADPARAMCOUNT; |
| + |
| + AdblockPlus::COM::IncomingParam key(pDispparams->rgvarg[0]); |
| + AdblockPlus::COM::IncomingParam section(pDispparams->rgvarg[1]); |
| + if (!key.wstringConvertible() || !section.wstringConvertible()) |
| + { |
| + return DISP_E_TYPEMISMATCH; |
| + } |
| + CStringW message = sGetMessage(to_CString(section.wstringValueNoexcept()), to_CString(key.wstringValueNoexcept())); |
| pVarResult->vt = VT_BSTR; |
| pVarResult->bstrVal = SysAllocString(message); |
| @@ -243,9 +250,12 @@ |
| if (VT_BSTR != pDispparams->rgvarg[0].vt) |
| return DISP_E_TYPEMISMATCH; |
| - CComBSTR url = pDispparams->rgvarg[0].bstrVal; |
| - |
| - settings->SetSubscription((BSTR)url); |
| + AdblockPlus::COM::IncomingParam url(pDispparams->rgvarg[0]); |
| + if (!url.wstringConvertible()) |
| + { |
| + return DISP_E_TYPEMISMATCH; |
| + } |
| + settings->SetSubscription(url.wstringValueNoexcept()); |
| } |
| else if (s_GetLanguage == method) |
| { |
| @@ -290,10 +300,15 @@ |
| if (VT_BSTR != pDispparams->rgvarg[0].vt) |
| return DISP_E_TYPEMISMATCH; |
| - CComBSTR domain = pDispparams->rgvarg[0].bstrVal; |
| - if (domain.Length()) |
| + AdblockPlus::COM::IncomingParam domain_arg(pDispparams->rgvarg[0]); |
| + if (!domain_arg.wstringConvertible()) |
| { |
| - settings->AddWhiteListedDomain((BSTR)domain); |
| + return DISP_E_TYPEMISMATCH; |
| + } |
| + std::wstring domain = domain_arg.wstringValueNoexcept(); |
| + if (!domain.empty()) |
| + { |
| + settings->AddWhiteListedDomain(to_CString(domain)); |
| } |
| } |
| else if (s_RemoveWhitelistDomain == method) |
| @@ -304,10 +319,15 @@ |
| if (VT_BSTR != pDispparams->rgvarg[0].vt) |
| return DISP_E_TYPEMISMATCH; |
| - CComBSTR domain = pDispparams->rgvarg[0].bstrVal; |
| - if (domain.Length()) |
| + AdblockPlus::COM::IncomingParam domain_arg(pDispparams->rgvarg[0]); |
| + if (!domain_arg.wstringConvertible()) |
| { |
| - settings->RemoveWhiteListedDomain((BSTR)domain); |
| + return DISP_E_TYPEMISMATCH; |
| + } |
| + std::wstring domain = domain_arg.wstringValueNoexcept(); |
| + if (!domain.empty()) |
| + { |
| + settings->RemoveWhiteListedDomain(to_CString(domain)); |
| } |
| } |
| else if (s_GetAppLocale == method) |