diff --git a/Source/Plugins.cpp b/Source/Plugins.cpp index 32a664a4..64c250a0 100644 --- a/Source/Plugins.cpp +++ b/Source/Plugins.cpp @@ -51,8 +51,9 @@ bool contains(const C& cntnr, const K& key) template const typename C::const_iterator get_iterator(const C& cntnr, const K& key) { - assert( contains(cntnr, key) ); - return cntnr.find(key); + const typename C::const_iterator it = cntnr.find(key); + assert(cntnr.end() != it); + return it; } template @@ -245,6 +246,16 @@ bool Plugins::IsPluginCommand(const tstring& token) const return contains(m_commands, token); } +bool Plugins::IsKnownPlugin(const tstring& token) const +{ + const tstring dllname = GetDllName(token); + return contains(m_dllname_to_path, dllname); +} +bool Plugins::IsPluginCallSyntax(const tstring& token) +{ + const tstring dllname = GetDllName(token); + return dllname.length() + 2 < token.length(); +} #endif diff --git a/Source/Plugins.h b/Source/Plugins.h index cdccfb53..b7f383dc 100644 --- a/Source/Plugins.h +++ b/Source/Plugins.h @@ -51,9 +51,11 @@ class Plugins bool Initialize(const TCHAR*arcsubdir, bool displayInfo); void AddPluginsDir(const tstring& path, bool displayInfo); bool IsPluginCommand(const tstring& command) const; + bool IsKnownPlugin(const tstring& token) const; bool GetCommandInfo(const tstring&command, tstring&canoniccmd, tstring&dllPath); int GetDllDataHandle(bool uninst, const tstring& command) const; void SetDllDataHandle(bool uninst, tstring&canoniccmd, int dataHandle); + static bool IsPluginCallSyntax(const tstring& token); private: // methods void GetExports(const tstring &pathToDll, bool displayInfo); diff --git a/Source/build.h b/Source/build.h index 689727e6..b03945d9 100644 --- a/Source/build.h +++ b/Source/build.h @@ -177,7 +177,7 @@ class CEXEBuild { bool is_ppbranch_token(TCHAR *s); bool is_pp_token(int tkid); bool is_unsafe_pp_token(int tkid); - int get_commandtoken(TCHAR *s, int *np, int *op, int *pos); + int get_commandtoken(const TCHAR *s, int *np, int *op, int *pos); const TCHAR* get_commandtoken_name(int tok); /** @@ -186,7 +186,7 @@ class CEXEBuild { * @return TP_FUNC, TP_SEC, TP_PAGEEX, TP_GLOBAL. */ int GetCurrentTokenPlace(); - int IsTokenPlacedRight(int pos, TCHAR *tok); + int IsTokenPlacedRight(int pos, const TCHAR *tok); // script.cpp #ifdef NSIS_SUPPORT_STANDARD_PREDEFINES diff --git a/Source/script.cpp b/Source/script.cpp index 061eb3fd..9daabf16 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -385,23 +385,24 @@ int CEXEBuild::doParse(const TCHAR *str) parse_again: if (line.getnumtokens() < 1) return PS_OK; + const TCHAR* const tokstr0 = line.gettoken_str(0); int np,op,pos; - int tkid=get_commandtoken(line.gettoken_str(0),&np,&op,&pos); + int tkid=get_commandtoken(tokstr0,&np,&op,&pos); if (tkid == -1) { - TCHAR *p=line.gettoken_str(0); + const TCHAR *p=tokstr0; if (p[0] && p[_tcslen(p)-1]==_T(':')) { if (p[0] == _T('!') || (p[0] >= _T('0') && p[0] <= _T('9')) || p[0] == _T('$') || p[0] == _T('-') || p[0] == _T('+')) { - ERROR_MSG(_T("Invalid label: %") NPRIs _T(" (labels cannot begin with !, $, -, +, or 0-9)\n"),line.gettoken_str(0)); + ERROR_MSG(_T("Invalid label: %") NPRIs _T(" (labels cannot begin with !, $, -, +, or 0-9)\n"),tokstr0); return PS_ERROR; } extern FILE *g_output; if (preprocessonly) - _ftprintf(g_output,_T("%") NPRIs _T("\n"),line.gettoken_str(0)); + _ftprintf(g_output,_T("%") NPRIs _T("\n"),tokstr0); else - if (add_label(line.gettoken_str(0))) return PS_ERROR; + if (add_label(tokstr0)) return PS_ERROR; line.eattoken(); goto parse_again; } @@ -411,7 +412,7 @@ parse_again: // We didn't recognise this command, could it be the name of a // function exported from a dll? // Plugins cannot be called in global scope so there is no need to initialize the list first - if (m_pPlugins && m_pPlugins->IsPluginCommand(line.gettoken_str(0))) + if (m_pPlugins && m_pPlugins->IsPluginCommand(tokstr0)) { np = 0; // parameters are optional op = -1; // unlimited number of optional parameters @@ -421,18 +422,23 @@ parse_again: else #endif { - ERROR_MSG(_T("Invalid command: %") NPRIs _T("\n"),line.gettoken_str(0)); +#ifdef NSIS_CONFIG_PLUGIN_SUPPORT + if (Plugins::IsPluginCallSyntax(tokstr0) && (!m_pPlugins || !m_pPlugins->IsKnownPlugin(tokstr0))) + ERROR_MSG(_T("Plugin not found, cannot call %") NPRIs _T("\n"),tokstr0); + else +#endif + ERROR_MSG(_T("Invalid command: %") NPRIs _T("\n"),tokstr0); return PS_ERROR; } } - if (IsTokenPlacedRight(pos, line.gettoken_str(0)) != PS_OK) + if (IsTokenPlacedRight(pos, tokstr0) != PS_OK) return PS_ERROR; int v=line.getnumtokens()-(np+1); if (v < 0 || (op >= 0 && v > op)) // opt_parms is -1 for unlimited { - ERROR_MSG(_T("%") NPRIs _T(" expects %d"),line.gettoken_str(0),np); + ERROR_MSG(_T("%") NPRIs _T(" expects %d"),tokstr0,np); if (op < 0) ERROR_MSG(_T("+")); if (op > 0) ERROR_MSG(_T("-%d"),op+np); ERROR_MSG(_T(" parameters, got %d.\n"),line.getnumtokens()-1); diff --git a/Source/tokens.cpp b/Source/tokens.cpp index 9dfc7eba..75c0a185 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -360,7 +360,7 @@ bool CEXEBuild::is_unsafe_pp_token(int tkid) return false; } -int CEXEBuild::get_commandtoken(TCHAR *s, int *np, int *op, int *pos) +int CEXEBuild::get_commandtoken(const TCHAR *s, int *np, int *op, int *pos) { for (int x = 0; x < TOK__LAST; x ++) if (!_tcsicmp(tokenlist[x].name,s)) @@ -384,7 +384,7 @@ int CEXEBuild::GetCurrentTokenPlace() return TP_GLOBAL; } -int CEXEBuild::IsTokenPlacedRight(int pos, TCHAR *tok) +int CEXEBuild::IsTokenPlacedRight(int pos, const TCHAR *tok) { if (preprocessonly) return PS_OK;