Skip to content

Commit 0f1e87b

Browse files
committed
escape shell metacharacters
1 parent c4d278e commit 0f1e87b

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

.changeset/deep-nails-behave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@opennextjs/cloudflare": patch
3+
---
4+
5+
fix: escape shell arguments when populating the cache

packages/cloudflare/src/cli/commands/populate-cache.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ async function populateR2IncrementalCache(
122122

123123
runWrangler(
124124
options,
125-
["r2 object put", JSON.stringify(path.join(bucket, cacheKey)), `--file ${JSON.stringify(fullPath)}`],
125+
["r2 object put", quoteShellMeta(path.join(bucket, cacheKey)), `--file ${quoteShellMeta(fullPath)}`],
126126
// NOTE: R2 does not support the environment flag and results in the following error:
127127
// Incorrect type for the 'cacheExpiry' field on 'HttpMetadata': the provided value is not of type 'date'.
128128
{ target: populateCacheOptions.target, excludeRemoteFlag: true, logging: "error" }
@@ -170,7 +170,7 @@ async function populateKVIncrementalCache(
170170

171171
runWrangler(
172172
options,
173-
["kv bulk put", JSON.stringify(chunkPath), `--binding ${JSON.stringify(KV_CACHE_BINDING_NAME)}`],
173+
["kv bulk put", quoteShellMeta(chunkPath), `--binding ${quoteShellMeta(KV_CACHE_BINDING_NAME)}`],
174174
{ ...populateCacheOptions, logging: "error" }
175175
);
176176

@@ -197,7 +197,7 @@ function populateD1TagCache(
197197
options,
198198
[
199199
"d1 execute",
200-
JSON.stringify(D1_TAG_BINDING_NAME),
200+
quoteShellMeta(D1_TAG_BINDING_NAME),
201201
`--command "CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE);"`,
202202
],
203203
{ ...populateCacheOptions, logging: "error" }
@@ -258,3 +258,23 @@ export async function populateCache(
258258
}
259259
}
260260
}
261+
262+
/**
263+
* Escape shell metacharacters.
264+
*
265+
* When `spawnSync` is invoked with `shell: true`, metacharacters need to be escaped.
266+
*
267+
* Based on https://github.com/ljharb/shell-quote/blob/main/quote.js
268+
*
269+
* @param arg
270+
* @returns escaped arg
271+
*/
272+
function quoteShellMeta(arg: string) {
273+
if (/["\s]/.test(arg) && !/'/.test(arg)) {
274+
return `'${arg.replace(/(['\\])/g, "\\$1")}'`;
275+
}
276+
if (/["'\s]/.test(arg)) {
277+
return `"${arg.replace(/(["\\$`!])/g, "\\$1")}"`;
278+
}
279+
return arg.replace(/([A-Za-z]:)?([#!"$&'()*,:;<=>?@[\\\]^`{|}])/g, "$1\\$2");
280+
}

0 commit comments

Comments
 (0)