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/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 678038830..a346b0308 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);
+#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,48 @@ 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,
+ nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ 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 };
+
+ 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;
+}
+
+#else
+
template
SI_Error
CSimpleIniTempl::LoadFile(
@@ -1415,8 +1485,49 @@ 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 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) {
+ 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, nullptr);
+ 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 +1568,8 @@ CSimpleIniTempl::LoadFile(
return rc;
}
+#endif
+
template
SI_Error
CSimpleIniTempl::LoadData(
@@ -2515,11 +2628,55 @@ 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,
+ nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
+
+ 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;
+
+ 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);
+ return rc;
+}
+
+#else
+
template
SI_Error
CSimpleIniTempl::SaveFile(
@@ -2536,6 +2693,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 +2702,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 +2730,7 @@ CSimpleIniTempl::SaveFile(
FileWriter writer(a_pFile);
return Save(writer, a_bAddSignature);
}
+#endif
template
SI_Error
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;
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/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 915f0acc3..a346b0308 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);
#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
@@ -1437,27 +1431,31 @@ 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;
- }
-
- 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);
-
- SI_Error const rc = LoadFile(hFile, dwFileSize, &OvrLpd);
-
- UnlockFileEx(hFile, 0, dwFileSize, dwFileSizeHigh, &OvrLpd);
+ OVERLAPPED OvrLpd = { 0 };
+ 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;
}
@@ -1498,9 +1496,15 @@ CSimpleIniTempl::LoadFile(
template
SI_Error
CSimpleIniTempl::LoadFile(
- HANDLE a_hFile, DWORD dwFileSize, LPOVERLAPPED pOvrLpd
+ 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) {
@@ -1510,7 +1514,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, nullptr);
if ((result == FALSE) || (nBytesRead != dwFileSize)) {
delete[] pData;
return SI_Error::SI_FILE;
@@ -2642,26 +2646,30 @@ CSimpleIniTempl::SaveFile(
{
HANDLE hFile = CreateFile(a_pwszFile,
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ nullptr, CREATE_ALWAYS, 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;
+ DWORD const flags = LOCKFILE_EXCLUSIVE_LOCK; // LOCK SHARED READ/WRITE(!) ~ LOCKFILE_FAIL_IMMEDIATELY
+ OVERLAPPED OvrLpd = { 0 };
+ SI_Error rc = SI_Error::SI_FILE;
+
+ 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
}
-
- 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 +2713,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/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)
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