rsync: escape U+2028/U+2029
JSON strings can contain unescaped U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR characters while ECMAScript strings cannot. ES2019 now allows those unescaped. The integrity code assumes that each JSON is a single line but that assumption does not hold true when these characters are there in the string. Fix is to escape them.
This commit is contained in:
+7
-2
@@ -10,6 +10,11 @@ import util from 'node:util';
|
||||
|
||||
const { log } = logger('syncer');
|
||||
|
||||
// JSON.stringify does not escape U+2028/U+2029 and readline treats them as line terminators
|
||||
// https://github.com/tc39/proposal-json-superset
|
||||
function jsonLineStringify(obj) {
|
||||
return JSON.stringify(obj).replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029');
|
||||
}
|
||||
|
||||
function readCache(cacheFile) {
|
||||
assert.strictEqual(typeof cacheFile, 'string');
|
||||
@@ -111,7 +116,7 @@ async function sync(dataLayout, cacheFile) {
|
||||
if (!entryStat.isDirectory() && !entryStat.isFile()) continue; // ignore non-files and dirs
|
||||
if (entryStat.isSymbolicLink()) continue;
|
||||
|
||||
safe.fs.appendFileSync(newCacheFd, JSON.stringify({ path: entryPath, stat: { mtime: entryStat.mtime.getTime(), size: entryStat.size, inode: entryStat.inode, mode: entryStat.mode } }) + '\n');
|
||||
safe.fs.appendFileSync(newCacheFd, jsonLineStringify({ path: entryPath, stat: { mtime: entryStat.mtime.getTime(), size: entryStat.size, inode: entryStat.inode, mode: entryStat.mode } }) + '\n');
|
||||
|
||||
if (curCacheIndex !== cache.length && cache[curCacheIndex].path < entryPath) { // files disappeared. first advance cache as needed
|
||||
advanceCache(entryPath);
|
||||
@@ -185,7 +190,7 @@ async function finalize(integrityMap, cacheFile) {
|
||||
cacheEntry.integrity = integrityMap.get(cacheEntry.path); // { size, sha256 }
|
||||
if (typeof cacheEntry.integrity === 'undefined') throw new BoxError(BoxError.INTERNAL_ERROR, `No integrity information for ${cacheEntry.path}`);
|
||||
}
|
||||
safe.fs.appendFileSync(tempCacheFd, JSON.stringify(cacheEntry) + '\n');
|
||||
safe.fs.appendFileSync(tempCacheFd, jsonLineStringify(cacheEntry) + '\n');
|
||||
}
|
||||
|
||||
safe.fs.closeSync(tempCacheFd);
|
||||
|
||||
Reference in New Issue
Block a user