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) |