Skip to content

Commit eb478df

Browse files
fix: Fix json escaping in header values (#4031)
1 parent 75c56d3 commit eb478df

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

e2e/tests-dfx/assetscanister.bash

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,6 +1897,28 @@ WARN: {
18971897
assert_match '/somedir/upload-me.txt 1/1 \(8 bytes\) sha [0-9a-z]* \(with cache and 1 header\)'
18981898
}
18991899

1900+
@test "asset configuration via .ic-assets.json5 - respects weird characters" {
1901+
install_asset assetscanister
1902+
touch src/e2e_project_frontend/assets/thing.txt
1903+
cat <<'EOF' >src/e2e_project_frontend/assets/.ic-assets.json5
1904+
[
1905+
{
1906+
"match": "thing.txt",
1907+
"headers": {
1908+
"X-Dummy-Header": "\"\'@%({[~$?\\"
1909+
}
1910+
}
1911+
]
1912+
EOF
1913+
dfx_start
1914+
assert_command dfx deploy
1915+
ID=$(dfx canister id e2e_project_frontend)
1916+
PORT=$(get_webserver_port)
1917+
assert_command curl --head "http://localhost:$PORT/thing.txt?canisterId=$ID"
1918+
# shellcheck disable=SC1003
1919+
assert_contains 'x-dummy-header: "'"'"'@%({[~$?\'
1920+
}
1921+
19001922
@test "uses selected canister wasm" {
19011923
dfx_start
19021924
use_asset_wasm 0.12.1

src/canisters/frontend/ic-asset/src/asset/config.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ mod rule_utils {
337337
use crate::error::LoadRuleError;
338338
use globset::{Glob, GlobMatcher};
339339
use itertools::Itertools;
340-
use serde::{Deserialize, Serializer};
340+
use serde::{de::Error as _, Deserialize, Serializer};
341341
use serde_json::Value;
342342
use std::collections::BTreeMap;
343343
use std::fmt;
@@ -387,12 +387,29 @@ mod rule_utils {
387387
where
388388
D: serde::Deserializer<'de>,
389389
{
390-
match serde_json::value::Value::deserialize(deserializer)? {
391-
Value::Object(v) => Ok(Maybe::Value(
392-
v.into_iter()
393-
.map(|(k, v)| (k, v.to_string().trim_matches('"').to_string()))
394-
.collect::<BTreeMap<String, String>>(),
395-
)),
390+
match Value::deserialize(deserializer)? {
391+
Value::Object(v) => {
392+
Ok(Maybe::Value(
393+
v.into_iter()
394+
.map(|(k, v)| {
395+
Ok((
396+
k,
397+
match v {
398+
Value::Bool(b) => b.to_string(),
399+
Value::Number(n) => n.to_string(),
400+
Value::String(s) => s, // v.to_string() would json-escape this
401+
Value::Null => String::new(),
402+
v => {
403+
return Err(D::Error::custom(format!(
404+
"headers must be strings, numbers, or bools (was {v:?})"
405+
)))
406+
}
407+
},
408+
))
409+
})
410+
.collect::<Result<BTreeMap<String, String>, D::Error>>()?,
411+
))
412+
}
396413
Value::Null => Ok(Maybe::Null),
397414
_ => Err(serde::de::Error::custom(
398415
"wrong data format for field `headers` (only map or null are allowed)",

0 commit comments

Comments
 (0)