summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Sago <ogham@bsago.me>2021-04-18 20:39:26 +0100
committerBenjamin Sago <ogham@bsago.me>2021-04-18 20:39:26 +0100
commit640818d36e7ed04e2666aba90d0c037787cb9d6c (patch)
treea1517f99a862696537aced6d47a30a23deed955c
parentfab09a7b622de0f38a90685983b1b6fc3f544d8e (diff)
Stop treating TXT messages as UTF-8
-rw-r--r--dns/src/record/txt.rs48
-rw-r--r--src/output.rs7
-rw-r--r--xtests/madns/outputs/bad-utf8.txt.example.ansitxt1
-rw-r--r--xtests/madns/outputs/bad-utf8.txt.example.json28
-rw-r--r--xtests/madns/outputs/utf8.txt.example.ansitxt1
-rw-r--r--xtests/madns/outputs/utf8.txt.example.json28
-rw-r--r--xtests/madns/txt-records.toml33
7 files changed, 120 insertions, 26 deletions
diff --git a/dns/src/record/txt.rs b/dns/src/record/txt.rs
index e03cffe..f5ac08e 100644
--- a/dns/src/record/txt.rs
+++ b/dns/src/record/txt.rs
@@ -18,7 +18,7 @@ use crate::wire::*;
pub struct TXT {
/// The messages contained in the record.
- pub messages: Vec<String>,
+ pub messages: Vec<Box<[u8]>>,
}
impl Wire for TXT {
@@ -50,8 +50,8 @@ impl Wire for TXT {
}
}
- let message = String::from_utf8_lossy(&buf).to_string();
- trace!("Parsed message -> {:?}", message);
+ let message = buf.into_boxed_slice();
+ trace!("Parsed message -> {:?}", String::from_utf8_lossy(&message));
messages.push(message);
if total_length >= stated_length {
@@ -85,7 +85,7 @@ mod test {
assert_eq!(TXT::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
TXT {
- messages: vec![ String::from("txt me") ],
+ messages: vec![ Box::new(*b"txt me") ],
});
}
@@ -124,15 +124,15 @@ mod test {
assert_eq!(TXT::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
TXT {
messages: vec![
- String::from("AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
- AAAAAAAAAAAAAAAAAAAAAAAAAAA"),
+ Box::new(*b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
+ AAAAAAAAAAAAAAAAAAAAAAAAAAA"),
],
});
// did you know you can just _write_ code like this, and nobody will stop you?
@@ -171,15 +171,15 @@ mod test {
assert_eq!(TXT::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
TXT {
messages: vec![
- String::from("BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
- BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
- BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
- BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
- BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
- BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
- BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
- BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
- BBBBBBBBBBBBBBBBBBBBBB"),
+ Box::new(*b"BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+ BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+ BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+ BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+ BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+ BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+ BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+ BBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
+ BBBBBBBBBBBBBBBBBBBBBB"),
],
});
}
@@ -196,8 +196,8 @@ mod test {
assert_eq!(TXT::read(buf.len() as _, &mut Cursor::new(buf)).unwrap(),
TXT {
messages: vec![
- String::from("txt me"),
- String::from("ya beb"),
+ Box::new(*b"txt me"),
+ Box::new(*b"ya beb"),
],
});
}
diff --git a/src/output.rs b/src/output.rs
index 6f4dda6..9ef1fba 100644
--- a/src/output.rs
+++ b/src/output.rs
@@ -276,7 +276,7 @@ impl TextFormat {
)
}
Record::TXT(txt) => {
- let messages = txt.messages.iter().map(|t| format!("{:?}", t)).collect::<Vec<_>>();
+ let messages = txt.messages.iter().map(|t| Ascii(t).to_string()).collect::<Vec<_>>();
messages.join(", ")
}
Record::URI(uri) => {
@@ -570,8 +570,11 @@ fn json_record_data(record: Record) -> JsonValue {
}
}
Record::TXT(txt) => {
+ let ms = txt.messages.into_iter()
+ .map(|txt| String::from_utf8_lossy(&txt).to_string())
+ .collect::<Vec<_>>();
object! {
- "messages": txt.messages,
+ "messages": ms,
}
}
Record::URI(uri) => {
diff --git a/xtests/madns/outputs/bad-utf8.txt.example.ansitxt b/xtests/madns/outputs/bad-utf8.txt.example.ansitxt
new file mode 100644
index 0000000..5db86df
--- /dev/null
+++ b/xtests/madns/outputs/bad-utf8.txt.example.ansitxt
@@ -0,0 +1 @@
+TXT bad-utf8.txt.example. 10m00s "\208\208\160\255"
diff --git a/xtests/madns/outputs/bad-utf8.txt.example.json b/xtests/madns/outputs/bad-utf8.txt.example.json
new file mode 100644
index 0000000..570df79
--- /dev/null
+++ b/xtests/madns/outputs/bad-utf8.txt.example.json
@@ -0,0 +1,28 @@
+{
+ "responses": [
+ {
+ "queries": [
+ {
+ "name": "bad-utf8.txt.example.",
+ "class": "IN",
+ "type": "TXT"
+ }
+ ],
+ "answers": [
+ {
+ "name": "bad-utf8.txt.example.",
+ "class": "IN",
+ "ttl": 600,
+ "type": "TXT",
+ "data": {
+ "messages": [
+ "�Р�"
+ ]
+ }
+ }
+ ],
+ "authorities": [],
+ "additionals": []
+ }
+ ]
+}
diff --git a/xtests/madns/outputs/utf8.txt.example.ansitxt b/xtests/madns/outputs/utf8.txt.example.ansitxt
new file mode 100644
index 0000000..ff16995
--- /dev/null
+++ b/xtests/madns/outputs/utf8.txt.example.ansitxt
@@ -0,0 +1 @@
+TXT utf8.txt.example. 10m00s "\240\159\146\176Cache \240\159\153\133\226\128\141\239\184\143Invalidation \226\133\139and \240\159\147\155Naming \240\159\142\179Things"
diff --git a/xtests/madns/outputs/utf8.txt.example.json b/xtests/madns/outputs/utf8.txt.example.json
new file mode 100644
index 0000000..2521272
--- /dev/null
+++ b/xtests/madns/outputs/utf8.txt.example.json
@@ -0,0 +1,28 @@
+{
+ "responses": [
+ {
+ "queries": [
+ {
+ "name": "utf8.txt.example.",
+ "class": "IN",
+ "type": "TXT"
+ }
+ ],
+ "answers": [
+ {
+ "name": "utf8.txt.example.",
+ "class": "IN",
+ "ttl": 600,
+ "type": "TXT",
+ "data": {
+ "messages": [
+ "💰Cache 🙅‍️Invalidation ⅋and 📛Naming 🎳Things"
+ ]
+ }
+ }
+ ],
+ "authorities": [],
+ "additionals": []
+ }
+ ]
+}
diff --git a/xtests/madns/txt-records.toml b/xtests/madns/txt-records.toml
index ce1f52a..f19d497 100644
--- a/xtests/madns/txt-records.toml
+++ b/xtests/madns/txt-records.toml
@@ -8,6 +8,22 @@ stderr = { empty = true }
status = 0
tags = [ "txt", "madns" ]
+[[cmd]]
+name = "Running with ‘utf8.txt.example’ escapes characters in the message"
+shell = "dog --colour=always ${MADNS_ARGS:-@madns.binarystar.systems:5301 --tcp} TXT utf8.txt.example"
+stdout = { file = "outputs/utf8.txt.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "txt", "madns", "chars" ]
+
+[[cmd]]
+name = "Running with ‘bad-utf8.txt.example’ escapes characters in the message and does not crash"
+shell = "dog --colour=always ${MADNS_ARGS:-@madns.binarystar.systems:5301 --tcp} TXT bad-utf8.txt.example"
+stdout = { file = "outputs/bad-utf8.txt.example.ansitxt" }
+stderr = { empty = true }
+status = 0
+tags = [ "txt", "madns", "chars" ]
+
# TXT record successes (JSON)
@@ -20,6 +36,23 @@ status = 0
tags = [ "txt", "madns", "json" ]
+[[cmd]]
+name = "Running with ‘utf8.txt.example --json’ interprets the response as UTF-8"
+shell = "dog --colour=always ${MADNS_ARGS:-@madns.binarystar.systems:5301 --tcp} TXT utf8.txt.example --json | jq"
+stdout = { file = "outputs/utf8.txt.example.json" }
+stderr = { empty = true }
+status = 0
+tags = [ "txt", "madns", "chars", "json" ]
+
+[[cmd]]
+name = "Running with ‘bad-utf8.txt.example --json’ uses UTF-8 replacement characters"
+shell = "dog --colour=always ${MADNS_ARGS:-@madns.binarystar.systems:5301 --tcp} TXT bad-utf8.txt.example --json | jq"
+stdout = { file = "outputs/bad-utf8.txt.example.json" }
+stderr = { empty = true }
+status = 0
+tags = [ "txt", "madns", "chars", "json" ]
+
+
# TXT record invalid packets
[[cmd]]