diff --git a/src/library.js b/src/library.js index a192a7b184a16..64a46577c5e41 100644 --- a/src/library.js +++ b/src/library.js @@ -1024,11 +1024,16 @@ LibraryManager.library = { return '%'; } }; + + // Replace %% with a pair of NULLs (which cannot occur in a C string), then + // re-inject them after processing. + pattern = pattern.replace(/%%/g, '\0\0') for (var rule in EXPANSION_RULES_2) { if (pattern.includes(rule)) { pattern = pattern.replace(new RegExp(rule, 'g'), EXPANSION_RULES_2[rule](date)); } } + pattern = pattern.replace(/\0\0/g, '%') var bytes = intArrayFromString(pattern, false); if (bytes.length > maxsize) { diff --git a/tests/core/test_strftime.cpp b/tests/core/test_strftime.cpp index 4ba7c575fc929..c99603a0ec8e8 100644 --- a/tests/core/test_strftime.cpp +++ b/tests/core/test_strftime.cpp @@ -39,6 +39,11 @@ int main() { tm.tm_yday = 51; tm.tm_isdst = 0; + // Test %% escaping + const char *fmt = "%%H=%H %%M=%m %%z=%z"; + strftime(s, sizeof(s), fmt, &tm); + printf("%s -> %s\n", fmt, s); + size = strftime(s, 1000, "", &tm); test((size == 0) && (*s == '\0'), "strftime test #1", s); diff --git a/tests/core/test_strftime.out b/tests/core/test_strftime.out index 86f916ae39a3a..d25f92e6c8448 100644 --- a/tests/core/test_strftime.out +++ b/tests/core/test_strftime.out @@ -1,3 +1,4 @@ +%%H=%H %%M=%m %%z=%z -> %H=20 %M=02 %z=+0000 strftime test #1: 1 strftime test #2: 1 strftime test #3: 1