Skip to content

identifiers equal to a keyword are not quoted #132

@sodiboo

Description

@sodiboo

Here's some test code:

use kdl::{KdlDocument, KdlNode};

#[test]
fn keywords() -> miette::Result<()> {
    let mut node = KdlNode::new("null");
    node.insert("inf", "-inf");
    node.push("nan");
    node.insert("true", "false");

    let mut document = KdlDocument::new();
    document.nodes_mut().push(node);

    let string = document.to_string();

    KdlDocument::parse_v2(&string)?;

    Ok(())
}

The document doesn't survive a roundtrip through stringify and parse.

---- keywords stdout ----
Error:   × Failed to parse KDL document

Error: 
  × Expected identifier string
   ╭────
 1null inf=-inf nan true=false
   · ──┬─
   ·   ╰── not identifier string
   ╰────

Error: 
  × Found invalid node name
   ╭────
 1null inf=-inf nan true=false
   · ──┬─
   ·   ╰── not node name
   ╰────
  help: This can be any string type, including a quoted, raw, or multiline string, as well as a plain identifier string.

Error: 
  × Expected identifier string
   ╭────
 1null inf=-inf nan true=false
   ·      ─┬─
   ·       ╰── not identifier string
   ╰────

Error: 
  × Expected identifier string
   ╭────
 1null inf=-inf nan true=false
   ·               ─┬─
   ·                ╰── not identifier string
   ╰────

Error: 
  × Expected identifier string
   ╭────
 1null inf=-inf nan true=false
   ·                   ──┬─
   ·                     ╰── not identifier string
   ╰────

Error: 
  × Expected identifier string
   ╭────
 1null inf=-inf nan true=false
   ·                        ──┬──
   ·                          ╰── not identifier string
   ╰────

Interestingly, there is no error on -inf. It is incorrectly serialized without quotes, and incorrectly parsed as an identifier string. The spec disallows this.

Other kinds of non-identifier strings, like numeric confusables, are quoted fine, i think? It's just the keywords.


v1 identifiers are also not quoted correctly:

use kdl::{KdlDocument, KdlNode};

#[test]
fn keywords_v1() -> miette::Result<()> {
    let mut node = KdlNode::new("null");
    node.insert("true", "true");
    node.insert("false", "false");
    node.insert("nan", "nan");
    node.insert("inf", "inf");
    node.insert("-inf", "-inf");

    let mut document = KdlDocument::new();
    document.nodes_mut().push(node);

    document.ensure_v1();

    let string = document.to_string();

    KdlDocument::parse_v1(&string)?;

    Ok(())
}

The error is much less useful.

---- keywords_v1 stdout ----
Error:   × Failed to parse KDL document

Error: 
  × An unspecified error occurred.
   ╭────
 1null true="true" false="false" nan="nan" inf="inf" -inf="-inf";
   · ▲
   · ╰── here
   ╰────

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions