difftreelog
fix(nixlike) string roundtrips
in: trunk
6 files changed
crates/nixlike/fuzz/.gitignorediffbeforeafterboth--- /dev/null
+++ b/crates/nixlike/fuzz/.gitignore
@@ -0,0 +1,4 @@
+
+target
+corpus
+artifacts
crates/nixlike/fuzz/Cargo.lockdiffbeforeafterbothno changes
crates/nixlike/fuzz/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/crates/nixlike/fuzz/Cargo.toml
@@ -0,0 +1,26 @@
+
+[package]
+name = "nixlike-fuzz"
+version = "0.0.0"
+authors = ["Automatically generated"]
+publish = false
+edition = "2018"
+
+[package.metadata]
+cargo-fuzz = true
+
+[dependencies]
+libfuzzer-sys = "0.4"
+
+[dependencies.nixlike]
+path = ".."
+
+# Prevent this from interfering with workspaces
+[workspace]
+members = ["."]
+
+[[bin]]
+name = "fuzz_target_1"
+path = "fuzz_targets/fuzz_target_1.rs"
+test = false
+doc = false
crates/nixlike/fuzz/fuzz_targets/fuzz_target_1.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/nixlike/fuzz/fuzz_targets/fuzz_target_1.rs
@@ -0,0 +1,9 @@
+#![no_main]
+use libfuzzer_sys::fuzz_target;
+
+fuzz_target!(|data: String| {
+ let serialized = nixlike::serialize(data.clone()).unwrap();
+ let deserialized: String = nixlike::parse_str(&serialized).unwrap();
+
+ assert_eq!(data, deserialized);
+});
crates/nixlike/src/lib.rsdiffbeforeafterboth--- a/crates/nixlike/src/lib.rs
+++ b/crates/nixlike/src/lib.rs
@@ -40,6 +40,10 @@
rule string_char() -> &'input str
= "\\\"" { "\"" }
/ "\\\\" { "\\" }
+ / "\\n" { "\n" }
+ / "\\t" { "\t" }
+ / "\\r" { "\r" }
+ / "''$" { "$" }
/ c:$([_]) { c }
rule string() -> String
= quiet! { "\"" v:(!"\"" c:string_char() {c})* "\"" { v.into_iter().collect() } } / expected!("<string>")
@@ -47,7 +51,10 @@
= quiet! { "true" {true}
/ "false" {false} } / expected!("<boolean>")
rule indent() -> String
- = quiet! { s:$(['a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '-']+) { s.to_owned() } } / expected!("<identifier>")
+ = quiet! {
+ s:$(['a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '-']+) { s.to_owned() }
+ / "\"" s:$(['a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '-' | '.']+) "\"" { s.to_owned() }
+ } / expected!("<identifier>")
rule object() -> LinkedHashMap<String, Value>
= "{" _
e:(k:indent()++(_ "." _) _ "=" _ v:value() _ ";" _ {(k, v)})*
@@ -111,20 +118,5 @@
#[test]
fn test() {
- let v: serde_json::Value = parse_str(
- r#"
- {
- b.c = 2;
- b.d = "hello";
- c = {
- k = 123;
- p = 231;
- ll = [1 2 3 [] [[4 5 6]] ];
- };
- }
- "#,
- )
- .unwrap();
- let s: String = serialize(v).unwrap();
- println!("{}", s);
+ assert_eq!(serialize("Hello\nworld").unwrap(), "\"Hello\\nworld\"");
}
crates/nixlike/src/to_string.rsdiffbeforeafterboth--- a/crates/nixlike/src/to_string.rs
+++ b/crates/nixlike/src/to_string.rs
@@ -5,7 +5,13 @@
};
fn write_nix_obj_key_buf(k: &str, v: &Value, out: &mut PrintItems) {
- out.push_str(k);
+ if k.contains(".") {
+ out.push_str("\"");
+ out.push_str(k);
+ out.push_str("\"");
+ } else {
+ out.push_str(k);
+ }
match v {
Value::Object(o) if o.len() == 1 => {
let (k, v) = o.iter().next().unwrap();
@@ -26,7 +32,15 @@
Value::Null => out.push_str("null"),
Value::Boolean(v) => out.push_str(if *v { "true" } else { "false" }),
Value::Number(n) => out.push_str(&format!("{}", n)),
- Value::String(s) => out.push_str(&format!("{:?}", s)),
+ Value::String(s) => out.push_str(&format!(
+ "\"{}\"",
+ s.replace('\\', "\\\\")
+ .replace('"', "\\\"")
+ .replace('\n', "\\n")
+ .replace('\t', "\\t")
+ .replace('\r', "\\r")
+ .replace("$", "''$")
+ )),
Value::Array(a) => {
if a.is_empty() {
out.push_str("[ ]");