From e8db035a263758a30a429bc6a803799df1339e07 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Mon, 17 Feb 2020 08:43:25 +0100 Subject: [PATCH 1/5] + chg: INI file read/write using synchronous file locking (shared read / exclusive write) --- Versions/build.txt | 2 +- Versions/day.txt | 2 +- minipath/src/SimpleIni.h | 169 ++++++++++++++++++++++++++++++++- np3portableapp/_buildname.txt | 2 +- res/Notepad3.exe.manifest.conf | 4 +- src/Config/SimpleIni.h | 69 ++++++-------- src/VersionEx.h | 6 +- 7 files changed, 204 insertions(+), 50 deletions(-) diff --git a/Versions/build.txt b/Versions/build.txt index 0cfbf0888..d00491fd7 100644 --- a/Versions/build.txt +++ b/Versions/build.txt @@ -1 +1 @@ -2 +1 diff --git a/Versions/day.txt b/Versions/day.txt index a817176f4..0ddd619ce 100644 --- a/Versions/day.txt +++ b/Versions/day.txt @@ -1 +1 @@ -216 +217 diff --git a/minipath/src/SimpleIni.h b/minipath/src/SimpleIni.h index 678038830..0f5f4d906 100644 --- a/minipath/src/SimpleIni.h +++ b/minipath/src/SimpleIni.h @@ -294,6 +294,7 @@ enum class SI_Error : int { #if defined(_WIN32) # define SI_HAS_WIDE_FILE +# define SI_USE_LOCKING_WIDE_FILE # define SI_WCHAR_T wchar_t #elif defined(SI_CONVERT_ICU) # define SI_HAS_WIDE_FILE @@ -412,10 +413,29 @@ public: fputs(a_pBuf, m_file); } private: + FileWriter() = delete; FileWriter(const FileWriter &); // disable FileWriter & operator=(const FileWriter &); // disable }; +#ifdef SI_USE_LOCKING_WIDE_FILE + class FileHndlWriter : public OutputWriter { + HANDLE m_file; + public: + FileHndlWriter(HANDLE a_file) : m_file(a_file) {}; + ~FileHndlWriter() { FlushFileBuffers(m_file); } + void Write(const char* a_pBuf) override { + DWORD nBytesWritten = 0UL; + DWORD const nBytesToWrite = static_cast(strlen(a_pBuf)); + WriteFile(m_file, a_pBuf, nBytesToWrite, &nBytesWritten, NULL); + } + private: + FileHndlWriter() = delete; + FileHndlWriter(const FileHndlWriter&) = delete; // disable + FileHndlWriter& operator=(const FileHndlWriter&) = delete; // disable + }; +#endif + /** OutputWriter class to write the INI data to a string */ class StringWriter : public OutputWriter { std::string & m_string; @@ -610,9 +630,11 @@ public: @return SI_Error See error definitions */ - SI_Error LoadFile( - FILE * a_fpFile - ); +#ifdef SI_USE_LOCKING_WIDE_FILE + SI_Error LoadFile( HANDLE a_hFile, DWORD dwFileSize); +#else + SI_Error LoadFile( FILE * a_fpFile ); +#endif #ifdef SI_SUPPORT_IOSTREAMS /** Load INI file data from an istream. @@ -698,11 +720,17 @@ public: @return SI_Error See error definitions */ +#ifdef SI_USE_LOCKING_WIDE_FILE + SI_Error SaveFile( + HANDLE a_hFile, + bool a_bAddSignature = false + ) const; +#else SI_Error SaveFile( FILE * a_pFile, bool a_bAddSignature = false ) const; - +#endif /** Save the INI data. The data will be written to the output device in a format appropriate to the current data, selected by: @@ -1392,6 +1420,46 @@ CSimpleIniTempl::LoadFile( } #ifdef SI_HAS_WIDE_FILE + +#ifdef SI_USE_LOCKING_WIDE_FILE + +template +SI_Error +CSimpleIniTempl::LoadFile( + const SI_WCHAR_T* a_pwszFile +) +{ + HANDLE hFile = CreateFile(a_pwszFile, + GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + return SI_Error::SI_FILE; + } + + DWORD dwFileSizeHigh = 0UL; + DWORD const dwFileSize = GetFileSize(hFile, &dwFileSizeHigh); + if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSizeHigh != 0UL)) { + return SI_Error::SI_FILE; + } + + SI_Error rc = SI_Error::SI_FILE; + + DWORD const flags = 0UL; // SHARED READ(!) ~ LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK + OVERLAPPED OvrLpd = { 0 }; + + if (LockFileEx(hFile, flags, 0, dwFileSize, dwFileSizeHigh, &OvrLpd)) { + + rc = LoadFile(hFile, dwFileSize); + + UnlockFileEx(hFile, 0, dwFileSize, dwFileSizeHigh, &OvrLpd); + } + CloseHandle(hFile); + return rc; +} + +#else + template SI_Error CSimpleIniTempl::LoadFile( @@ -1415,8 +1483,43 @@ CSimpleIniTempl::LoadFile( return LoadFile(szFile); #endif // _WIN32 } + +#endif // SI_USE_LOCKING_WIDE_FILE + #endif // SI_HAS_WIDE_FILE + +#ifdef SI_USE_LOCKING_WIDE_FILE + +template +SI_Error +CSimpleIniTempl::LoadFile( + HANDLE a_hFile, DWORD dwFileSize +) +{ + // allocate and ensure NULL terminated + auto* pData = new(std::nothrow) char[dwFileSize + 1]; + if (!pData) { + return SI_Error::SI_NOMEM; + } + pData[dwFileSize] = '\0'; + + // load the raw file data + DWORD nBytesRead = 0UL; + BOOL const result = ReadFile(a_hFile, pData, dwFileSize, &nBytesRead, NULL); + if ((result == FALSE) || (nBytesRead != dwFileSize)) { + delete[] pData; + return SI_Error::SI_FILE; + } + + // convert the raw data to unicode + SI_Error const rc = LoadData(pData, (size_t)nBytesRead); + delete[] pData; + return rc; +} + +#else + template SI_Error CSimpleIniTempl::LoadFile( @@ -1457,6 +1560,8 @@ CSimpleIniTempl::LoadFile( return rc; } +#endif + template SI_Error CSimpleIniTempl::LoadData( @@ -2515,11 +2620,49 @@ CSimpleIniTempl::SaveFile( #endif // __STDC_WANT_SECURE_LIB__ if (!fp) return SI_FILE; SI_Error rc = SaveFile(fp, a_bAddSignature); + fflush(fp); fclose(fp); return rc; } #ifdef SI_HAS_WIDE_FILE + +#ifdef SI_USE_LOCKING_WIDE_FILE + +template +SI_Error +CSimpleIniTempl::SaveFile( + const SI_WCHAR_T* a_pwszFile, + bool a_bAddSignature +) const +{ + HANDLE hFile = CreateFile(a_pwszFile, + GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile == INVALID_HANDLE_VALUE) { + return SI_Error::SI_FILE; + } + + DWORD const flags = LOCKFILE_EXCLUSIVE_LOCK; // LOCK SHARED READ/WRITE(!) ~ LOCKFILE_FAIL_IMMEDIATELY + OVERLAPPED OvrLpd = { 0 }; + SI_Error rc = SI_Error::SI_FILE; + + if (LockFileEx(hFile, flags, 0, MAXDWORD, 0, &OvrLpd)) { + + rc = SaveFile(hFile, a_bAddSignature); + + FlushFileBuffers(hFile); + + UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd); + } + + CloseHandle(hFile); + return rc; +} + +#else + template SI_Error CSimpleIniTempl::SaveFile( @@ -2536,6 +2679,7 @@ CSimpleIniTempl::SaveFile( #endif // __STDC_WANT_SECURE_LIB__ if (!fp) return SI_Error::SI_FILE; SI_Error rc = SaveFile(fp, a_bAddSignature); + fflush(fp); fclose(fp); return rc; #else // !_WIN32 (therefore SI_CONVERT_ICU) @@ -2544,8 +2688,24 @@ CSimpleIniTempl::SaveFile( return SaveFile(szFile, a_bAddSignature); #endif // _WIN32 } + +#endif // SI_USE_LOCKING_WIDE_FILE + #endif // SI_HAS_WIDE_FILE + +#ifdef SI_USE_LOCKING_WIDE_FILE +template +SI_Error +CSimpleIniTempl::SaveFile( + HANDLE a_hFile, + bool a_bAddSignature +) const +{ + FileHndlWriter writer(a_hFile); + return Save(writer, a_bAddSignature); +} +#else template SI_Error CSimpleIniTempl::SaveFile( @@ -2556,6 +2716,7 @@ CSimpleIniTempl::SaveFile( FileWriter writer(a_pFile); return Save(writer, a_bAddSignature); } +#endif template SI_Error diff --git a/np3portableapp/_buildname.txt b/np3portableapp/_buildname.txt index 4fad18a3b..dffc957ee 100644 --- a/np3portableapp/_buildname.txt +++ b/np3portableapp/_buildname.txt @@ -1 +1 @@ -"RC1" +BETA diff --git a/res/Notepad3.exe.manifest.conf b/res/Notepad3.exe.manifest.conf index 6e1459e78..4df816877 100644 --- a/res/Notepad3.exe.manifest.conf +++ b/res/Notepad3.exe.manifest.conf @@ -3,8 +3,8 @@ - Notepad3 RC1 + Notepad3 BETA diff --git a/src/Config/SimpleIni.h b/src/Config/SimpleIni.h index 915f0acc3..0f5f4d906 100644 --- a/src/Config/SimpleIni.h +++ b/src/Config/SimpleIni.h @@ -294,7 +294,7 @@ enum class SI_Error : int { #if defined(_WIN32) # define SI_HAS_WIDE_FILE -//# define SI_USE_LOCKING_WIDE_FILE +# define SI_USE_LOCKING_WIDE_FILE # define SI_WCHAR_T wchar_t #elif defined(SI_CONVERT_ICU) # define SI_HAS_WIDE_FILE @@ -419,25 +419,20 @@ public: }; #ifdef SI_USE_LOCKING_WIDE_FILE - class FileWriterLocking : public OutputWriter { + class FileHndlWriter : public OutputWriter { HANDLE m_file; - LPOVERLAPPED m_pOvrLpd; public: - FileWriterLocking(HANDLE a_file, LPOVERLAPPED a_pOvrLpd) - : m_file(a_file) - , m_pOvrLpd(a_pOvrLpd) { } - ~FileWriterLocking() { - FlushFileBuffers(m_file); - } + FileHndlWriter(HANDLE a_file) : m_file(a_file) {}; + ~FileHndlWriter() { FlushFileBuffers(m_file); } void Write(const char* a_pBuf) override { DWORD nBytesWritten = 0UL; DWORD const nBytesToWrite = static_cast(strlen(a_pBuf)); - WriteFile(m_file, a_pBuf, nBytesToWrite, &nBytesWritten, m_pOvrLpd); + WriteFile(m_file, a_pBuf, nBytesToWrite, &nBytesWritten, NULL); } private: - FileWriterLocking() = delete; - FileWriterLocking(const FileWriterLocking&) = delete; // disable - FileWriterLocking& operator=(const FileWriterLocking&) = delete; // disable + FileHndlWriter() = delete; + FileHndlWriter(const FileHndlWriter&) = delete; // disable + FileHndlWriter& operator=(const FileHndlWriter&) = delete; // disable }; #endif @@ -636,7 +631,7 @@ public: @return SI_Error See error definitions */ #ifdef SI_USE_LOCKING_WIDE_FILE - SI_Error LoadFile( HANDLE a_hFile, DWORD dwFileSize, LPOVERLAPPED pOvrLpd); + SI_Error LoadFile( HANDLE a_hFile, DWORD dwFileSize); #else SI_Error LoadFile( FILE * a_fpFile ); #endif @@ -728,7 +723,6 @@ public: #ifdef SI_USE_LOCKING_WIDE_FILE SI_Error SaveFile( HANDLE a_hFile, - LPOVERLAPPED a_pOvrLpd, bool a_bAddSignature = false ) const; #else @@ -1448,16 +1442,18 @@ CSimpleIniTempl::LoadFile( if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSizeHigh != 0UL)) { return SI_Error::SI_FILE; } - - OVERLAPPED OvrLpd; ZeroMemory(&OvrLpd, sizeof(OVERLAPPED)); + + SI_Error rc = SI_Error::SI_FILE; DWORD const flags = 0UL; // SHARED READ(!) ~ LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK - LockFileEx(hFile, flags, 0, dwFileSize, dwFileSizeHigh, &OvrLpd); + OVERLAPPED OvrLpd = { 0 }; - SI_Error const rc = LoadFile(hFile, dwFileSize, &OvrLpd); + if (LockFileEx(hFile, flags, 0, dwFileSize, dwFileSizeHigh, &OvrLpd)) { - UnlockFileEx(hFile, 0, dwFileSize, dwFileSizeHigh, &OvrLpd); + rc = LoadFile(hFile, dwFileSize); + UnlockFileEx(hFile, 0, dwFileSize, dwFileSizeHigh, &OvrLpd); + } CloseHandle(hFile); return rc; } @@ -1498,7 +1494,7 @@ CSimpleIniTempl::LoadFile( template SI_Error CSimpleIniTempl::LoadFile( - HANDLE a_hFile, DWORD dwFileSize, LPOVERLAPPED pOvrLpd + HANDLE a_hFile, DWORD dwFileSize ) { // allocate and ensure NULL terminated @@ -1510,7 +1506,7 @@ CSimpleIniTempl::LoadFile( // load the raw file data DWORD nBytesRead = 0UL; - BOOL const result = ReadFile(a_hFile, pData, dwFileSize, &nBytesRead, pOvrLpd); + BOOL const result = ReadFile(a_hFile, pData, dwFileSize, &nBytesRead, NULL); if ((result == FALSE) || (nBytesRead != dwFileSize)) { delete[] pData; return SI_Error::SI_FILE; @@ -2642,27 +2638,25 @@ CSimpleIniTempl::SaveFile( { HANDLE hFile = CreateFile(a_pwszFile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return SI_Error::SI_FILE; } - DWORD dwFileSizeHigh = 0UL; - DWORD const dwFileSize = GetFileSize(hFile, &dwFileSizeHigh); - if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSizeHigh != 0UL)) { - return SI_Error::SI_FILE; + DWORD const flags = LOCKFILE_EXCLUSIVE_LOCK; // LOCK SHARED READ/WRITE(!) ~ LOCKFILE_FAIL_IMMEDIATELY + OVERLAPPED OvrLpd = { 0 }; + SI_Error rc = SI_Error::SI_FILE; + + if (LockFileEx(hFile, flags, 0, MAXDWORD, 0, &OvrLpd)) { + + rc = SaveFile(hFile, a_bAddSignature); + + FlushFileBuffers(hFile); + + UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd); } - OVERLAPPED OvrLpd; ZeroMemory(&OvrLpd, sizeof(OVERLAPPED)); - - DWORD const flags = 0UL; // SHARED READ(!) ~ LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK - LockFileEx(hFile, flags, 0, dwFileSize, dwFileSizeHigh, &OvrLpd); - - SI_Error const rc = SaveFile(hFile, &OvrLpd, a_bAddSignature); - - UnlockFileEx(hFile, 0, dwFileSize, dwFileSizeHigh, &OvrLpd); - CloseHandle(hFile); return rc; } @@ -2705,11 +2699,10 @@ template SI_Error CSimpleIniTempl::SaveFile( HANDLE a_hFile, - LPOVERLAPPED a_pOvrLpd, bool a_bAddSignature ) const { - FileWriterLocking writer(a_hFile, a_pOvrLpd); + FileHndlWriter writer(a_hFile); return Save(writer, a_bAddSignature); } #else diff --git a/src/VersionEx.h b/src/VersionEx.h index 0510c0026..c5d6ca0cc 100644 --- a/src/VersionEx.h +++ b/src/VersionEx.h @@ -8,12 +8,12 @@ #define SAPPNAME "Notepad3" #define VERSION_MAJOR 5 #define VERSION_MINOR 20 -#define VERSION_REV 216 -#define VERSION_BUILD 2 +#define VERSION_REV 217 +#define VERSION_BUILD 1 #define SCINTILLA_VER 430 #define ONIGURUMA_REGEX_VER 6.9.4 #define UCHARDET_VER 2018.09.27 #define TINYEXPR_VER 2018.05.11 #define UTHASH_VER 2.1.0 -#define VERSION_PATCH RC1 +#define VERSION_PATCH BETA #define VERSION_COMMIT_ID nebukadn From 27f56daf392a0558edbc11acd5b0cc1d33dd5810 Mon Sep 17 00:00:00 2001 From: RaiKoHoff Date: Mon, 17 Feb 2020 18:28:01 +0100 Subject: [PATCH 2/5] + chg: correct version numbering --- np3portableapp/_buildname.txt | 2 +- res/Notepad3.exe.manifest.conf | 2 +- src/VersionEx.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/np3portableapp/_buildname.txt b/np3portableapp/_buildname.txt index dffc957ee..4fad18a3b 100644 --- a/np3portableapp/_buildname.txt +++ b/np3portableapp/_buildname.txt @@ -1 +1 @@ -BETA +"RC1" diff --git a/res/Notepad3.exe.manifest.conf b/res/Notepad3.exe.manifest.conf index 4df816877..9f1f274ec 100644 --- a/res/Notepad3.exe.manifest.conf +++ b/res/Notepad3.exe.manifest.conf @@ -6,5 +6,5 @@ version="5.20.217.1" type="win32" /> - Notepad3 BETA + Notepad3 RC1 diff --git a/src/VersionEx.h b/src/VersionEx.h index c5d6ca0cc..e28d7bd83 100644 --- a/src/VersionEx.h +++ b/src/VersionEx.h @@ -15,5 +15,5 @@ #define UCHARDET_VER 2018.09.27 #define TINYEXPR_VER 2018.05.11 #define UTHASH_VER 2.1.0 -#define VERSION_PATCH BETA -#define VERSION_COMMIT_ID nebukadn +#define VERSION_PATCH RC1 +#define VERSION_COMMIT_ID t7820-rk From b1d65d7a4e3560212dc4f1e18eca4d9830f506c7 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Mon, 17 Feb 2020 23:33:38 +0100 Subject: [PATCH 3/5] + upd: Current (2020-02-17) oniguruma DEV --- oniguruma/README.md | 2 + oniguruma/doc/API | 45 ++++++++++-- oniguruma/src/oniguruma.h | 7 ++ oniguruma/src/regcomp.c | 46 +++++++----- oniguruma/src/regerror.c | 2 + oniguruma/src/regexec.c | 148 ++++++++++++++++++++++++++++++-------- oniguruma/src/regint.h | 11 ++- oniguruma/src/regparse.c | 2 +- 8 files changed, 207 insertions(+), 56 deletions(-) diff --git a/oniguruma/README.md b/oniguruma/README.md index b02a86b05..01900e1e8 100644 --- a/oniguruma/README.md +++ b/oniguruma/README.md @@ -30,6 +30,8 @@ Supported character encodings: Master branch ------------- +* NEW API: retry limit in search functions +* Limit on maximum nesting level of subexp call (16) * Fixed behavior of isolated options in Perl and Java syntaxes. /...(?i).../ diff --git a/oniguruma/doc/API b/oniguruma/doc/API index 43d53385a..c1fb2c991 100644 --- a/oniguruma/doc/API +++ b/oniguruma/doc/API @@ -1,4 +1,4 @@ -Oniguruma API Version 6.9.4 2019/09/30 +Oniguruma API Version 6.9.5 2020/02/13 #include @@ -273,6 +273,20 @@ Oniguruma API Version 6.9.4 2019/09/30 normal return: ONIG_NORMAL +# int onig_set_retry_limit_in_search_of_match_param(OnigMatchParam* mp, unsigned long limit) + + Set a retry limit count of a search process. + 0 means unlimited. + + If the value of this limit is not 0 and is smaller than the current value of the retry limit in match of mp, the value of retry limit in match is set to this limit. + + arguments + 1 mp: match-param pointer + 2 limit: number of limit + + normal return: ONIG_NORMAL + + # int onig_set_progress_callout_of_match_param(OnigMatchParam* mp, OnigCalloutFunc f) Set a function for callouts of contents in progress. @@ -333,7 +347,7 @@ Oniguruma API Version 6.9.4 2019/09/30 arguments 1-7: same as onig_search() - 8 mp: match parameter values (match_stack_limit, retry_limit_in_match) + 8 mp: match parameter values (match_stack_limit, retry_limit_in_match, retry_limit_in_search) # int onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at, @@ -368,7 +382,7 @@ Oniguruma API Version 6.9.4 2019/09/30 arguments 1-6: same as onig_match() - 7 mp: match parameter values (match_stack_limit, retry_limit_in_match) + 7 mp: match parameter values (match_stack_limit, retry_limit_in_match, retry_limit_in_search) # int onig_scan(regex_t* reg, const UChar* str, const UChar* end, @@ -866,19 +880,38 @@ Oniguruma API Version 6.9.4 2019/09/30 # unsigned long onig_get_retry_limit_in_match(void) - Return the limit of retry counts in matching process. + Return the limit of retry counts in a matching process. (default: 10000000) - normal return: limit value + normal return: current limit value -# int onig_set_retry_limit_in_match(unsigned long n) +# unsigned long onig_get_retry_limit_in_search(void) + + Return the limit of retry counts in a search process. + 0 means unlimited. + (default: 0) + + normal return: current limit value + + +# int onig_set_retry_limit_in_match(unsigned long limit) Set the limit of retry counts in matching process. normal return: ONIG_NORMAL +# int onig_set_retry_limit_in_search(unsigned long limit) + + Set a retry limit count of a search process. + 0 means unlimited. + + If the value of this limit is not 0 and is smaller than the current value of the retry limit in match, the value of retry limit in match is set to this limit. + + normal return: ONIG_NORMAL + + # OnigCalloutFunc onig_get_progress_callout(void) Get a function for callouts of contents in progress. diff --git a/oniguruma/src/oniguruma.h b/oniguruma/src/oniguruma.h index 1cf0963f7..aea8866bb 100644 --- a/oniguruma/src/oniguruma.h +++ b/oniguruma/src/oniguruma.h @@ -576,6 +576,7 @@ ONIG_EXTERN OnigSyntaxType* OnigDefaultSyntax; #define ONIGERR_MATCH_STACK_LIMIT_OVER -15 #define ONIGERR_PARSE_DEPTH_LIMIT_OVER -16 #define ONIGERR_RETRY_LIMIT_IN_MATCH_OVER -17 +#define ONIGERR_RETRY_LIMIT_IN_SEARCH_OVER -18 #define ONIGERR_DEFAULT_ENCODING_IS_NOT_SETTED -21 #define ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR -22 #define ONIGERR_FAIL_TO_INITIALIZE -23 @@ -924,6 +925,10 @@ unsigned long onig_get_retry_limit_in_match P_((void)); ONIG_EXTERN int onig_set_retry_limit_in_match P_((unsigned long n)); ONIG_EXTERN +unsigned long onig_get_retry_limit_in_search P_((void)); +ONIG_EXTERN +int onig_set_retry_limit_in_search P_((unsigned long n)); +ONIG_EXTERN unsigned int onig_get_parse_depth_limit P_((void)); ONIG_EXTERN int onig_set_capture_num_limit P_((int num)); @@ -952,6 +957,8 @@ int onig_set_match_stack_limit_size_of_match_param P_((OnigMatchParam* param, un ONIG_EXTERN int onig_set_retry_limit_in_match_of_match_param P_((OnigMatchParam* param, unsigned long limit)); ONIG_EXTERN +int onig_set_retry_limit_in_search_of_match_param P_((OnigMatchParam* param, unsigned long limit)); +ONIG_EXTERN int onig_set_progress_callout_of_match_param P_((OnigMatchParam* param, OnigCalloutFunc f)); ONIG_EXTERN int onig_set_retraction_callout_of_match_param P_((OnigMatchParam* param, OnigCalloutFunc f)); diff --git a/oniguruma/src/regcomp.c b/oniguruma/src/regcomp.c index 5f6cdda2d..4dbbd567a 100644 --- a/oniguruma/src/regcomp.c +++ b/oniguruma/src/regcomp.c @@ -408,12 +408,12 @@ onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag) } static int -int_multiply_cmp(int x, int y, int v) +len_multiply_cmp(OnigLen x, int y, OnigLen v) { if (x == 0 || y == 0) return -1; - if (x < INT_MAX / y) { - int xy = x * y; + if (x < INFINITE_LEN / y) { + OnigLen xy = x * (OnigLen )y; if (xy > v) return 1; else { if (xy == v) return 0; @@ -421,7 +421,7 @@ int_multiply_cmp(int x, int y, int v) } } else - return 1; + return v == INFINITE_LEN ? 0 : 1; } extern int @@ -429,7 +429,7 @@ onig_positive_int_multiply(int x, int y) { if (x == 0 || y == 0) return 0; - if (x < INT_MAX / y) + if (x < ONIG_INT_MAX / y) return x * y; else return -1; @@ -1394,7 +1394,7 @@ compile_length_quantifier_node(QuantNode* qn, regex_t* reg) /* anychar repeat */ if (is_anychar_infinite_greedy(qn)) { if (qn->lower <= 1 || - int_multiply_cmp(tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0) { + len_multiply_cmp((OnigLen )tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0) { if (IS_NOT_NULL(qn->next_head_exact)) return OPSIZE_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower; else @@ -1408,7 +1408,7 @@ compile_length_quantifier_node(QuantNode* qn, regex_t* reg) if (infinite && (qn->lower <= 1 || - int_multiply_cmp(tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { + len_multiply_cmp(tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { if (qn->lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) { len = OPSIZE_JUMP; } @@ -1439,7 +1439,7 @@ compile_length_quantifier_node(QuantNode* qn, regex_t* reg) } else if (!infinite && qn->greedy && (qn->upper == 1 || - int_multiply_cmp(tlen + OPSIZE_PUSH, qn->upper, + len_multiply_cmp((OnigLen )tlen + OPSIZE_PUSH, qn->upper, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { len = tlen * qn->lower; len += (OPSIZE_PUSH + tlen) * (qn->upper - qn->lower); @@ -1467,7 +1467,8 @@ compile_quantifier_node(QuantNode* qn, regex_t* reg, ScanEnv* env) if (is_anychar_infinite_greedy(qn) && (qn->lower <= 1 || - int_multiply_cmp(tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { + len_multiply_cmp((OnigLen )tlen, qn->lower, + QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { r = compile_tree_n_times(NODE_QUANT_BODY(qn), qn->lower, reg, env); if (r != 0) return r; if (IS_NOT_NULL(qn->next_head_exact)) { @@ -1491,7 +1492,8 @@ compile_quantifier_node(QuantNode* qn, regex_t* reg, ScanEnv* env) if (infinite && (qn->lower <= 1 || - int_multiply_cmp(tlen, qn->lower, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { + len_multiply_cmp((OnigLen )tlen, qn->lower, + QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { int addr; if (qn->lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) { @@ -1586,7 +1588,7 @@ compile_quantifier_node(QuantNode* qn, regex_t* reg, ScanEnv* env) } else if (! infinite && qn->greedy && (qn->upper == 1 || - int_multiply_cmp(tlen + OPSIZE_PUSH, qn->upper, + len_multiply_cmp((OnigLen )tlen + OPSIZE_PUSH, qn->upper, QUANTIFIER_EXPAND_LIMIT_SIZE) <= 0)) { int n = qn->upper - qn->lower; @@ -4826,11 +4828,13 @@ is_all_code_len_1_items(int n, OnigCaseFoldCodeItem items[]) } static int -get_min_max_byte_len_case_fold_items(int n, OnigCaseFoldCodeItem items[], int* rmin, int* rmax) +get_min_max_byte_len_case_fold_items(int n, OnigCaseFoldCodeItem items[], + OnigLen* rmin, OnigLen* rmax) { - int i, len, minlen, maxlen; + int i; + OnigLen len, minlen, maxlen; - minlen = INT_MAX; + minlen = INFINITE_LEN; maxlen = 0; for (i = 0; i < n; i++) { OnigCaseFoldCodeItem* item = items + i; @@ -4925,7 +4929,7 @@ unravel_cf_string_add(Node** rlist, Node** rsn, UChar* s, UChar* end, static int unravel_cf_string_alt_or_cc_add(Node** rlist, int n, - OnigCaseFoldCodeItem items[], int byte_len, OnigEncoding enc, + OnigCaseFoldCodeItem items[], OnigEncoding enc, OnigCaseFoldType case_fold_flag, UChar* s, UChar* end) { int r, i; @@ -4982,7 +4986,7 @@ unravel_cf_string_alt_or_cc_add(Node** rlist, int n, static int unravel_cf_look_behind_add(Node** rlist, Node** rsn, int n, OnigCaseFoldCodeItem items[], OnigEncoding enc, - UChar* s, int one_len) + UChar* s, OnigLen one_len) { int r, i, found; @@ -5028,7 +5032,8 @@ unravel_cf_look_behind_add(Node** rlist, Node** rsn, static int unravel_case_fold_string(Node* node, regex_t* reg, int state) { - int r, n, one_len, min_len, max_len, in_look_behind; + int r, n, in_look_behind; + OnigLen min_len, max_len, one_len; UChar *start, *end, *p, *q; StrNode* snode; Node *sn, *list; @@ -5056,7 +5061,7 @@ unravel_case_fold_string(Node* node, regex_t* reg, int state) goto err; } - one_len = enclen(enc, p); + one_len = (OnigLen )enclen(enc, p); if (n == 0) { q = p + one_len; r = unravel_cf_string_add(&list, &sn, p, q, 0 /* flag */); @@ -5082,7 +5087,7 @@ unravel_case_fold_string(Node* node, regex_t* reg, int state) } q = p + max_len; - r = unravel_cf_string_alt_or_cc_add(&list, n, items, max_len, enc, + r = unravel_cf_string_alt_or_cc_add(&list, n, items, enc, reg->case_fold_flag, p, q); if (r != 0) goto err; sn = NULL_NODE; @@ -7347,6 +7352,9 @@ onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end, #endif #ifdef USE_CALLOUT || (IS_NOT_NULL(reg->extp) && reg->extp->callout_num != 0) +#endif +#ifdef USE_CALL + || scan_env.num_call > 0 #endif ) reg->stack_pop_level = STACK_POP_LEVEL_ALL; diff --git a/oniguruma/src/regerror.c b/oniguruma/src/regerror.c index ab0decd67..e4e252cf1 100644 --- a/oniguruma/src/regerror.c +++ b/oniguruma/src/regerror.c @@ -55,6 +55,8 @@ onig_error_code_to_format(int code) p = "parse depth limit over"; break; case ONIGERR_RETRY_LIMIT_IN_MATCH_OVER: p = "retry-limit-in-match over"; break; + case ONIGERR_RETRY_LIMIT_IN_SEARCH_OVER: + p = "retry-limit-in-search over"; break; case ONIGERR_TYPE_BUG: p = "undefined type (bug)"; break; case ONIGERR_PARSER_BUG: diff --git a/oniguruma/src/regexec.c b/oniguruma/src/regexec.c index 76fd754fb..ad477c4b9 100644 --- a/oniguruma/src/regexec.c +++ b/oniguruma/src/regexec.c @@ -35,6 +35,10 @@ #include "regint.h" +#pragma warning( push ) +#pragma warning( disable : 4018 ) + + #define IS_MBC_WORD_ASCII_MODE(enc,s,end,mode) \ ((mode) == 0 ? ONIGENC_IS_MBC_WORD(enc,s,end) : ONIGENC_IS_MBC_WORD_ASCII(enc,s,end)) @@ -72,7 +76,10 @@ typedef struct { struct OnigMatchParamStruct { unsigned int match_stack_limit; +#ifdef USE_RETRY_LIMIT unsigned long retry_limit_in_match; + unsigned long retry_limit_in_search; +#endif #ifdef USE_CALLOUT OnigCalloutFunc progress_callout_of_contents; OnigCalloutFunc retraction_callout_of_contents; @@ -95,8 +102,27 @@ extern int onig_set_retry_limit_in_match_of_match_param(OnigMatchParam* param, unsigned long limit) { +#ifdef USE_RETRY_LIMIT param->retry_limit_in_match = limit; return ONIG_NORMAL; +#else + return ONIG_NO_SUPPORT_CONFIG; +#endif +} + +extern int +onig_set_retry_limit_in_search_of_match_param(OnigMatchParam* param, + unsigned long limit) +{ +#ifdef USE_RETRY_LIMIT + param->retry_limit_in_search = limit; + if (limit != 0 && param->retry_limit_in_match > limit) + param->retry_limit_in_match = limit; + + return ONIG_NORMAL; +#else + return ONIG_NO_SUPPORT_CONFIG; +#endif } extern int @@ -141,7 +167,11 @@ typedef struct { int ptr_num; const UChar* start; /* search start position (for \G: BEGIN_POSITION) */ unsigned int match_stack_limit; +#ifdef USE_RETRY_LIMIT unsigned long retry_limit_in_match; + unsigned long retry_limit_in_search; + unsigned long retry_limit_in_search_counter; +#endif OnigMatchParam* mp; #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE int best_len; /* for ONIG_OPTION_FIND_LONGEST */ @@ -1026,8 +1056,8 @@ onig_region_copy(OnigRegion* to, OnigRegion* from) #endif #define STK_EMPTY_CHECK_END 0x5000 /* for recursive call */ #define STK_MEM_END_MARK 0x8100 -#define STK_CALL_FRAME 0x0400 -#define STK_RETURN 0x0500 +#define STK_CALL_FRAME (0x0400 | STK_MASK_POP_HANDLED) +#define STK_RETURN (0x0500 | STK_MASK_POP_HANDLED) #define STK_SAVE_VAL 0x0600 #define STK_MARK 0x0704 @@ -1147,6 +1177,21 @@ struct OnigCalloutArgsStruct { #endif /* USE_REPEAT_AND_EMPTY_CHECK_LOCAL_VAR */ +#ifdef USE_RETRY_LIMIT +#define RETRY_IN_MATCH_ARG_INIT(msa,mpv) \ + (msa).retry_limit_in_match = (mpv)->retry_limit_in_match;\ + (msa).retry_limit_in_search = (mpv)->retry_limit_in_search;\ + (msa).retry_limit_in_search_counter = 0; +#else +#define RETRY_IN_MATCH_ARG_INIT(msa,mpv) +#endif + +#ifdef USE_CALL +#define POP_CALL else if (stk->type == STK_RETURN) {subexp_call_nest_counter++;} else if (stk->type == STK_CALL_FRAME) {subexp_call_nest_counter--;} +#else +#define POP_CALL +#endif + #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE #define MATCH_ARG_INIT(msa, reg, arg_option, arg_region, arg_start, mpv) do { \ (msa).stack_p = (void* )0;\ @@ -1154,7 +1199,7 @@ struct OnigCalloutArgsStruct { (msa).region = (arg_region);\ (msa).start = (arg_start);\ (msa).match_stack_limit = (mpv)->match_stack_limit;\ - (msa).retry_limit_in_match = (mpv)->retry_limit_in_match;\ + RETRY_IN_MATCH_ARG_INIT(msa,mpv)\ (msa).mp = mpv;\ (msa).best_len = ONIG_MISMATCH;\ (msa).ptr_num = PTR_NUM_SIZE(reg);\ @@ -1166,7 +1211,7 @@ struct OnigCalloutArgsStruct { (msa).region = (arg_region);\ (msa).start = (arg_start);\ (msa).match_stack_limit = (mpv)->match_stack_limit;\ - (msa).retry_limit_in_match = (mpv)->retry_limit_in_match;\ + RETRY_IN_MATCH_ARG_INIT(msa,mpv)\ (msa).mp = mpv;\ (msa).ptr_num = PTR_NUM_SIZE(reg);\ } while(0) @@ -1210,7 +1255,7 @@ struct OnigCalloutArgsStruct { #define STACK_SAVE do{\ - msa->stack_n = (int )(stk_end - stk_base);\ + msa->stack_n = (int )(stk_end - stk_base);\ if (is_alloca != 0) {\ size_t size = sizeof(StackIndex) * msa->ptr_num \ + sizeof(StackType) * msa->stack_n;\ @@ -1238,9 +1283,10 @@ onig_set_match_stack_limit_size(unsigned int size) return 0; } -#ifdef USE_RETRY_LIMIT_IN_MATCH +#ifdef USE_RETRY_LIMIT -static unsigned long RetryLimitInMatch = DEFAULT_RETRY_LIMIT_IN_MATCH; +static unsigned long RetryLimitInMatch = DEFAULT_RETRY_LIMIT_IN_MATCH; +static unsigned long RetryLimitInSearch = DEFAULT_RETRY_LIMIT_IN_SEARCH; #define CHECK_RETRY_LIMIT_IN_MATCH do {\ if (retry_in_match_counter++ > retry_limit_in_match) {\ @@ -1252,24 +1298,47 @@ static unsigned long RetryLimitInMatch = DEFAULT_RETRY_LIMIT_IN_MATCH; #define CHECK_RETRY_LIMIT_IN_MATCH -#endif /* USE_RETRY_LIMIT_IN_MATCH */ +#endif /* USE_RETRY_LIMIT */ extern unsigned long onig_get_retry_limit_in_match(void) { -#ifdef USE_RETRY_LIMIT_IN_MATCH +#ifdef USE_RETRY_LIMIT return RetryLimitInMatch; #else - /* return ONIG_NO_SUPPORT_CONFIG; */ return 0; #endif } extern int -onig_set_retry_limit_in_match(unsigned long size) +onig_set_retry_limit_in_match(unsigned long n) { -#ifdef USE_RETRY_LIMIT_IN_MATCH - RetryLimitInMatch = size; +#ifdef USE_RETRY_LIMIT + RetryLimitInMatch = n; + return 0; +#else + return ONIG_NO_SUPPORT_CONFIG; +#endif +} + +extern unsigned long +onig_get_retry_limit_in_search(void) +{ +#ifdef USE_RETRY_LIMIT + return RetryLimitInSearch; +#else + return 0; +#endif +} + +extern int +onig_set_retry_limit_in_search(unsigned long n) +{ +#ifdef USE_RETRY_LIMIT + RetryLimitInSearch = n; + if (n != 0 && RetryLimitInMatch > n) + RetryLimitInMatch = n; + return 0; #else return ONIG_NO_SUPPORT_CONFIG; @@ -1318,8 +1387,9 @@ extern int onig_initialize_match_param(OnigMatchParam* mp) { mp->match_stack_limit = MatchStackLimit; -#ifdef USE_RETRY_LIMIT_IN_MATCH - mp->retry_limit_in_match = RetryLimitInMatch; +#ifdef USE_RETRY_LIMIT + mp->retry_limit_in_match = RetryLimitInMatch; + mp->retry_limit_in_search = RetryLimitInSearch; #endif #ifdef USE_CALLOUT @@ -1521,9 +1591,9 @@ onig_set_callout_data_by_callout_args_self(OnigCalloutArgs* args, static int -stack_double(int is_alloca, char** arg_alloc_base, - StackType** arg_stk_base, StackType** arg_stk_end, StackType** arg_stk, - MatchArg* msa) +stack_double(int* is_alloca, char** arg_alloc_base, + StackType** arg_stk_base, StackType** arg_stk_end, + StackType** arg_stk, MatchArg* msa) { unsigned int n; int used; @@ -1542,18 +1612,21 @@ stack_double(int is_alloca, char** arg_alloc_base, size = sizeof(StackIndex) * msa->ptr_num + sizeof(StackType) * n; n *= 2; new_size = sizeof(StackIndex) * msa->ptr_num + sizeof(StackType) * n; - if (is_alloca != 0) { + if (*is_alloca != 0) { new_alloc_base = (char* )xmalloc(new_size); if (IS_NULL(new_alloc_base)) { STACK_SAVE; return ONIGERR_MEMORY; } xmemcpy(new_alloc_base, alloc_base, size); + *is_alloca = 0; } else { if (msa->match_stack_limit != 0 && n > msa->match_stack_limit) { - if ((unsigned int )(stk_end - stk_base) == msa->match_stack_limit) + if ((unsigned int )(stk_end - stk_base) == msa->match_stack_limit) { + STACK_SAVE; return ONIGERR_MATCH_STACK_LIMIT_OVER; + } else n = msa->match_stack_limit; } @@ -1576,9 +1649,8 @@ stack_double(int is_alloca, char** arg_alloc_base, #define STACK_ENSURE(n) do {\ if ((int )(stk_end - stk) < (n)) {\ - int r = stack_double(is_alloca, &alloc_base, &stk_base, &stk_end, &stk, msa);\ - if (r != 0) { STACK_SAVE; return r; } \ - is_alloca = 0;\ + int r = stack_double(&is_alloca, &alloc_base, &stk_base, &stk_end, &stk, msa);\ + if (r != 0) return r;\ UPDATE_FOR_STACK_REALLOC;\ }\ } while(0) @@ -1921,6 +1993,7 @@ stack_double(int is_alloca, char** arg_alloc_base, }\ POP_REPEAT_INC \ POP_EMPTY_CHECK_START \ + POP_CALL \ POP_CALLOUT_CASE\ }\ }\ @@ -1947,6 +2020,7 @@ stack_double(int is_alloca, char** arg_alloc_base, }\ POP_REPEAT_INC \ POP_EMPTY_CHECK_START \ + POP_CALL \ /* Don't call callout here because negation of total success by (?!..) (?options; OnigEncoding encode = reg->enc; OnigCaseFoldType case_fold_flag = reg->case_fold_flag; +#ifdef USE_CALL + unsigned long subexp_call_nest_counter = 0; +#endif #ifdef ONIG_DEBUG_MATCH static unsigned int counter = 1; @@ -2749,7 +2827,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, msa->mp->match_at_call_counter++; #endif -#ifdef USE_RETRY_LIMIT_IN_MATCH +#ifdef USE_RETRY_LIMIT retry_limit_in_match = msa->retry_limit_in_match; #endif @@ -2773,7 +2851,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, STACK_PUSH_BOTTOM(STK_ALT, FinishCode); /* bottom stack */ INIT_RIGHT_RANGE; -#ifdef USE_RETRY_LIMIT_IN_MATCH +#ifdef USE_RETRY_LIMIT retry_in_match_counter = 0; #endif @@ -3794,8 +3872,6 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, CASE_OP(POP) STACK_POP_ONE; - /* for stop backtrack */ - /* CHECK_RETRY_LIMIT_IN_MATCH; */ INC_OP; JUMP_OUT; @@ -3900,14 +3976,19 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, #ifdef USE_CALL CASE_OP(CALL) + if (subexp_call_nest_counter == SUBEXP_CALL_MAX_NEST_LEVEL) + goto fail; + subexp_call_nest_counter++; addr = p->call.addr; INC_OP; STACK_PUSH_CALL_FRAME(p); p = reg->ops + addr; + JUMP_OUT; CASE_OP(RETURN) STACK_RETURN(p); STACK_PUSH_RETURN; + subexp_call_nest_counter--; JUMP_OUT; #endif @@ -4138,6 +4219,15 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, } BYTECODE_INTERPRETER_END; match_at_end: + if (msa->retry_limit_in_search != 0) { + if (retry_in_match_counter > ULONG_MAX - msa->retry_limit_in_search_counter) + best_len = ONIGERR_RETRY_LIMIT_IN_SEARCH_OVER; + else { + msa->retry_limit_in_search_counter += retry_in_match_counter; + if (msa->retry_limit_in_search_counter > msa->retry_limit_in_search) + best_len = ONIGERR_RETRY_LIMIT_IN_SEARCH_OVER; + } + } STACK_SAVE; return best_len; } @@ -6389,6 +6479,8 @@ onig_setup_builtin_monitors_by_ascii_encoded_name(void* fp /* FILE* */) return ONIG_NORMAL; } +#pragma warning( pop ) + #endif /* ONIG_NO_PRINT */ #endif /* USE_CALLOUT */ diff --git a/oniguruma/src/regint.h b/oniguruma/src/regint.h index 837045c77..1efd60c7e 100644 --- a/oniguruma/src/regint.h +++ b/oniguruma/src/regint.h @@ -64,7 +64,7 @@ #define USE_STUBBORN_CHECK_CAPTURES_IN_EMPTY_REPEAT /* /(?:()|())*\2/ */ #define USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE /* /\n$/ =~ "\n" */ #define USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR -#define USE_RETRY_LIMIT_IN_MATCH +#define USE_RETRY_LIMIT #ifdef USE_GOTO_LABELS_AS_VALUES #define USE_THREADED_CODE #define USE_DIRECT_THREADED_CODE @@ -86,7 +86,9 @@ #define INIT_MATCH_STACK_SIZE 160 #define DEFAULT_MATCH_STACK_LIMIT_SIZE 0 /* unlimited */ #define DEFAULT_RETRY_LIMIT_IN_MATCH 10000000 +#define DEFAULT_RETRY_LIMIT_IN_SEARCH 0 /* unlimited */ #define DEFAULT_PARSE_DEPTH_LIMIT 4096 +#define SUBEXP_CALL_MAX_NEST_LEVEL 16 #include "regenc.h" @@ -180,9 +182,14 @@ #define CHECK_NULL_RETURN_MEMERR(p) if (IS_NULL(p)) return ONIGERR_MEMORY #define NULL_UCHARP ((UChar* )0) +#ifndef ONIG_INT_MAX +#define ONIG_INT_MAX INT_MAX +#endif + #define CHAR_MAP_SIZE 256 #define INFINITE_LEN ONIG_INFINITE_DISTANCE -#define LOOK_BEHIND_MAX_CHAR_LEN INT_MAX +#define STEP_BACK_MAX_CHAR_LEN 65535 /* INT_MAX is too big */ +#define LOOK_BEHIND_MAX_CHAR_LEN STEP_BACK_MAX_CHAR_LEN /* escape other system UChar definition */ #ifdef ONIG_ESCAPE_UCHAR_COLLISION diff --git a/oniguruma/src/regparse.c b/oniguruma/src/regparse.c index 784ea567b..54f92e2c8 100644 --- a/oniguruma/src/regparse.c +++ b/oniguruma/src/regparse.c @@ -3456,7 +3456,7 @@ scan_number(UChar** src, const UChar* end, OnigEncoding enc) PFETCH(c); if (IS_CODE_DIGIT_ASCII(enc, c)) { val = (int )DIGITVAL(c); - if ((INT_MAX - val) / 10 < num) + if ((ONIG_INT_MAX - val) / 10 < num) return -1; /* overflow */ num = num * 10 + val; From 8c96566039692c30545e33db0a9b8729570edec2 Mon Sep 17 00:00:00 2001 From: RaiKoHoff Date: Tue, 18 Feb 2020 10:16:58 +0100 Subject: [PATCH 4/5] + fix: concurrent access to .ini-File (lock file) --- minipath/minipath.vcxproj | 4 +++ minipath/src/Config.cpp | 42 ++++++++++++++++----------- minipath/src/SimpleIni.h | 60 ++++++++++++++++++++++++--------------- src/Config/Config.cpp | 9 +++--- src/Config/SimpleIni.h | 60 ++++++++++++++++++++++++--------------- src/Notepad3.vcxproj | 4 +++ 6 files changed, 112 insertions(+), 67 deletions(-) diff --git a/minipath/minipath.vcxproj b/minipath/minipath.vcxproj index 2491dd0f7..5c9515863 100644 --- a/minipath/minipath.vcxproj +++ b/minipath/minipath.vcxproj @@ -102,6 +102,7 @@ Fast /utf-8 %(AdditionalOptions) stdcpp17 + Sync /MACHINE:I386 %(AdditionalOptions) @@ -164,6 +165,7 @@ true /utf-8 %(AdditionalOptions) stdcpp17 + Sync /MACHINE:I386 %(AdditionalOptions) @@ -224,6 +226,7 @@ Fast /utf-8 %(AdditionalOptions) stdcpp17 + Sync false @@ -265,6 +268,7 @@ true /utf-8 %(AdditionalOptions) stdcpp17 + Sync false diff --git a/minipath/src/Config.cpp b/minipath/src/Config.cpp index f74dbcafb..2e0e2ee20 100644 --- a/minipath/src/Config.cpp +++ b/minipath/src/Config.cpp @@ -62,7 +62,9 @@ static BOOL const s_bSetSpaces = FALSE; // ---------------------------------------------------------------------------- -constexpr bool SI_Success(const SI_Error rc) noexcept { return (rc >= SI_Error::SI_OK); }; +constexpr bool SI_Success(const SI_Error rc) noexcept { + return ((rc == SI_Error::SI_OK) || (rc == SI_Error::SI_UPDATED) || (rc == SI_Error::SI_INSERTED)); +}; // ============================================================================ @@ -72,17 +74,9 @@ static CSimpleIni s_INI(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine); extern "C" BOOL LoadIniFile(LPCWSTR lpIniFilePath) { s_INI.Reset(); - SI_Error const rc = s_INI.LoadFile(lpIniFilePath); - return SI_Success(rc); -} - -extern "C" BOOL SaveIniFile(LPCWSTR lpIniFilePath) -{ s_INI.SetSpaces(s_bSetSpaces); - SI_Error const rc = s_INI.SaveFile(lpIniFilePath, s_bWriteSIG); - if (SI_Success(rc)) { - s_INI.Reset(); // done - } + s_INI.SetMultiLine(s_bUseMultiLine); + SI_Error const rc = s_INI.LoadFile(lpIniFilePath); return SI_Success(rc); } @@ -91,6 +85,15 @@ extern "C" void ReleaseIniFile() s_INI.Reset(); } +extern "C" BOOL SaveIniFile(LPCWSTR lpIniFilePath) +{ + s_INI.SetSpaces(s_bSetSpaces); + s_INI.SetMultiLine(s_bUseMultiLine); + SI_Error const rc = s_INI.SaveFile(lpIniFilePath, s_bWriteSIG); + ReleaseIniFile(); + return SI_Success(rc); +} + //============================================================================= // @@ -220,7 +223,6 @@ extern "C" BOOL IniSectionDelete(LPCWSTR lpSectionName, LPCWSTR lpKeyName, BOOL extern "C" BOOL IniSectionClear(LPCWSTR lpSectionName, BOOL bRemoveEmpty) { - BOOL const ok = s_INI.Delete(lpSectionName, nullptr, bRemoveEmpty); if (!bRemoveEmpty) { SI_Error const rc = s_INI.SetValue(lpSectionName, nullptr, nullptr); @@ -263,6 +265,9 @@ extern "C" size_t IniFileGetString(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LP StringCchCopyW(lpReturnedString, cchReturnedString, Ini.GetValue(lpSectionName, lpKeyName, lpDefault, &bHasMultiple)); //assert(!bHasMultiple); } + else { + StringCchCopyW(lpReturnedString, cchReturnedString, lpDefault); + } return (size_t)lstrlen(lpReturnedString); } // ============================================================================ @@ -271,17 +276,16 @@ extern "C" size_t IniFileGetString(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LP extern "C" BOOL IniFileSetString(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR lpKeyName, LPCWSTR lpString) { CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine); + Ini.SetSpaces(s_bSetSpaces); + Ini.SetMultiLine(s_bUseMultiLine); SI_Error rc = Ini.LoadFile(lpFilePath); if (SI_Success(rc)) { SI_Error const res = Ini.SetValue(lpSectionName, lpKeyName, lpString, nullptr, !s_bUseMultiKey); rc = SI_Success(res) ? SI_Error::SI_OK : SI_Error::SI_FAIL; - if (SI_Success(rc)) { - Ini.SetSpaces(s_bSetSpaces); rc = Ini.SaveFile(lpFilePath, s_bWriteSIG); } - Ini.Reset(); } return SI_Success(rc); } @@ -306,10 +310,11 @@ extern "C" int IniFileGetInt(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR extern "C" BOOL IniFileSetInt(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR lpKeyName, int iValue) { CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine); + Ini.SetSpaces(s_bSetSpaces); + Ini.SetMultiLine(s_bUseMultiLine); SI_Error rc = Ini.LoadFile(lpFilePath); if (SI_Success(rc)) { Ini.SetLongValue(lpSectionName, lpKeyName, (long)iValue, nullptr, false, !s_bUseMultiKey); - Ini.SetSpaces(s_bSetSpaces); rc = Ini.SaveFile(lpFilePath, s_bWriteSIG); } Ini.Reset(); @@ -336,10 +341,11 @@ extern "C" BOOL IniFileGetBool(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWST extern "C" BOOL IniFileSetBool(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR lpKeyName, BOOL bValue) { CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine); + Ini.SetSpaces(s_bSetSpaces); + Ini.SetMultiLine(s_bUseMultiLine); SI_Error rc = Ini.LoadFile(lpFilePath); if (SI_Success(rc)) { Ini.SetBoolValue(lpSectionName, lpKeyName, bValue, nullptr, !s_bUseMultiKey); - Ini.SetSpaces(s_bSetSpaces); rc = Ini.SaveFile(lpFilePath, s_bWriteSIG); } Ini.Reset(); @@ -351,6 +357,8 @@ extern "C" BOOL IniFileSetBool(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWST extern "C" BOOL IniFileDelete(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR lpKeyName, BOOL bRemoveEmpty) { CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine); + Ini.SetMultiLine(s_bUseMultiLine); + Ini.SetSpaces(s_bSetSpaces); SI_Error rc = Ini.LoadFile(lpFilePath); if (SI_Success(rc)) { diff --git a/minipath/src/SimpleIni.h b/minipath/src/SimpleIni.h index 0f5f4d906..a346b0308 100644 --- a/minipath/src/SimpleIni.h +++ b/minipath/src/SimpleIni.h @@ -631,7 +631,7 @@ public: @return SI_Error See error definitions */ #ifdef SI_USE_LOCKING_WIDE_FILE - SI_Error LoadFile( HANDLE a_hFile, DWORD dwFileSize); + SI_Error LoadFile( HANDLE a_hFile); #else SI_Error LoadFile( FILE * a_fpFile ); #endif @@ -1431,28 +1431,30 @@ CSimpleIniTempl::LoadFile( { HANDLE hFile = CreateFile(a_pwszFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) { return SI_Error::SI_FILE; } - DWORD dwFileSizeHigh = 0UL; - DWORD const dwFileSize = GetFileSize(hFile, &dwFileSizeHigh); - if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSizeHigh != 0UL)) { - return SI_Error::SI_FILE; - } - SI_Error rc = SI_Error::SI_FILE; DWORD const flags = 0UL; // SHARED READ(!) ~ LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK OVERLAPPED OvrLpd = { 0 }; - if (LockFileEx(hFile, flags, 0, dwFileSize, dwFileSizeHigh, &OvrLpd)) { - - rc = LoadFile(hFile, dwFileSize); - - UnlockFileEx(hFile, 0, dwFileSize, dwFileSizeHigh, &OvrLpd); + bool bLocked = false; + try { + bLocked = LockFileEx(hFile, flags, 0, MAXDWORD, 0, &OvrLpd); + if (bLocked) { + rc = LoadFile(hFile); + bLocked = !UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd); + } + } + catch (...) { + if (bLocked) { + bLocked = !UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd); + } + throw; // re-throw to pass the exception to some other handler } CloseHandle(hFile); return rc; @@ -1494,9 +1496,15 @@ CSimpleIniTempl::LoadFile( template SI_Error CSimpleIniTempl::LoadFile( - HANDLE a_hFile, DWORD dwFileSize + HANDLE a_hFile ) { + DWORD dwFileSizeHigh = 0UL; + DWORD const dwFileSize = GetFileSize(a_hFile, &dwFileSizeHigh); + if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSize == 0) || (dwFileSizeHigh != 0UL)) { + return SI_Error::SI_FILE; + } + // allocate and ensure NULL terminated auto* pData = new(std::nothrow) char[dwFileSize + 1]; if (!pData) { @@ -1506,7 +1514,7 @@ CSimpleIniTempl::LoadFile( // load the raw file data DWORD nBytesRead = 0UL; - BOOL const result = ReadFile(a_hFile, pData, dwFileSize, &nBytesRead, NULL); + BOOL const result = ReadFile(a_hFile, pData, dwFileSize, &nBytesRead, nullptr); if ((result == FALSE) || (nBytesRead != dwFileSize)) { delete[] pData; return SI_Error::SI_FILE; @@ -2638,7 +2646,7 @@ CSimpleIniTempl::SaveFile( { HANDLE hFile = CreateFile(a_pwszFile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) { return SI_Error::SI_FILE; @@ -2648,13 +2656,19 @@ CSimpleIniTempl::SaveFile( OVERLAPPED OvrLpd = { 0 }; SI_Error rc = SI_Error::SI_FILE; - if (LockFileEx(hFile, flags, 0, MAXDWORD, 0, &OvrLpd)) { - - rc = SaveFile(hFile, a_bAddSignature); - - FlushFileBuffers(hFile); - - UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd); + bool bLocked = false; + try { + bLocked = LockFileEx(hFile, flags, 0, MAXDWORD, 0, &OvrLpd); + if (bLocked) { + rc = SaveFile(hFile, a_bAddSignature); + bLocked = !UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd); + } + } + catch(...) { + if (bLocked) { + bLocked = !UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd); + } + throw; // re-throw to pass the exception to some other handler } CloseHandle(hFile); diff --git a/src/Config/Config.cpp b/src/Config/Config.cpp index c1ddefad2..8daaae29d 100644 --- a/src/Config/Config.cpp +++ b/src/Config/Config.cpp @@ -288,7 +288,6 @@ extern "C" size_t IniFileGetString(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LP else { StringCchCopyW(lpReturnedString, cchReturnedString, lpDefault); } - Ini.Reset(); return StringCchLenW(lpReturnedString, cchReturnedString); } // ============================================================================ @@ -298,6 +297,7 @@ extern "C" bool IniFileSetString(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCW { CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine); Ini.SetSpaces(s_bSetSpaces); + Ini.SetMultiLine(s_bUseMultiLine); SI_Error rc = Ini.LoadFile(lpFilePath); if (SI_Success(rc)) { @@ -307,7 +307,6 @@ extern "C" bool IniFileSetString(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCW rc = Ini.SaveFile(lpFilePath, s_bWriteSIG); } } - Ini.Reset(); return SI_Success(rc); } // ============================================================================ @@ -323,7 +322,6 @@ extern "C" int IniFileGetInt(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR //assert(!bHasMultiple); return iValue; } - Ini.Reset(); return iDefault; } // ============================================================================ @@ -333,6 +331,7 @@ extern "C" bool IniFileSetInt(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR { CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine); Ini.SetSpaces(s_bSetSpaces); + Ini.SetMultiLine(s_bUseMultiLine); SI_Error rc = Ini.LoadFile(lpFilePath); if (SI_Success(rc)) { Ini.SetLongValue(lpSectionName, lpKeyName, (long)iValue, nullptr, false, !s_bUseMultiKey); @@ -354,7 +353,6 @@ extern "C" bool IniFileGetBool(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWST //assert(!bHasMultiple); return bValue; } - Ini.Reset(); return bDefault; } // ============================================================================ @@ -364,6 +362,7 @@ extern "C" bool IniFileSetBool(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWST { CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine); Ini.SetSpaces(s_bSetSpaces); + Ini.SetMultiLine(s_bUseMultiLine); SI_Error rc = Ini.LoadFile(lpFilePath); if (SI_Success(rc)) { Ini.SetBoolValue(lpSectionName, lpKeyName, bValue, nullptr, !s_bUseMultiKey); @@ -378,11 +377,13 @@ extern "C" bool IniFileSetBool(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWST extern "C" bool IniFileDelete(LPCWSTR lpFilePath, LPCWSTR lpSectionName, LPCWSTR lpKeyName, bool bRemoveEmpty) { CSimpleIni Ini(s_bIsUTF8, s_bUseMultiKey, s_bUseMultiLine); + Ini.SetMultiLine(s_bUseMultiLine); Ini.SetSpaces(s_bSetSpaces); SI_Error rc = Ini.LoadFile(lpFilePath); if (SI_Success(rc)) { Ini.Delete(lpSectionName, lpKeyName, bRemoveEmpty); + Ini.SetSpaces(s_bSetSpaces); rc = Ini.SaveFile(lpFilePath, s_bWriteSIG); } Ini.Reset(); diff --git a/src/Config/SimpleIni.h b/src/Config/SimpleIni.h index 0f5f4d906..a346b0308 100644 --- a/src/Config/SimpleIni.h +++ b/src/Config/SimpleIni.h @@ -631,7 +631,7 @@ public: @return SI_Error See error definitions */ #ifdef SI_USE_LOCKING_WIDE_FILE - SI_Error LoadFile( HANDLE a_hFile, DWORD dwFileSize); + SI_Error LoadFile( HANDLE a_hFile); #else SI_Error LoadFile( FILE * a_fpFile ); #endif @@ -1431,28 +1431,30 @@ CSimpleIniTempl::LoadFile( { HANDLE hFile = CreateFile(a_pwszFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) { return SI_Error::SI_FILE; } - DWORD dwFileSizeHigh = 0UL; - DWORD const dwFileSize = GetFileSize(hFile, &dwFileSizeHigh); - if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSizeHigh != 0UL)) { - return SI_Error::SI_FILE; - } - SI_Error rc = SI_Error::SI_FILE; DWORD const flags = 0UL; // SHARED READ(!) ~ LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK OVERLAPPED OvrLpd = { 0 }; - if (LockFileEx(hFile, flags, 0, dwFileSize, dwFileSizeHigh, &OvrLpd)) { - - rc = LoadFile(hFile, dwFileSize); - - UnlockFileEx(hFile, 0, dwFileSize, dwFileSizeHigh, &OvrLpd); + bool bLocked = false; + try { + bLocked = LockFileEx(hFile, flags, 0, MAXDWORD, 0, &OvrLpd); + if (bLocked) { + rc = LoadFile(hFile); + bLocked = !UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd); + } + } + catch (...) { + if (bLocked) { + bLocked = !UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd); + } + throw; // re-throw to pass the exception to some other handler } CloseHandle(hFile); return rc; @@ -1494,9 +1496,15 @@ CSimpleIniTempl::LoadFile( template SI_Error CSimpleIniTempl::LoadFile( - HANDLE a_hFile, DWORD dwFileSize + HANDLE a_hFile ) { + DWORD dwFileSizeHigh = 0UL; + DWORD const dwFileSize = GetFileSize(a_hFile, &dwFileSizeHigh); + if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSize == 0) || (dwFileSizeHigh != 0UL)) { + return SI_Error::SI_FILE; + } + // allocate and ensure NULL terminated auto* pData = new(std::nothrow) char[dwFileSize + 1]; if (!pData) { @@ -1506,7 +1514,7 @@ CSimpleIniTempl::LoadFile( // load the raw file data DWORD nBytesRead = 0UL; - BOOL const result = ReadFile(a_hFile, pData, dwFileSize, &nBytesRead, NULL); + BOOL const result = ReadFile(a_hFile, pData, dwFileSize, &nBytesRead, nullptr); if ((result == FALSE) || (nBytesRead != dwFileSize)) { delete[] pData; return SI_Error::SI_FILE; @@ -2638,7 +2646,7 @@ CSimpleIniTempl::SaveFile( { HANDLE hFile = CreateFile(a_pwszFile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); if (hFile == INVALID_HANDLE_VALUE) { return SI_Error::SI_FILE; @@ -2648,13 +2656,19 @@ CSimpleIniTempl::SaveFile( OVERLAPPED OvrLpd = { 0 }; SI_Error rc = SI_Error::SI_FILE; - if (LockFileEx(hFile, flags, 0, MAXDWORD, 0, &OvrLpd)) { - - rc = SaveFile(hFile, a_bAddSignature); - - FlushFileBuffers(hFile); - - UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd); + bool bLocked = false; + try { + bLocked = LockFileEx(hFile, flags, 0, MAXDWORD, 0, &OvrLpd); + if (bLocked) { + rc = SaveFile(hFile, a_bAddSignature); + bLocked = !UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd); + } + } + catch(...) { + if (bLocked) { + bLocked = !UnlockFileEx(hFile, 0, MAXDWORD, 0, &OvrLpd); + } + throw; // re-throw to pass the exception to some other handler } CloseHandle(hFile); diff --git a/src/Notepad3.vcxproj b/src/Notepad3.vcxproj index 2735606c7..8abe66851 100644 --- a/src/Notepad3.vcxproj +++ b/src/Notepad3.vcxproj @@ -120,6 +120,7 @@ stdcpp17 false /utf-8 %(AdditionalOptions) + Sync comctl32.lib;imm32.lib;shlwapi.lib;uxtheme.lib;muiload.lib;dwrite.lib;scintilla.lib;%(AdditionalDependencies) @@ -183,6 +184,7 @@ stdcpp17 false /utf-8 %(AdditionalOptions) + Sync comctl32.lib;imm32.lib;shlwapi.lib;uxtheme.lib;muiload.lib;dwrite.lib;scintilla.lib;%(AdditionalDependencies) @@ -247,6 +249,7 @@ /utf-8 %(AdditionalOptions) AnySuitable true + Sync comctl32.lib;imm32.lib;shlwapi.lib;uxtheme.lib;muiload.lib;dwrite.lib;scintilla.lib;%(AdditionalDependencies) @@ -314,6 +317,7 @@ /utf-8 %(AdditionalOptions) AnySuitable true + Sync comctl32.lib;imm32.lib;shlwapi.lib;uxtheme.lib;muiload.lib;dwrite.lib;scintilla.lib;%(AdditionalDependencies) From 8040d09c41b816e086caad835e259e3a21485fff Mon Sep 17 00:00:00 2001 From: RaiKoHoff Date: Tue, 18 Feb 2020 10:19:27 +0100 Subject: [PATCH 5/5] + upd: versioning files --- Versions/day.txt | 2 +- res/Notepad3.exe.manifest.conf | 2 +- src/VersionEx.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Versions/day.txt b/Versions/day.txt index 0ddd619ce..dc6f4a877 100644 --- a/Versions/day.txt +++ b/Versions/day.txt @@ -1 +1 @@ -217 +218 diff --git a/res/Notepad3.exe.manifest.conf b/res/Notepad3.exe.manifest.conf index 9f1f274ec..2fccaf9a5 100644 --- a/res/Notepad3.exe.manifest.conf +++ b/res/Notepad3.exe.manifest.conf @@ -3,7 +3,7 @@ Notepad3 RC1 diff --git a/src/VersionEx.h b/src/VersionEx.h index e28d7bd83..d91b73a70 100644 --- a/src/VersionEx.h +++ b/src/VersionEx.h @@ -8,7 +8,7 @@ #define SAPPNAME "Notepad3" #define VERSION_MAJOR 5 #define VERSION_MINOR 20 -#define VERSION_REV 217 +#define VERSION_REV 218 #define VERSION_BUILD 1 #define SCINTILLA_VER 430 #define ONIGURUMA_REGEX_VER 6.9.4