Fixed bug #1122 StrCpy maxlen inconsistent behavior

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6810 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2016-12-05 15:44:19 +00:00
parent aaca82cd5f
commit 7f2ca3cdee
5 changed files with 57 additions and 77 deletions

View file

@ -14,6 +14,8 @@ Released on December ?th, 2016
\b \R{setctlcolors}{SetCtlColors} now supports Windows color constant values \b \R{setctlcolors}{SetCtlColors} now supports Windows color constant values
\b StrCpy "" maxlen handling (\W{http://sf.net/p/nsis/bugs/1122}{bug #1122})
\b Fixed buffer size bug in winchar.cpp (\W{http://sf.net/p/nsis/patches/271}{patch #271}) \b Fixed buffer size bug in winchar.cpp (\W{http://sf.net/p/nsis/patches/271}{patch #271})
\S2{} Translations \S2{} Translations

View file

@ -3730,6 +3730,13 @@ int CEXEBuild::DeclaredUserVar(const TCHAR *szVarName)
} }
int CEXEBuild::GetUnsafeUserVarIndex(LineParser &line, int token)
{
TCHAR *p = line.gettoken_str(token);
int idx = (*p == _T('$') && *++p) ? m_UserVarNames.get(p) : -1;
if (idx >= 0 && m_UserVarNames.get_reference(idx) >= 0) m_UserVarNames.inc_reference(idx);
return idx;
}
int CEXEBuild::GetUserVarIndex(LineParser &line, int token) int CEXEBuild::GetUserVarIndex(LineParser &line, int token)
{ {
TCHAR *p = line.gettoken_str(token); TCHAR *p = line.gettoken_str(token);

View file

@ -411,6 +411,7 @@ class CEXEBuild {
int disable_window_icon; int disable_window_icon;
// User variables stuff // User variables stuff
int GetUnsafeUserVarIndex(LineParser &line, int token);
int GetUserVarIndex(LineParser &line, int token); int GetUserVarIndex(LineParser &line, int token);
// Added by ramon 3 jun 2003 // Added by ramon 3 jun 2003
UserVarsStringList m_UserVarNames; UserVarsStringList m_UserVarNames;

View file

@ -122,12 +122,23 @@ void NSISCALL update_status_text_buf1(int strtab)
update_status_text(strtab, g_bufs[1]); update_status_text(strtab, g_bufs[1]);
} }
static INT_PTR NSISCALL GetIntPtrFromParm(int id_) #ifdef _WIN64
static INT_PTR NSISCALL GetIntPtrFromParm(int id)
{ {
return strtoiptr(GetNSISStringTT(g_parms[id_])); return strtoiptr(GetNSISStringTT(g_parms[id]));
} }
#else
#define GetIntPtrFromParm(id_) ( (INT32)(GetIntFromParmEx(id_).LowPart) )
#endif
#define GetHwndFromParm(id_) ( (HWND)GetIntPtrFromParm(id_) ) #define GetHwndFromParm(id_) ( (HWND)GetIntPtrFromParm(id_) )
#define GetIntFromParm(id_) ( (INT32)(UINT32)GetIntPtrFromParm(id_) ) #define GetIntFromParm(id_) ( (INT32)(UINT32)GetIntPtrFromParm(id_) )
static LARGE_INTEGER GetIntFromParmEx(int id)
{
LARGE_INTEGER v;
const TCHAR *p = GetNSISStringTT(g_parms[id]);
v.LowPart = myatoi(p), v.HighPart = *p;
return v; // HighPart is non-zero if the string is not empty
}
// NB - USE CAUTION when rearranging code to make use of the new return value of // NB - USE CAUTION when rearranging code to make use of the new return value of
// this function - be sure the parm being accessed is not modified before the call. // this function - be sure the parm being accessed is not modified before the call.
@ -616,20 +627,18 @@ static int NSISCALL ExecuteEntry(entry *entry_)
break; break;
case EW_ASSIGNVAR: case EW_ASSIGNVAR:
{ {
int newlen=GetIntFromParm(2); LARGE_INTEGER newlenex=GetIntFromParmEx(2);
int start=GetIntFromParm(3); int start=GetIntFromParm(3), newlen=newlenex.LowPart;
int l; TCHAR *p=var0, *buf0=GetStringFromParm(0x01);
TCHAR *p=var0; int srclen=mystrlen(buf0);
TCHAR *buf0=GetStringFromParm(0x01);
*p=0; *p=0;
if (!parm2 || newlen) if (!newlenex.HighPart) newlen=srclen; // "StrCpy $1 $2 $3" where $3=""
if (newlen)
{ {
l=mystrlen(buf0); if (start<0) start=srclen+start;
if (start<0) start=l+start;
if (start>=0) if (start>=0)
{ {
if (start>l) start=l; if (start>srclen) start=srclen;
mystrcpy(p,buf0+start); mystrcpy(p,buf0+start);
if (newlen) if (newlen)
{ {

View file

@ -4601,8 +4601,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
ent.which=EW_SHOWWINDOW; ent.which=EW_SHOWWINDOW;
ent.offsets[0]=add_asciistring(_T("$HWNDPARENT")); ent.offsets[0]=add_asciistring(_T("$HWNDPARENT"));
ent.offsets[1]=add_asciistring(_T("5")/*SW_SHOW*/); ent.offsets[1]=add_asciistring(_T("5")/*SW_SHOW*/);
ret = add_entry(&ent); if ((ret = add_entry(&ent)) != PS_OK) return ret;
if (ret != PS_OK) return ret;
ent.which=EW_BRINGTOFRONT; ent.which=EW_BRINGTOFRONT;
ent.offsets[0]=0; ent.offsets[0]=0;
ent.offsets[1]=0; ent.offsets[1]=0;
@ -5043,22 +5042,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
const TCHAR* msgprefix = _T(""); const TCHAR* msgprefix = _T("");
int idx = -1; int idx = -1;
if (TOK_STRCPY == which_token) if (TOK_STRCPY == which_token)
{
idx = GetUserVarIndex(line, 1); idx = GetUserVarIndex(line, 1);
}
else else
{ idx = GetUnsafeUserVarIndex(line, 1), msgprefix = _T("Unsafe");
msgprefix = _T("Unsafe");
TCHAR *p = line.gettoken_str(1);
if (*p == _T('$') && *++p) idx = m_UserVarNames.get(p);
if (-1 != idx && m_UserVarNames.get_reference(idx) != -1) m_UserVarNames.inc_reference(idx);
}
if (idx < 0) PRINTHELP() if (idx < 0) PRINTHELP()
ent.offsets[0]=idx; ent.offsets[0]=idx; // Destination variable
ent.offsets[1]=add_string(line.gettoken_str(2)); ent.offsets[1]=add_string(line.gettoken_str(2)); // Source string
ent.offsets[2]=add_string(line.gettoken_str(3)); ent.offsets[2]=add_string(line.gettoken_str(3)); // Optional MaxLen
ent.offsets[3]=add_string(line.gettoken_str(4)); ent.offsets[3]=add_string(line.gettoken_str(4)); // Optional StartOffset
SCRIPT_MSG(_T("%") NPRIs _T("StrCpy %") NPRIs _T(" \"%") NPRIs _T("\" (%") NPRIs _T(") (%") NPRIs _T(")\n"), SCRIPT_MSG(_T("%") NPRIs _T("StrCpy %") NPRIs _T(" \"%") NPRIs _T("\" (%") NPRIs _T(") (%") NPRIs _T(")\n"),
msgprefix,line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4)); msgprefix,line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
return add_entry(&ent); return add_entry(&ent);
@ -5082,11 +5073,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
return add_entry(&ent); return add_entry(&ent);
case TOK_GETCURRENTADDR: case TOK_GETCURRENTADDR:
ent.which=EW_ASSIGNVAR; ent.which=EW_ASSIGNVAR;
ent.offsets[0]=GetUserVarIndex(line, 1); if ((ent.offsets[0]=GetUserVarIndex(line, 1)) < 0) PRINTHELP()
ent.offsets[1]=add_intstring(1+(cur_header->blocks[NB_ENTRIES].num)); ent.offsets[1]=add_intstring(1+(cur_header->blocks[NB_ENTRIES].num));
if (ent.offsets[0] < 0) PRINTHELP() ent.offsets[2]=ent.offsets[3]=0;
ent.offsets[2]=0;
ent.offsets[3]=0;
SCRIPT_MSG(_T("GetCurrentAddress: %") NPRIs _T("\n"),line.gettoken_str(1)); SCRIPT_MSG(_T("GetCurrentAddress: %") NPRIs _T("\n"),line.gettoken_str(1));
return add_entry(&ent); return add_entry(&ent);
case TOK_STRCMP: case TOK_STRCMP:
@ -5109,18 +5098,13 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
return PS_ERROR; return PS_ERROR;
} }
ent.which=EW_ASSIGNVAR; ent.which=EW_ASSIGNVAR;
ent.offsets[0]=GetUserVarIndex(line, 2); if ((ent.offsets[0]=GetUserVarIndex(line, 2)) < 0) PRINTHELP()
ent.offsets[1]=add_intstring(high); ent.offsets[1]=add_intstring(high);
ent.offsets[2]=0; ent.offsets[2]=ent.offsets[3]=0;
ent.offsets[3]=0; if (PS_OK != add_entry(&ent)) return PS_ERROR;
if (ent.offsets[0]<0) PRINTHELP() if ((ent.offsets[0]=GetUserVarIndex(line, 3)) < 0) PRINTHELP()
add_entry(&ent);
ent.offsets[0]=GetUserVarIndex(line, 3);
ent.offsets[1]=add_intstring(low); ent.offsets[1]=add_intstring(low);
ent.offsets[2]=0; ent.offsets[2]=ent.offsets[3]=0;
ent.offsets[3]=0;
if (ent.offsets[0]<0) PRINTHELP()
SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T(" (%u,%u)->(%") NPRIs _T(",%") NPRIs _T(")\n"), SCRIPT_MSG(_T("%") NPRIs _T(": %") NPRIs _T(" (%u,%u)->(%") NPRIs _T(",%") NPRIs _T(")\n"),
cmdname,line.gettoken_str(1),high,low,line.gettoken_str(2),line.gettoken_str(3)); cmdname,line.gettoken_str(1),high,low,line.gettoken_str(2),line.gettoken_str(3));
} }
@ -5154,22 +5138,16 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
unsigned long long ll = (st.st_mtime * 10000000LL) + 116444736000000000LL; unsigned long long ll = (st.st_mtime * 10000000LL) + 116444736000000000LL;
high = (DWORD) (ll >> 32), low = (DWORD) ll; high = (DWORD) (ll >> 32), low = (DWORD) ll;
#endif #endif
ent.which=EW_ASSIGNVAR; ent.which=EW_ASSIGNVAR;
ent.offsets[0]=GetUserVarIndex(line, 2); if ((ent.offsets[0]=GetUserVarIndex(line, 2)) < 0) PRINTHELP()
wsprintf(buf,_T("%u"),high); wsprintf(buf,_T("%u"),high);
ent.offsets[1]=add_string(buf); ent.offsets[1]=add_string(buf);
ent.offsets[2]=0; ent.offsets[2]=ent.offsets[3]=0;
ent.offsets[3]=0; if (PS_OK != add_entry(&ent)) return PS_ERROR;
if (ent.offsets[0]<0) PRINTHELP() if ((ent.offsets[0]=GetUserVarIndex(line, 3)) < 0) PRINTHELP()
add_entry(&ent);
ent.offsets[0]=GetUserVarIndex(line, 3);
wsprintf(buf,_T("%u"),low); wsprintf(buf,_T("%u"),low);
ent.offsets[1]=add_string(buf); ent.offsets[1]=add_string(buf);
ent.offsets[2]=0; ent.offsets[2]=ent.offsets[3]=0;
ent.offsets[3]=0;
if (ent.offsets[0]<0) PRINTHELP()
SCRIPT_MSG(_T("GetFileTimeLocal: %") NPRIs _T(" (%u,%u)->(%") NPRIs _T(",%") NPRIs _T(")\n"), SCRIPT_MSG(_T("GetFileTimeLocal: %") NPRIs _T(" (%u,%u)->(%") NPRIs _T(",%") NPRIs _T(")\n"),
line.gettoken_str(1),high,low,line.gettoken_str(2),line.gettoken_str(3)); line.gettoken_str(1),high,low,line.gettoken_str(2),line.gettoken_str(3));
} }
@ -6149,7 +6127,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
PRINTHELP(); PRINTHELP();
case TOK__PLUGINCOMMAND: case TOK__PLUGINCOMMAND:
{ {
int ret;
tstring command, dllPath; tstring command, dllPath;
if (!m_pPlugins->GetCommandInfo(line.gettoken_str(0), command, dllPath)) if (!m_pPlugins->GetCommandInfo(line.gettoken_str(0), command, dllPath))
@ -6159,17 +6136,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
} }
tstring dllName = get_file_name(dllPath); tstring dllName = get_file_name(dllPath);
int data_handle = m_pPlugins->GetDllDataHandle(!!uninstall_mode, command); int data_handle = m_pPlugins->GetDllDataHandle(!!uninstall_mode, command), ret;
if (uninstall_mode) uninst_plugin_used = true; else plugin_used = true; if (uninstall_mode) uninst_plugin_used = true; else plugin_used = true;
// Initialize $PLUGINSDIR // Initialize $PLUGINSDIR
ent.which=EW_CALL; ent.which=EW_CALL;
ent.offsets[0]=ns_func.add(uninstall_mode?_T("un.Initialize_____Plugins"):_T("Initialize_____Plugins"),0); ent.offsets[0]=ns_func.add(uninstall_mode?_T("un.Initialize_____Plugins"):_T("Initialize_____Plugins"),0);
ret=add_entry(&ent); if ((ret=add_entry(&ent)) != PS_OK) return ret;
if (ret != PS_OK) {
return ret;
}
// DLL name on the users machine // DLL name on the users machine
TCHAR tempDLL[NSIS_MAX_STRLEN]; TCHAR tempDLL[NSIS_MAX_STRLEN];
@ -6217,17 +6191,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
ent.offsets[3]=0xffffffff; ent.offsets[3]=0xffffffff;
ent.offsets[4]=0xffffffff; ent.offsets[4]=0xffffffff;
ent.offsets[5]=DefineInnerLangString(NLF_FILE_ERROR); ent.offsets[5]=DefineInnerLangString(NLF_FILE_ERROR);
ret=add_entry(&ent); if ((ret=add_entry(&ent)) != PS_OK) return ret;
if (ret != PS_OK) {
return ret;
}
} }
// SetDetailsPrint lastused // SetDetailsPrint lastused
ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), 0, 1); ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), 0, 1);
if (ret != PS_OK) { if (ret != PS_OK) return ret;
return ret;
}
// Call the DLL // Call the DLL
tstring funcname = get_string_suffix(command, _T("::")); tstring funcname = get_string_suffix(command, _T("::"));
@ -6236,8 +6205,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
int i = 1; int i = 1;
int nounload = 0; int nounload = 0;
if (!_tcsicmp(line.gettoken_str(i), _T("/NOUNLOAD"))) { if (!_tcsicmp(line.gettoken_str(i), _T("/NOUNLOAD"))) {
i++; i++, nounload++;
nounload++;
} }
// First push dll args // First push dll args
@ -6251,10 +6219,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
if (!_tcsicmp(line.gettoken_str(w), _T("/NOUNLOAD"))) nounloadmisused=1; if (!_tcsicmp(line.gettoken_str(w), _T("/NOUNLOAD"))) nounloadmisused=1;
ent.offsets[1]=0; ent.offsets[1]=0;
ent.offsets[2]=0; ent.offsets[2]=0;
ret=add_entry(&ent); if ((ret=add_entry(&ent)) != PS_OK) return ret;
if (ret != PS_OK) {
return ret;
}
SCRIPT_MSG(_T(" %") NPRIs,line.gettoken_str(i)); SCRIPT_MSG(_T(" %") NPRIs,line.gettoken_str(i));
} }
SCRIPT_MSG(_T("\n")); SCRIPT_MSG(_T("\n"));
@ -6268,10 +6233,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
ent.offsets[2]=0; ent.offsets[2]=0;
ent.offsets[3]=nounload|build_plugin_unload; ent.offsets[3]=nounload|build_plugin_unload;
ent.offsets[4]=1; ent.offsets[4]=1;
ret=add_entry(&ent); if ((ret=add_entry(&ent)) != PS_OK) return ret;
if (ret != PS_OK) {
return ret;
}
DefineInnerLangString(NLF_SYMBOL_NOT_FOUND); DefineInnerLangString(NLF_SYMBOL_NOT_FOUND);
DefineInnerLangString(NLF_COULD_NOT_LOAD); DefineInnerLangString(NLF_COULD_NOT_LOAD);
@ -6288,8 +6250,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
// Call [un.]Initialize_____Plugins // Call [un.]Initialize_____Plugins
ent.which=EW_CALL; ent.which=EW_CALL;
ent.offsets[0]=ns_func.add(uninstall_mode?_T("un.Initialize_____Plugins"):_T("Initialize_____Plugins"),0); ent.offsets[0]=ns_func.add(uninstall_mode?_T("un.Initialize_____Plugins"):_T("Initialize_____Plugins"),0);
ret=add_entry(&ent); if ((ret=add_entry(&ent)) != PS_OK) return ret;
if (ret != PS_OK) return ret;
// SetDetailsPrint lastused // SetDetailsPrint lastused
ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), 0, 1); ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), 0, 1);
if (ret != PS_OK) return ret; if (ret != PS_OK) return ret;