summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2018-03-31 20:38:43 +0200
committerDidier Raboud <odyx@debian.org>2018-03-31 20:38:43 +0200
commite4d2f9992bc72368b0b1f439b32c169142209b0b (patch)
treee65920abd4a197b5ec2aa99e298ace61f605caa2 /Source
parent98d6ab3f202959828f1f0f57c276afc2e1c51197 (diff)
Import Upstream version 3.01
Diffstat (limited to 'Source')
-rwxr-xr-xSource/Tests/compression.cpp8
-rwxr-xr-xSource/Tests/mmap.cpp5
-rwxr-xr-xSource/Tests/textrunner.cpp5
-rwxr-xr-xSource/Tests/winchar.cpp7
-rwxr-xr-xSource/build.cpp7
-rwxr-xr-xSource/build.h8
-rwxr-xr-xSource/exehead/Ui.c2
-rwxr-xr-xSource/exehead/exec.c41
-rwxr-xr-xSource/makenssi.cpp36
-rwxr-xr-xSource/script.cpp190
-rwxr-xr-xSource/utf.cpp3
-rwxr-xr-xSource/util.cpp50
-rwxr-xr-xSource/util.h8
-rwxr-xr-xSource/winchar.cpp4
14 files changed, 206 insertions, 168 deletions
diff --git a/Source/Tests/compression.cpp b/Source/Tests/compression.cpp
index f38ab3a..f586d48 100755
--- a/Source/Tests/compression.cpp
+++ b/Source/Tests/compression.cpp
@@ -17,8 +17,12 @@ public:
void randData(IGrowBuf &buf, int kb) {
srand(time(0));
+#define IsBug1156(r) ( ((r) & 0x80) == 0x80 )
for (int i = 0; i < kb; i++) {
- int r = rand();
+ int r;
+ do
+ r = rand();
+ while (IsBug1156(r)); // Temporary workaround for https://sf.net/p/nsis/bugs/1156/#zlibCompressionTest loops endlessly
for (size_t j = 0; j < 1024/sizeof(int); j++) {
buf.add(&r, sizeof(int));
}
@@ -89,11 +93,13 @@ public:
CPPUNIT_ASSERT_EQUAL( C_OK, compressor.Init(9, 1 << 23) );
testCompressDecompress(1024, compressor, decompressor);
+#ifndef NSIS_TESTS_FASTCOMPRESSIONONLY
CPPUNIT_ASSERT_EQUAL( C_OK, compressor.Init(9, 1 << 23) );
testCompressDecompress(8*1024, compressor, decompressor);
CPPUNIT_ASSERT_EQUAL( C_OK, compressor.Init(9, 1 << 23) );
testCompressDecompress(32*1024, compressor, decompressor);
+#endif
}
};
diff --git a/Source/Tests/mmap.cpp b/Source/Tests/mmap.cpp
index 8e04b5e..9ed0e5b 100755
--- a/Source/Tests/mmap.cpp
+++ b/Source/Tests/mmap.cpp
@@ -9,11 +9,10 @@
using namespace std; // for std::min
-int g_display_errors = 1;
-FILE *g_output = stderr;
void quit() {
- _ftprintf(g_output, _T("MMap quit\n"));
+ extern FILE *g_errout;
+ _ftprintf(g_errout, _T("MMap quit\n"));
}
class MMapTest : public CppUnit::TestFixture {
diff --git a/Source/Tests/textrunner.cpp b/Source/Tests/textrunner.cpp
index 171a578..9f116fa 100755
--- a/Source/Tests/textrunner.cpp
+++ b/Source/Tests/textrunner.cpp
@@ -1,9 +1,14 @@
#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
+#include "../util.h" // for NSISRT_*
+
+NSISRT_DEFINEGLOBALS();
int main(int argc, char* argv[])
{
+ if (!NSISRT_Initialize()) return 1;
+
// Get the top level suite from the registry
CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
diff --git a/Source/Tests/winchar.cpp b/Source/Tests/winchar.cpp
index 6fdb3bc..bd6b780 100755
--- a/Source/Tests/winchar.cpp
+++ b/Source/Tests/winchar.cpp
@@ -28,22 +28,21 @@ class WinCharTest : public CppUnit::TestFixture {
public:
void setUp() {
- NSISRT_Initialize();
}
void testFromTchar() {
WINWCHAR test[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 };
WINWCHAR *dyn = WinWStrDupFromTChar(_T("test"));
- CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, 5) );
+ CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, sizeof(test)) );
free(dyn);
dyn = WinWStrDupFromChar("test");
- CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, 5) );
+ CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, sizeof(test)) );
free(dyn);
dyn = WinWStrDupFromWC(L"test");
- CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, 5) );
+ CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, sizeof(test)) );
free(dyn);
}
diff --git a/Source/build.cpp b/Source/build.cpp
index 44689e9..639951d 100755
--- a/Source/build.cpp
+++ b/Source/build.cpp
@@ -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)
{
TCHAR *p = line.gettoken_str(token);
diff --git a/Source/build.h b/Source/build.h
index 1be2979..d08399e 100755
--- a/Source/build.h
+++ b/Source/build.h
@@ -82,12 +82,13 @@ namespace MakensisAPI {
};
#ifdef _WIN32
enum sndmsg_e {
- QUERYHOST = WM_APP // QUERYHOST_e in wParam
+ QUERYHOST = WM_APP // [0x03000000] QUERYHOST_e in wParam. MUST return 0 for unknown QUERYHOST_e values!
};
+#endif
enum QUERYHOST_e {
- QH_OUTPUTCHARSET = 1 // return (wincodepage+1) or 0 for default (This encoding is used by stdout and the notify messages)
+ QH_OUTPUTCHARSET = 1, // [0x03000000] return (wincodepage+1) or 0 for default (This encoding is used by stdout, stderr and the notify messages)
+ QH_ENABLESTDERR // [0x03001000] return 1 to output error messages to stderr or 0 to output error messages to stdout
};
-#endif
}
#define PAGE_CUSTOM 0
@@ -410,6 +411,7 @@ class CEXEBuild {
int disable_window_icon;
// User variables stuff
+ int GetUnsafeUserVarIndex(LineParser &line, int token);
int GetUserVarIndex(LineParser &line, int token);
// Added by ramon 3 jun 2003
UserVarsStringList m_UserVarNames;
diff --git a/Source/exehead/Ui.c b/Source/exehead/Ui.c
index 5a02104..6e6b3bf 100755
--- a/Source/exehead/Ui.c
+++ b/Source/exehead/Ui.c
@@ -232,7 +232,7 @@ FORCE_INLINE int NSISCALL ui_doinstall(void)
// detect default language
// more information at:
- // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_0xrn.asp
+ // https://web.archive.org/web/20060618155426/http://msdn.microsoft.com/library/en-us/intl/nls_0xrn.asp
LANGID (WINAPI *GUDUIL)();
diff --git a/Source/exehead/exec.c b/Source/exehead/exec.c
index a30e345..6d5702b 100755
--- a/Source/exehead/exec.c
+++ b/Source/exehead/exec.c
@@ -122,12 +122,23 @@ void NSISCALL update_status_text_buf1(int strtab)
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 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
// 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;
case EW_ASSIGNVAR:
{
- int newlen=GetIntFromParm(2);
- int start=GetIntFromParm(3);
- int l;
- TCHAR *p=var0;
- TCHAR *buf0=GetStringFromParm(0x01);
+ LARGE_INTEGER newlenex=GetIntFromParmEx(2);
+ int start=GetIntFromParm(3), newlen=newlenex.LowPart;
+ TCHAR *p=var0, *buf0=GetStringFromParm(0x01);
+ int srclen=mystrlen(buf0);
*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=l+start;
+ if (start<0) start=srclen+start;
if (start>=0)
{
- if (start>l) start=l;
+ if (start>srclen) start=srclen;
mystrcpy(p,buf0+start);
if (newlen)
{
@@ -1702,10 +1711,12 @@ static int NSISCALL ExecuteEntry(entry *entry_)
#ifdef NSIS_LOCKWINDOW_SUPPORT
case EW_LOCKWINDOW:
{
- // ui_dlg_visible is 1 or 0, so is parm0
+ // ui_dlg_visible is 1 or 0, so is parm0. It is used because WM_SETREDRAW will toggle WS_VISIBLE!
+ // BUGBUG: This has unfortunate consequences when used in
+ // combination with BringToFront on the first page.
+ // See http://forums.winamp.com/showthread.php?t=397781 for details.
SendMessage(g_hwnd, WM_SETREDRAW, parm0 & ui_dlg_visible, 0);
- if ( parm0 )
- InvalidateRect(g_hwnd, NULL, FALSE);
+ if (parm0) InvalidateRect(g_hwnd, NULL, FALSE);
break;
}
#endif //NSIS_LOCKWINDOW_SUPPORT
diff --git a/Source/makenssi.cpp b/Source/makenssi.cpp
index 0a17290..2c3b4e2 100755
--- a/Source/makenssi.cpp
+++ b/Source/makenssi.cpp
@@ -36,14 +36,13 @@
using namespace std;
+NSISRT_DEFINEGLOBALS();
bool g_dopause=false, g_warnaserror=false;
-int g_display_errors=1;
-FILE *g_output;
NStreamEncoding g_outputenc;
#ifdef _WIN32
UINT g_wincon_orgoutcp;
#ifdef _UNICODE
-WINSIO_OSDATA g_osdata_stdout;
+WINSIO_OSDATA g_osdata_stdout, g_osdata_stderr;
#endif
#endif
const TCHAR *g_argv0=0;
@@ -71,7 +70,8 @@ static void myatexit()
{
dopause();
ResetPrintColor();
- if (g_output != stdout && g_output) fclose(g_output);
+ if (g_output != stdout && g_output) fclose(g_output), g_output = 0;
+ if (g_errout != stderr && g_errout) fclose(g_errout), g_errout = 0;
#ifdef _WIN32
SetConsoleOutputCP(g_wincon_orgoutcp);
#endif
@@ -108,7 +108,11 @@ static DWORD WINAPI sigint_event_msg_handler(LPVOID ThreadParam)
return 0;
}
-#endif
+
+static UINT_PTR QueryHost(HWND hHost, UINT_PTR wp, UINT_PTR lp=0, UINT_PTR def=0) { return hHost ? SendMessage(hHost, MakensisAPI::QUERYHOST, wp, lp) : def; }
+#else //! _WIN32
+static inline UINT_PTR QueryHost(HWND hHost, UINT_PTR wp, UINT_PTR lp=0, UINT_PTR def=0) { return def; }
+#endif //~ _WIN32
static void init_signals(HWND notify_hwnd)
{
@@ -285,6 +289,7 @@ static inline int makensismain(int argc, TCHAR **argv)
allow_unaligned_data_access();
#endif
assert(sizeof(UINT_PTR) == sizeof(void*));
+ assert('a' + 25 == 'z' && '0' < 'A' && 'A' < 'a'); // ASCII, do you speak it?
assert(sizeof(wchar_t) > 1 && sizeof(wchar_t) <= 4);
assert(sizeof(WINWCHAR) == 2 && sizeof(WORD) == 2);
assert(sizeof(WINWCHAR) == sizeof(WCHAR)); // Not really required but if WCHAR changes we need to know
@@ -293,7 +298,7 @@ static inline int makensismain(int argc, TCHAR **argv)
if (!NSISRT_Initialize())
{
- _ftprintf(stdout,_T("NSISRT_Initialize failed!\n"));
+ _ftprintf(stderr,_T("NSISRT_Initialize failed!\n"));
return 1;
}
@@ -301,11 +306,10 @@ static inline int makensismain(int argc, TCHAR **argv)
const TCHAR*stdoutredirname=0;
NStreamEncoding inputenc, &outputenc = g_outputenc;
int argpos=0;
- bool in_files=false;
- bool do_cd=true;
+ bool do_cd=true, noconfig=false;
bool no_logo=true;
- bool initialparsefail=false;
- bool noconfig=false;
+ bool initialparsefail=false, in_files=false;
+ bool oneoutputstream=false;
signed char pponly=0;
#ifdef _WIN32
signed char outputbom=1;
@@ -390,17 +394,23 @@ static inline int makensismain(int argc, TCHAR **argv)
FILE*stdoutredir=stdout;
if (stdoutredirname) stdoutredir=my_fopen(stdoutredirname,"w");
g_output=stdoutredir;
- if (!g_output) g_output=stdout;
+ if (!g_output)
+ g_output=stdout; // We could not open stdoutredirname, fall back to stdout
+ else if (stdoutredirname)
+ oneoutputstream=true; // -O used, put all output in the same file
+ if (oneoutputstream || !(1 & QueryHost(hostnotifyhandle,MakensisAPI::QH_ENABLESTDERR,0,1)))
+ g_errout=g_output;
#if defined(_WIN32) && defined(_UNICODE)
if (hostnotifyhandle)
{
// The host can override the output format if they want to
LPARAM lp=MAKELONG(outputenc.GetCodepage(),outputbom);
- LRESULT mr=SendMessage(hostnotifyhandle,MakensisAPI::QUERYHOST,MakensisAPI::QH_OUTPUTCHARSET,lp);
+ LRESULT mr=QueryHost(hostnotifyhandle,MakensisAPI::QH_OUTPUTCHARSET,lp);
if (mr) outputenc.SetCodepage((WORD)(--mr)), outputbom = -1;
}
- if (!WinStdIO_OStreamInit(g_osdata_stdout,g_output,outputenc.GetCodepage(),outputbom))
+ if (( !WinStdIO_OStreamInit(g_osdata_stdout,g_output,outputenc.GetCodepage(),outputbom))
+ || (g_errout != g_output && !WinStdIO_OStreamInit(g_osdata_stderr,g_errout,outputenc.GetCodepage(),outputbom)))
{
assert(!"StdIO init failed");
return 1;
diff --git a/Source/script.cpp b/Source/script.cpp
index bb390bc..f921d51 100755
--- a/Source/script.cpp
+++ b/Source/script.cpp
@@ -77,6 +77,36 @@ static UINT read_line_helper(NStreamLineReader&lr, TCHAR*buf, UINT cch)
return ++cch - eof;
}
+#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+static bool LookupWinSysColorId(const TCHAR*Str, UINT&Clr)
+{
+ static const struct { const TCHAR*Name; UINT Id; } map[] = { // Note: This list is incomplete.
+ { _T("WINDOW"), 5 }, { _T("WINDOWTEXT"), 8 },
+ { _T("3DFACE"), 15 }, { _T("BTNTEXT"), 18 }, // "Three-dimensional display elements and dialog box"
+ { _T("HIGHLIGHT"), 13 }, { _T("HIGHLIGHTTEXT"), 14 }, // "Item(s) selected in a control"
+ { _T("GRAYTEXT"), 17 }, // "Grayed (disabled) text"
+ { _T("HOTLIGHT"), 26 }, // "Color for a hyperlink or hot-tracked item" (Win98+)
+ };
+ for (UINT i = 0; i < COUNTOF(map); ++i)
+ if (!_tcsicmp(map[i].Name, Str)) return (Clr = map[i].Id, true);
+ return false;
+}
+static UINT ParseCtlColor(const TCHAR*Str, int&CCFlags, int CCFlagmask)
+{
+ UINT clr, v;
+ TCHAR buf[7+!0], *pEnd;
+ my_strncpy(buf, Str, 7+!0), buf[7] = '\0';
+ if (!_tcscmp(_T("SYSCLR:"), buf))
+ {
+ CCFlags |= ((CC_TEXT_SYS|CC_BK_SYS) & CCFlagmask); // ExeHead must call GetSysColor
+ if (!LookupWinSysColorId(Str+7, clr)) clr = _tcstoul(Str+7, &pEnd, 0);
+ }
+ else
+ v = _tcstoul(Str, &pEnd, 16), clr = ((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16);
+ return clr;
+}
+#endif
+
#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
// Added by Sunil Kamath 11 June 2003
TCHAR *CEXEBuild::set_file_predefine(const TCHAR *filename)
@@ -3205,7 +3235,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
case 1: comp=4; break;
case 2: comp=5, validparams=!!*(define=line.gettoken_str(2)); break;
case 3: cmpv=line.gettoken_int(3,&validparams); break;
- default: comp=-1;
+ default: forceutf8=comp=-1;
}
if (!validparams || comp == -1) PRINTHELP()
tstring compile;
@@ -4458,69 +4488,41 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
ent.which=EW_SETCTLCOLORS;
ent.offsets[0]=add_string(line.gettoken_str(1));
ctlcolors c={0, };
- int a = 2;
- if (!_tcsicmp(line.gettoken_str(2),_T("/BRANDING")))
- a++;
-
TCHAR *p;
- if (a == 2 && line.getnumtokens() == 5) {
+ int a = 2, ctok = line.getnumtokens();
+ if (!_tcsicmp(line.gettoken_str(2),_T("/BRANDING"))) a+=1;
+ if (!_tcsicmp(line.gettoken_str(2),_T("/RESET"))) { if (ctok != 3) return PS_ERROR; else a+=2; }
+ if (a == 2 && ctok == 5) {
ERROR_MSG(_T("Error: SetCtlColors expected 3 parameters, got 4\n"));
return PS_ERROR;
}
-
if (!_tcsicmp(line.gettoken_str(a+1),_T("transparent"))) {
- c.flags|=CC_BKB;
- c.lbStyle=BS_NULL;
- c.bkmode=TRANSPARENT;
+ c.flags|=CC_BKB, c.lbStyle=BS_NULL, c.bkmode=TRANSPARENT;
}
- else {
- p=line.gettoken_str(a+1);
- if (*p) {
- int v=_tcstoul(p,&p,16);
- c.bkc=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16);
- c.flags|=CC_BK|CC_BKB;
- }
- c.lbStyle=BS_SOLID;
- c.bkmode=OPAQUE;
- }
-
- p=line.gettoken_str(a);
- if (*p) {
- int v=_tcstoul(p,&p,16);
- c.text=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16);
- c.flags|=CC_TEXT;
+ else { // Parse background color
+ c.lbStyle=BS_SOLID, c.bkmode=OPAQUE;
+ if (*(p=line.gettoken_str(a+1)))
+ c.flags|=CC_BK|CC_BKB, c.bkc=ParseCtlColor(p, c.flags, CC_BK_SYS);
}
-
- if (a == 3)
- {
+ if (*(p=line.gettoken_str(a))) // Set text color?
+ c.flags|=CC_TEXT, c.text=ParseCtlColor(p, c.flags, CC_TEXT_SYS);
+ if (a == 3) { // Handle /BRANDING
c.flags|=CC_BK|CC_BKB;
c.lbStyle=BS_NULL;
- if (!*line.gettoken_str(a+1))
- {
- c.bkc=COLOR_BTNFACE;
- c.flags|=CC_BK_SYS;
- }
+ if (!*line.gettoken_str(a+1)) c.bkc=COLOR_BTNFACE, c.flags|=CC_BK_SYS;
c.flags|=CC_TEXT;
- if (!*line.gettoken_str(a))
- {
- c.text=COLOR_BTNFACE;
- c.flags|=CC_TEXT_SYS;
- }
+ if (!*line.gettoken_str(a)) c.text=COLOR_BTNFACE, c.flags|=CC_TEXT_SYS;
c.bkmode=OPAQUE;
}
-
+ if (a == 4) c.bkmode=OPAQUE, c.flags=0, c.bkb = 0; // Experimental and undocumented /RESET, a formal way of doing SetCtlColors $hCtl "" ""
assert(sizeof(ctlcolors64) > sizeof(ctlcolors));
int i, l=cur_ctlcolors->getlen()/sizeof(ctlcolors), pad=is_target_64bit()?sizeof(ctlcolors64)-sizeof(ctlcolors):0;
- for (i=0; i<l; i++) {
+ for (i=0; i<l; i++)
if (!memcmp((ctlcolors*)cur_ctlcolors->get()+i,&c,sizeof(ctlcolors))) {
ent.offsets[1]=i*(sizeof(ctlcolors)+pad);
break;
}
- }
- if (i>=l) {
- ent.offsets[1]=cur_ctlcolors->add(&c,sizeof(ctlcolors))+(l*pad);
- }
-
+ if (i>=l) ent.offsets[1]=cur_ctlcolors->add(&c,sizeof(ctlcolors))+(l*pad);
SCRIPT_MSG(_T("SetCtlColors: hwnd=%") NPRIs _T(" %") NPRIs _T("text=%") NPRIs _T(" background=%") NPRIs _T("\n"),line.gettoken_str(1),a==2?_T(""):_T("/BRANDING "),line.gettoken_str(a),line.gettoken_str(a+1));
}
return add_entry(&ent);
@@ -4599,8 +4601,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
ent.which=EW_SHOWWINDOW;
ent.offsets[0]=add_asciistring(_T("$HWNDPARENT"));
ent.offsets[1]=add_asciistring(_T("5")/*SW_SHOW*/);
- ret = add_entry(&ent);
- if (ret != PS_OK) return ret;
+ if ((ret = add_entry(&ent)) != PS_OK) return ret;
ent.which=EW_BRINGTOFRONT;
ent.offsets[0]=0;
ent.offsets[1]=0;
@@ -5041,22 +5042,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
const TCHAR* msgprefix = _T("");
int idx = -1;
if (TOK_STRCPY == which_token)
- {
idx = GetUserVarIndex(line, 1);
- }
else
- {
- 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);
- }
+ idx = GetUnsafeUserVarIndex(line, 1), msgprefix = _T("Unsafe");
if (idx < 0) PRINTHELP()
- ent.offsets[0]=idx;
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=add_string(line.gettoken_str(3));
- ent.offsets[3]=add_string(line.gettoken_str(4));
-
+ ent.offsets[0]=idx; // Destination variable
+ ent.offsets[1]=add_string(line.gettoken_str(2)); // Source string
+ ent.offsets[2]=add_string(line.gettoken_str(3)); // Optional MaxLen
+ 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"),
msgprefix,line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
return add_entry(&ent);
@@ -5080,11 +5073,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
return add_entry(&ent);
case TOK_GETCURRENTADDR:
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));
- if (ent.offsets[0] < 0) PRINTHELP()
- ent.offsets[2]=0;
- ent.offsets[3]=0;
+ ent.offsets[2]=ent.offsets[3]=0;
SCRIPT_MSG(_T("GetCurrentAddress: %") NPRIs _T("\n"),line.gettoken_str(1));
return add_entry(&ent);
case TOK_STRCMP:
@@ -5107,18 +5098,13 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
return PS_ERROR;
}
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[2]=0;
- ent.offsets[3]=0;
- if (ent.offsets[0]<0) PRINTHELP()
- add_entry(&ent);
-
- ent.offsets[0]=GetUserVarIndex(line, 3);
+ ent.offsets[2]=ent.offsets[3]=0;
+ if (PS_OK != add_entry(&ent)) return PS_ERROR;
+ if ((ent.offsets[0]=GetUserVarIndex(line, 3)) < 0) PRINTHELP()
ent.offsets[1]=add_intstring(low);
- ent.offsets[2]=0;
- ent.offsets[3]=0;
- if (ent.offsets[0]<0) PRINTHELP()
+ ent.offsets[2]=ent.offsets[3]=0;
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));
}
@@ -5152,22 +5138,16 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
unsigned long long ll = (st.st_mtime * 10000000LL) + 116444736000000000LL;
high = (DWORD) (ll >> 32), low = (DWORD) ll;
#endif
-
ent.which=EW_ASSIGNVAR;
- ent.offsets[0]=GetUserVarIndex(line, 2);
+ if ((ent.offsets[0]=GetUserVarIndex(line, 2)) < 0) PRINTHELP()
wsprintf(buf,_T("%u"),high);
ent.offsets[1]=add_string(buf);
- ent.offsets[2]=0;
- ent.offsets[3]=0;
- if (ent.offsets[0]<0) PRINTHELP()
- add_entry(&ent);
-
- ent.offsets[0]=GetUserVarIndex(line, 3);
+ ent.offsets[2]=ent.offsets[3]=0;
+ if (PS_OK != add_entry(&ent)) return PS_ERROR;
+ if ((ent.offsets[0]=GetUserVarIndex(line, 3)) < 0) PRINTHELP()
wsprintf(buf,_T("%u"),low);
ent.offsets[1]=add_string(buf);
- ent.offsets[2]=0;
- ent.offsets[3]=0;
- if (ent.offsets[0]<0) PRINTHELP()
+ ent.offsets[2]=ent.offsets[3]=0;
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));
}
@@ -6147,7 +6127,6 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
PRINTHELP();
case TOK__PLUGINCOMMAND:
{
- int ret;
tstring command, dllPath;
if (!m_pPlugins->GetCommandInfo(line.gettoken_str(0), command, dllPath))
@@ -6157,17 +6136,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
}
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;
// Initialize $PLUGINSDIR
ent.which=EW_CALL;
ent.offsets[0]=ns_func.add(uninstall_mode?_T("un.Initialize_____Plugins"):_T("Initialize_____Plugins"),0);
- ret=add_entry(&ent);
- if (ret != PS_OK) {
- return ret;
- }
+ if ((ret=add_entry(&ent)) != PS_OK) return ret;
// DLL name on the users machine
TCHAR tempDLL[NSIS_MAX_STRLEN];
@@ -6215,17 +6191,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
ent.offsets[3]=0xffffffff;
ent.offsets[4]=0xffffffff;
ent.offsets[5]=DefineInnerLangString(NLF_FILE_ERROR);
- ret=add_entry(&ent);
- if (ret != PS_OK) {
- return ret;
- }
+ if ((ret=add_entry(&ent)) != PS_OK) return ret;
}
// SetDetailsPrint lastused
ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), 0, 1);
- if (ret != PS_OK) {
- return ret;
- }
+ if (ret != PS_OK) return ret;
// Call the DLL
tstring funcname = get_string_suffix(command, _T("::"));
@@ -6234,8 +6205,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
int i = 1;
int nounload = 0;
if (!_tcsicmp(line.gettoken_str(i), _T("/NOUNLOAD"))) {
- i++;
- nounload++;
+ i++, nounload++;
}
// First push dll args
@@ -6249,10 +6219,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
if (!_tcsicmp(line.gettoken_str(w), _T("/NOUNLOAD"))) nounloadmisused=1;
ent.offsets[1]=0;
ent.offsets[2]=0;
- ret=add_entry(&ent);
- if (ret != PS_OK) {
- return ret;
- }
+ if ((ret=add_entry(&ent)) != PS_OK) return ret;
SCRIPT_MSG(_T(" %") NPRIs,line.gettoken_str(i));
}
SCRIPT_MSG(_T("\n"));
@@ -6266,10 +6233,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
ent.offsets[2]=0;
ent.offsets[3]=nounload|build_plugin_unload;
ent.offsets[4]=1;
- ret=add_entry(&ent);
- if (ret != PS_OK) {
- return ret;
- }
+ if ((ret=add_entry(&ent)) != PS_OK) return ret;
DefineInnerLangString(NLF_SYMBOL_NOT_FOUND);
DefineInnerLangString(NLF_COULD_NOT_LOAD);
@@ -6286,8 +6250,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
// Call [un.]Initialize_____Plugins
ent.which=EW_CALL;
ent.offsets[0]=ns_func.add(uninstall_mode?_T("un.Initialize_____Plugins"):_T("Initialize_____Plugins"),0);
- ret=add_entry(&ent);
- if (ret != PS_OK) return ret;
+ if ((ret=add_entry(&ent)) != PS_OK) return ret;
// SetDetailsPrint lastused
ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), 0, 1);
if (ret != PS_OK) return ret;
@@ -6297,9 +6260,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
case TOK_PLUGINDIR:
case TOK__PLUGINCOMMAND:
case TOK_INITPLUGINSDIR:
- {
ERROR_MSG(_T("Error: %") NPRIs _T(" specified, NSIS_CONFIG_PLUGIN_SUPPORT not defined.\n"),line.gettoken_str(0));
- }
return PS_ERROR;
#endif// NSIS_CONFIG_PLUGIN_SUPPORT
@@ -6308,8 +6269,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
SCRIPT_MSG(_T("LockWindow: lock state=%d\n"),line.gettoken_str(1));
ent.which=EW_LOCKWINDOW;
ent.offsets[0]=line.gettoken_enum(1,_T("on\0off\0"));
- if (ent.offsets[0] == -1)
- PRINTHELP();
+ if (ent.offsets[0] == -1) PRINTHELP();
return add_entry(&ent);
#else
case TOK_LOCKWINDOW:
diff --git a/Source/utf.cpp b/Source/utf.cpp
index 8d0f842..7658552 100755
--- a/Source/utf.cpp
+++ b/Source/utf.cpp
@@ -33,6 +33,9 @@ bool StrSetUTF16LE(tstring&dest, const void*src)
src = (const void*) cec.Convert(src);
if (!src) return false;
#endif
+#ifdef C_ASSERT
+ C_ASSERT(sizeof(tstring::value_type) >= sizeof(wchar_t));
+#endif
try { dest = (wchar_t*) src; } catch(...) { return false; }
return true;
}
diff --git a/Source/util.cpp b/Source/util.cpp
index 43e6ac1..13c0926 100755
--- a/Source/util.cpp
+++ b/Source/util.cpp
@@ -56,7 +56,7 @@ namespace Apple { // defines struct section
using namespace std;
extern int g_display_errors;
-extern FILE *g_output;
+extern FILE *g_output, *g_errout;
double my_wtof(const wchar_t *str)
{
@@ -203,7 +203,7 @@ static char g_nrt_iconv_narrowlocbuf[50], *g_nrt_iconv_narrowloc = 0;
#ifdef HAVE_LANGINFO_H // BUGBUG: scons needs to check for HAVE_LANGINFO_H and HAVE_NL_LANGINFO support?
#include <langinfo.h>
#endif
-bool NSISRT_Initialize()
+bool NSISRT_Initialize() // Init function for POSIX
{
iconvdescriptor id;
g_nrt_iconv_narrowloc = const_cast<char*>(""); // Use "" and not "char", "char" is a GNU extension?
@@ -1019,7 +1019,13 @@ bool GetFileSize64(HANDLE hFile, ULARGE_INTEGER &uli)
uli.LowPart = GetFileSize(hFile, &uli.HighPart);
return INVALID_FILE_SIZE != uli.LowPart || !GetLastError();
}
-#endif
+static HANDLE NSISRT_GetConsoleScreenHandle()
+{
+ DWORD cm;
+ HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
+ return GetConsoleMode(hCon, &cm) ? hCon : GetStdHandle(STD_ERROR_HANDLE);
+}
+#endif //~ _WIN32
#if defined(_WIN32) && defined(_UNICODE) && defined(MAKENSIS)
#include <io.h> // for _get_osfhandle
bool WINAPI WinStdIO_OStreamInit(WINSIO_OSDATA&osd, FILE*strm, WORD cp, int bom)
@@ -1073,17 +1079,23 @@ end:
strm.Detach();
return retval;
}
+static WINSIO_OSDATA*WinStdIO_GetNativeStreamData(FILE*strm)
+{
+ extern WINSIO_OSDATA g_osdata_stdout, g_osdata_stderr;
+ if (g_output == strm) return &g_osdata_stdout;
+ return g_errout == strm ? &g_osdata_stderr : NULL;
+}
int WINAPI WinStdIO_vfwprintf(FILE*strm, const wchar_t*Fmt, va_list val)
{
- if (g_output == strm && Fmt)
+ WINSIO_OSDATA*pOSD;
+ if (Fmt && (pOSD = WinStdIO_GetNativeStreamData(strm)))
{
- extern WINSIO_OSDATA g_osdata_stdout;
ExpandoString<wchar_t, NSIS_MAX_STRLEN> buf;
errno = ENOMEM;
const size_t cchfmt = buf.StrFmt(Fmt, val, false);
UINT cch = (UINT) cchfmt;
assert(sizeof(size_t) <= 4 || cchfmt == cch);
- if (cch && !WinStdIO_OStreamWrite(g_osdata_stdout, buf, cch))
+ if (cch && !WinStdIO_OStreamWrite(*pOSD, buf, cch))
{
cch = 0, errno = EIO;
}
@@ -1107,12 +1119,36 @@ int WinStdIO_wprintf(const wchar_t*Fmt, ...)
va_end(val);
return rv;
}
+static HANDLE NSISRT_FastGetConsoleScreenHandle()
+{
+ extern WINSIO_OSDATA g_osdata_stdout, g_osdata_stderr;
+ return WinStdIO_IsConsole(g_osdata_stdout) ? g_osdata_stdout.hNative : g_osdata_stderr.hNative;
+}
+bool NSISRT_Initialize() // Init function for MakeNSIS Win32
+{
+ static bool inited = false;
+ if (inited) return inited;
+ extern WINSIO_OSDATA g_osdata_stdout, g_osdata_stderr;
+ g_osdata_stderr.mode = g_osdata_stdout.mode = 0, g_osdata_stderr.hNative = g_osdata_stdout.hNative = 0;
+ return (inited = true);
+}
+#elif defined(_WIN32)
+#define NSISRT_FastGetConsoleScreenHandle NSISRT_GetConsoleScreenHandle
+bool NSISRT_Initialize() { return true; } // Init function for non-MakeNSIS Win32 (NSISRT_DEFINEGLOBALS sets g_output and g_errout)
#endif
+void PrintColorFmtErrMsg(const TCHAR *fmtstr, va_list args)
+{
+ PrintColorFmtMsg_WARN(_T("")); // flush g_output
+ SetPrintColorERR();
+ _vftprintf(g_errout, fmtstr, args), fflush(g_errout);
+ ResetPrintColor();
+}
+
void PrintColorFmtMsg(unsigned int type, const TCHAR *fmtstr, va_list args)
{
#ifdef _WIN32
- const HANDLE hWin32Con = GetStdHandle(STD_OUTPUT_HANDLE);
+ HANDLE hWin32Con = NSISRT_FastGetConsoleScreenHandle();
static INT32 contxtattrbak = -1;
WORD txtattr = 0;
if (contxtattrbak < 0)
diff --git a/Source/util.h b/Source/util.h
index ea148ce..eddd49e 100755
--- a/Source/util.h
+++ b/Source/util.h
@@ -105,6 +105,8 @@ public:
int sane_system(const TCHAR *command);
+#define NSISRT_DEFINEGLOBALS() int g_display_errors=1; FILE *g_output=stdout, *g_errout=stderr
+void PrintColorFmtErrMsg(const TCHAR *fmtstr, va_list args);
void PrintColorFmtMsg(unsigned int type, const TCHAR *fmtstr, va_list args);
void FlushOutputAndResetPrintColor();
#ifdef _WIN32
@@ -161,11 +163,12 @@ inline void PrintColorFmtMsg_ERR(const TCHAR *fmtstr, ...)
{
va_list val;
va_start(val,fmtstr);
- PrintColorFmtMsg(2, fmtstr, val);
+ PrintColorFmtErrMsg(fmtstr, val);
va_end(val);
}
+bool NSISRT_Initialize();
#ifndef _WIN32
// iconv const inconsistency workaround by Alexandre Oliva
template <typename T>
@@ -233,7 +236,6 @@ BOOL IsValidCodePage(UINT CodePage);
#else
#define CharNext CharNextA
#endif
-bool NSISRT_Initialize();
#define NSISRT_free(p) ( free((void*)(p)) )
wchar_t* NSISRT_mbtowc(const char *Str);
char* NSISRT_wctomb(const wchar_t *Str);
@@ -260,8 +262,6 @@ int my_open(const TCHAR *pathname, int flags);
#else // _WIN32
-#define NSISRT_Initialize() (true)
-
#define my_convert(x) (x)
#define my_convert_free(x)
diff --git a/Source/winchar.cpp b/Source/winchar.cpp
index 0e11c6f..864b386 100755
--- a/Source/winchar.cpp
+++ b/Source/winchar.cpp
@@ -46,7 +46,7 @@ int WinWStrNICmpASCII(const WINWCHAR *a, const char *b, size_t n)
WINWCHAR* WinWStrDupFromChar(const char *s, unsigned int cp)
{
int cch = MultiByteToWideChar(cp, 0, s, -1, 0, 0);
- wchar_t *p = (wchar_t*) malloc(cch);
+ wchar_t *p = (wchar_t*) malloc(cch * sizeof(wchar_t));
if (p)
{
MultiByteToWideChar(cp, 0, s, -1, p, cch);
@@ -111,7 +111,7 @@ WINWCHAR* WinWStrDupFromWC(const wchar_t *s)
// NOTE: Anything outside the ASCII range will not convert correctly!
size_t cch = wcslen(s);
WINWCHAR* p = (WINWCHAR*) malloc(++cch * 2);
- if (p) for (size_t i = 0; i < cch; ++i) p[i] = (unsigned char) s[i];
+ if (p) for (size_t i = 0; i < cch; ++i) p[i] = FIX_ENDIAN_INT16(s[i]);
return p;
#endif
}