diff --git a/Docs/src/history.but b/Docs/src/history.but index 6e60ac3a..5bce35b9 100644 --- a/Docs/src/history.but +++ b/Docs/src/history.but @@ -36,6 +36,8 @@ ANSI targets are deprecated, consider moving to Unicode. \b Zero uninitialized data in icon group (\W{http://sf.net/p/nsis/bugs/1230}{bug #1230}) +\b Automatically doubles ampersands in the name attribute + \S2{} Translations \b Updated Hindi (\W{http://sf.net/p/nsis/patches/291}{patch #291}) and Portuguese (\W{http://sf.net/p/nsis/bugs/1219}{bug #1219}) diff --git a/Source/build.h b/Source/build.h index 465435a0..14868f92 100644 --- a/Source/build.h +++ b/Source/build.h @@ -508,7 +508,7 @@ class CEXEBuild { * a PS_ERROR. If this function call is overwriting a set user string, * this will return a PS_WARNING. */ - int SetInnerString(int id, TCHAR *str); + int SetInnerString(int id, const TCHAR *str); int GenerateLangTable(LanguageTable *lt, int num_lang_tables); int GenerateLangTables(); diff --git a/Source/lang.cpp b/Source/lang.cpp index 190a11ce..72ebea2d 100644 --- a/Source/lang.cpp +++ b/Source/lang.cpp @@ -517,7 +517,7 @@ int CEXEBuild::SetLangString(const TCHAR *name, LANGID lang, const TCHAR *str) // @return If the id is invalid or the string is not valid, it will return a // PS_ERROR. If this function call is overwriting a set user string, this // will return a PS_WARNING. -int CEXEBuild::SetInnerString(int id, TCHAR *str) { +int CEXEBuild::SetInnerString(int id, const TCHAR *str) { if ((unsigned int)id >= NLF_STRINGS || !str) return PS_ERROR; int ret = PS_OK; diff --git a/Source/script.cpp b/Source/script.cpp index e7413425..7f008d06 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -1279,7 +1279,10 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { if (SetInnerString(NLF_NAME,line.gettoken_str(1)) == PS_WARNING) warning_fl(DW_INNERSTRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); - SetInnerString(NLF_NAME_DA,line.gettoken_str(2)); + tstring da; + const TCHAR *normstr = line.gettoken_str(1), *dastr = line.gettoken_str(2); + if (!*dastr && _tcschr(normstr,_T('&'))) dastr = (da = replace_all(normstr,_T("&"),_T("&&"))).c_str(); + SetInnerString(NLF_NAME_DA,dastr); SCRIPT_MSG(_T("Name: \"%") NPRIs _T("\""),line.gettoken_str(1)); if (*line.gettoken_str(2)) SCRIPT_MSG(_T(" \"%") NPRIs _T("\""),line.gettoken_str(2)); diff --git a/Source/util.cpp b/Source/util.cpp index 35223e56..e55d1732 100644 --- a/Source/util.cpp +++ b/Source/util.cpp @@ -880,6 +880,16 @@ bool IsWindowsPathRelative(const TCHAR *p) return PathGetDosDriveNumber(p) < 0; } +tstring replace_all(const TCHAR *str, const TCHAR *find, const TCHAR *repl) +{ + tstring out = str; + for (size_t cchF = _tcslen(find), cchR = _tcslen(repl), i = 0; ; i += cchR) + if ((i = out.find(find, i)) == tstring::npos) + return out; + else + out.replace(i, cchF, repl); +} + struct ToLower { TCHAR operator() (TCHAR c) const { return _totlower(c); } diff --git a/Source/util.h b/Source/util.h index c4694212..4b860e56 100644 --- a/Source/util.h +++ b/Source/util.h @@ -60,6 +60,7 @@ inline tstring& path_append(tstring& base, const tstring& more) { return path_ap inline bool IsAgnosticPathSeparator(const TCHAR c) { return _T('\\') == c || _T('/') == c; } bool IsWindowsPathRelative(const TCHAR *p); +tstring replace_all(const TCHAR*str, const TCHAR*find, const TCHAR* replace); tstring lowercase(const tstring&); tstring get_string_prefix(const tstring& str, const tstring& separator); tstring get_string_suffix(const tstring& str, const tstring& separator);