switch from OLPC canonical JSON to a JSON subset
fixes #92
diff --git a/src/interchange/cjson.rs b/src/interchange/cjson.rs
index f0baee8..397bfc5 100644
--- a/src/interchange/cjson.rs
+++ b/src/interchange/cjson.rs
@@ -1,7 +1,6 @@
use itoa;
use json;
use std::collections::BTreeMap;
-use std::io;
pub fn canonicalize(jsn: &json::Value) -> Result<Vec<u8>, String> {
let converted = convert(jsn)?;
@@ -36,7 +35,11 @@
})
}
&Value::String(ref s) => {
- escape_str(&mut buf, &s).map_err(|err| format!("Write error: {}", err))
+ // this mess is abusing serde_json to get json escaping
+ let s = json::Value::String(s.clone());
+ let s = json::to_string(&s)
+ .map_err(|e| format!("{:?}", e))?;
+ Ok(buf.extend(s.as_bytes()))
}
&Value::Array(ref arr) => {
buf.push(b'[');
@@ -58,9 +61,13 @@
buf.push(b',');
}
first = false;
- escape_str(&mut buf, &k).map_err(|err| {
- format!("Write error: {}", err)
- })?;
+
+ // this mess is abusing serde_json to get json escaping
+ let k = json::Value::String(k.clone());
+ let k = json::to_string(&k)
+ .map_err(|e| format!("{:?}", e))?;
+ buf.extend(k.as_bytes());
+
buf.push(b':');
v.write(&mut buf)?;
}
@@ -104,73 +111,10 @@
}
}
-/// Serializes and escapes a `&str` into a JSON string.
-fn escape_str<W>(wr: &mut W, value: &str) -> Result<(), io::Error>
-where
- W: io::Write,
-{
- let bytes = value.as_bytes();
-
- wr.write_all(b"\"")?;
-
- let mut start = 0;
-
- for (i, &byte) in bytes.iter().enumerate() {
- let escape = ESCAPE[byte as usize];
- if escape == 0 {
- continue;
- }
-
- if start < i {
- wr.write_all(&bytes[start..i])?;
- }
-
- wr.write_all(&[b'\\', escape])?;
-
- start = i + 1;
- }
-
- if start != bytes.len() {
- wr.write_all(&bytes[start..])?;
- }
-
- wr.write_all(b"\"")?;
- Ok(())
-}
-
-const QU: u8 = b'"'; // \x22
-const BS: u8 = b'\\'; // \x5C
-
-// Lookup table of escape sequences. A value of b'x' at index i means that byte
-// i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped.
-#[cfg_attr(rustfmt, rustfmt_skip)]
-static ESCAPE: [u8; 256] = [
- // 1 2 3 4 5 6 7 8 9 A B C D E F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
- 0, 0, QU, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, BS, 0, 0, 0, // 5
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F
-];
-
#[cfg(test)]
mod test {
use super::*;
- use std::fs::File;
- use std::io::Read;
-
#[test]
fn write_str() {
let jsn = Value::String(String::from("wat"));
@@ -204,25 +148,4 @@
jsn.write(&mut out).expect("write failed");
assert_eq!(&out, b"{\"lol\":[\"haha\",\"omg so tired\"]}");
}
-
- #[test]
- fn root_json() {
- let mut file = File::open("./tests/cjson/root.json").expect("couldn't open root.json");
- let mut buf = String::new();
- file.read_to_string(&mut buf).expect(
- "couldn't read root.json",
- );
-
- let mut file = File::open("./tests/cjson/root.cjson").expect("couldn't open root.cjson");
- let mut cjsn = String::new();
- file.read_to_string(&mut cjsn).expect(
- "couldn't read root.cjson",
- );
-
- let ref jsn = json::from_str(&buf).expect("not json");
- let out = canonicalize(jsn).expect("couldn't canonicalize");
- let out = ::std::str::from_utf8(&out).expect("not utf-8");
-
- assert_eq!(out, cjsn);
- }
}
diff --git a/tests/cjson/root.cjson b/tests/cjson/root.cjson
deleted file mode 100644
index e132582..0000000
--- a/tests/cjson/root.cjson
+++ /dev/null
@@ -1,33 +0,0 @@
-{"signatures":[{"keyid":"ed3c845525d34937bf0584989a76fa300c0a6072de714b11b8dca535e10b9088","method":"rsassa-pss-sha256","sig":"49bdc0586c83afad062c608a70a5cfd6dd32bf47eb7830960322723615f723fbf43c7d80dab455b08114624d89de740b2547bece8fda01a8acaecf651fcbe98f291971de695fb2f00889bd1ec076e9d431c4c004791dc5e223f023301eca865c0ede005952dfa4fc7b1a591f8875445872d6162039d5e59418998e0c99a15ad28689b82b72099926354ca253cffafe7a3f7ececb9ecddda35cecb05ea9ca184c7ea942ea8a1a49b7445803dd3a14d74697d220f59cef5d56bc9b640d8aca2328f0d6ea4aa25ba79164ecdf31904a176b6100188970d37860c2612cf4571613fdbaa29080be50cae2966dd46a677acaf1dd500d7a86d025877aab0fdaa72f1856"}],"signed":{"_type":"Root","consistent_snapshot":false,"expires":"2038-01-19T03:14:06Z","keys":{"0bde74244f238cd6d4e3839d35a5b248d6cde5759b760ebdbee45a386109a41a":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8QLzN27B3+DKhWR8nJZO
-ScZ6XS2mubhqcr3giT+WJejjVH4zIlaeC5tosaY96VKI5vRd4aFgQwq2XEx+YTJM
-dAaUGOUSvPYa+iv+O0ilPeYyXazoCaxEDj5c5EQCWJh5EJO+6fdnF7oqFrfGk2kx
-54kY8wBfYEr2psXLTuidKLmxu1gZLymRcH7oDHggFahii0HqXGUSrcTzsuqLI83/
-ulQ0VmJhkY9zooTgh+NhUvKKVGNy7O2rNQLzPXFyeun9bOeKhKiCnUIt0kxtFJPg
-l6u8X46qg4uKqVbDbv2oUV5jTfVDlGwJVAWvC8JPC8N1P0BRmGGqA3NGxpmMRBa6
-fQIDAQAB
------END PUBLIC KEY-----"}},"a4304752b0a81316df3d0d1c331e882fe284f1239fe394f31211a19da02e16bd":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoeX9pEiyvBLIl46oLfUJ
-KphECc0sojOmVEtp9rAP/aChHdYHl3usyOexNyQNX7vucmk9rnK/aOFJwo5Mtf5r
-Yl4sIMK5jqI2mvjGjuminjBDGoLCRiK3mFxAGyr4t0AtxtpW8AR4tvgUfl3DS+aB
-XRYBhsx6zndQsPfrggakyv9xeA4uORDQ2ivrq+4BkDCXo65ZA61qFSsfPaShfij0
-klGPLVbyTMc+offlfiiL6ogd6MI49wNb+IDslAPfwrPZ4M3SLWVMmb6+JclFzwp0
-p+CURLWXCptDC9muFSMxZTwaBWBiresHEN36zBoU27ziZCNHpaIgGhjRaJVjzjBo
-MQIDAQAB
------END PUBLIC KEY-----"}},"dbfa99f76c6a89191a6747a5e6ed63da202ce77a1f32ae85e152f325ca9a4117":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr0weyzfZ42HVeafaN3WN
-Tz9PNsy/p2AqgPWYLD/lZRO0VwTRfQ/IM30NQ2DdK1Nu/uEkKTFs+Opx1sL+ezCJ
-M2BtqxZKzWlpdGR5Fu2VhXC+pd4FzSBPD3H70Ln85fsww2dnJOVZyxL++vgRKj/I
-QM26ind9pkDhdowSj9bu45Sn8M1BJ7WWoxj4JMficgeSQ4DhrP6Xx326hLLOp0uf
-LxJbNNCeBqlmpZR+wi5MO21L+1JLEhFxCpmrhii4IILi6zooi5Je8RLW544IkzQE
-5sCX/q9PdnEXc7yOKksja9J6tHcUR6cLWdbGAH4MpUGaT91eDKMh9nNNtwoDpDNV
-qwIDAQAB
------END PUBLIC KEY-----"}},"ed3c845525d34937bf0584989a76fa300c0a6072de714b11b8dca535e10b9088":{"keytype":"rsa","keyval":{"public":"-----BEGIN PUBLIC KEY-----
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAndqFFxVnq7FjihMB7sBj
-fMMIS2112HB0PauY7wDQ8gTnfbWkCOOQ2kvh0f8Ph41rQ1iZiPaZq+eQ+yqhPCsP
-JKSeq9H8oOCon4JI5afSTUTkC0NmA1SN3cMMJvUgNr+uBWOc+IHr90o6xBTuzplm
-nzzjGCGNaOMLt7P3yuF8q9UXb1DBOBvqYutGB5UB+9Ma0K4c5lMnUy0IVb6j1tEC
-FKSi4RTepA5UAOV5LE2T6Gs89kRjhTxvVsKAAj92z3VGX5pJR9zm6ZrAbjSen9Lf
-vFWgd2Hz1Qy4d9Jm0iSaJb5VG06/O4JMT1FXfIv2OP5NlzKoyDxp5ZEVLHWNksHH
-awIDAQAB
------END PUBLIC KEY-----"}}},"roles":{"root":{"keyids":["ed3c845525d34937bf0584989a76fa300c0a6072de714b11b8dca535e10b9088"],"threshold":1},"snapshot":{"keyids":["dbfa99f76c6a89191a6747a5e6ed63da202ce77a1f32ae85e152f325ca9a4117"],"threshold":1},"targets":{"keyids":["0bde74244f238cd6d4e3839d35a5b248d6cde5759b760ebdbee45a386109a41a"],"threshold":1},"timestamp":{"keyids":["a4304752b0a81316df3d0d1c331e882fe284f1239fe394f31211a19da02e16bd"],"threshold":1}},"version":1}}
\ No newline at end of file
diff --git a/tests/cjson/root.json b/tests/cjson/root.json
deleted file mode 100644
index 4aee181..0000000
--- a/tests/cjson/root.json
+++ /dev/null
@@ -1,67 +0,0 @@
-{
- "signatures": [
- {
- "keyid": "ed3c845525d34937bf0584989a76fa300c0a6072de714b11b8dca535e10b9088",
- "method": "rsassa-pss-sha256",
- "sig": "49bdc0586c83afad062c608a70a5cfd6dd32bf47eb7830960322723615f723fbf43c7d80dab455b08114624d89de740b2547bece8fda01a8acaecf651fcbe98f291971de695fb2f00889bd1ec076e9d431c4c004791dc5e223f023301eca865c0ede005952dfa4fc7b1a591f8875445872d6162039d5e59418998e0c99a15ad28689b82b72099926354ca253cffafe7a3f7ececb9ecddda35cecb05ea9ca184c7ea942ea8a1a49b7445803dd3a14d74697d220f59cef5d56bc9b640d8aca2328f0d6ea4aa25ba79164ecdf31904a176b6100188970d37860c2612cf4571613fdbaa29080be50cae2966dd46a677acaf1dd500d7a86d025877aab0fdaa72f1856"
- }
- ],
- "signed": {
- "_type": "Root",
- "consistent_snapshot": false,
- "expires": "2038-01-19T03:14:06Z",
- "keys": {
- "0bde74244f238cd6d4e3839d35a5b248d6cde5759b760ebdbee45a386109a41a": {
- "keytype": "rsa",
- "keyval": {
- "public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8QLzN27B3+DKhWR8nJZO\nScZ6XS2mubhqcr3giT+WJejjVH4zIlaeC5tosaY96VKI5vRd4aFgQwq2XEx+YTJM\ndAaUGOUSvPYa+iv+O0ilPeYyXazoCaxEDj5c5EQCWJh5EJO+6fdnF7oqFrfGk2kx\n54kY8wBfYEr2psXLTuidKLmxu1gZLymRcH7oDHggFahii0HqXGUSrcTzsuqLI83/\nulQ0VmJhkY9zooTgh+NhUvKKVGNy7O2rNQLzPXFyeun9bOeKhKiCnUIt0kxtFJPg\nl6u8X46qg4uKqVbDbv2oUV5jTfVDlGwJVAWvC8JPC8N1P0BRmGGqA3NGxpmMRBa6\nfQIDAQAB\n-----END PUBLIC KEY-----"
- }
- },
- "a4304752b0a81316df3d0d1c331e882fe284f1239fe394f31211a19da02e16bd": {
- "keytype": "rsa",
- "keyval": {
- "public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoeX9pEiyvBLIl46oLfUJ\nKphECc0sojOmVEtp9rAP/aChHdYHl3usyOexNyQNX7vucmk9rnK/aOFJwo5Mtf5r\nYl4sIMK5jqI2mvjGjuminjBDGoLCRiK3mFxAGyr4t0AtxtpW8AR4tvgUfl3DS+aB\nXRYBhsx6zndQsPfrggakyv9xeA4uORDQ2ivrq+4BkDCXo65ZA61qFSsfPaShfij0\nklGPLVbyTMc+offlfiiL6ogd6MI49wNb+IDslAPfwrPZ4M3SLWVMmb6+JclFzwp0\np+CURLWXCptDC9muFSMxZTwaBWBiresHEN36zBoU27ziZCNHpaIgGhjRaJVjzjBo\nMQIDAQAB\n-----END PUBLIC KEY-----"
- }
- },
- "dbfa99f76c6a89191a6747a5e6ed63da202ce77a1f32ae85e152f325ca9a4117": {
- "keytype": "rsa",
- "keyval": {
- "public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr0weyzfZ42HVeafaN3WN\nTz9PNsy/p2AqgPWYLD/lZRO0VwTRfQ/IM30NQ2DdK1Nu/uEkKTFs+Opx1sL+ezCJ\nM2BtqxZKzWlpdGR5Fu2VhXC+pd4FzSBPD3H70Ln85fsww2dnJOVZyxL++vgRKj/I\nQM26ind9pkDhdowSj9bu45Sn8M1BJ7WWoxj4JMficgeSQ4DhrP6Xx326hLLOp0uf\nLxJbNNCeBqlmpZR+wi5MO21L+1JLEhFxCpmrhii4IILi6zooi5Je8RLW544IkzQE\n5sCX/q9PdnEXc7yOKksja9J6tHcUR6cLWdbGAH4MpUGaT91eDKMh9nNNtwoDpDNV\nqwIDAQAB\n-----END PUBLIC KEY-----"
- }
- },
- "ed3c845525d34937bf0584989a76fa300c0a6072de714b11b8dca535e10b9088": {
- "keytype": "rsa",
- "keyval": {
- "public": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAndqFFxVnq7FjihMB7sBj\nfMMIS2112HB0PauY7wDQ8gTnfbWkCOOQ2kvh0f8Ph41rQ1iZiPaZq+eQ+yqhPCsP\nJKSeq9H8oOCon4JI5afSTUTkC0NmA1SN3cMMJvUgNr+uBWOc+IHr90o6xBTuzplm\nnzzjGCGNaOMLt7P3yuF8q9UXb1DBOBvqYutGB5UB+9Ma0K4c5lMnUy0IVb6j1tEC\nFKSi4RTepA5UAOV5LE2T6Gs89kRjhTxvVsKAAj92z3VGX5pJR9zm6ZrAbjSen9Lf\nvFWgd2Hz1Qy4d9Jm0iSaJb5VG06/O4JMT1FXfIv2OP5NlzKoyDxp5ZEVLHWNksHH\nawIDAQAB\n-----END PUBLIC KEY-----"
- }
- }
- },
- "roles": {
- "root": {
- "keyids": [
- "ed3c845525d34937bf0584989a76fa300c0a6072de714b11b8dca535e10b9088"
- ],
- "threshold": 1
- },
- "snapshot": {
- "keyids": [
- "dbfa99f76c6a89191a6747a5e6ed63da202ce77a1f32ae85e152f325ca9a4117"
- ],
- "threshold": 1
- },
- "targets": {
- "keyids": [
- "0bde74244f238cd6d4e3839d35a5b248d6cde5759b760ebdbee45a386109a41a"
- ],
- "threshold": 1
- },
- "timestamp": {
- "keyids": [
- "a4304752b0a81316df3d0d1c331e882fe284f1239fe394f31211a19da02e16bd"
- ],
- "threshold": 1
- }
- },
- "version": 1
- }
-}