Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Can't tokenize alias as key without seperator #319

Open
stealthybox opened this issue Jan 12, 2017 · 2 comments
Open

Can't tokenize alias as key without seperator #319

stealthybox opened this issue Jan 12, 2017 · 2 comments

Comments

@stealthybox
Copy link

stealthybox commented Jan 12, 2017

js-yaml: @3.7.0
Node v7.2.1
Windows 10 Pro

disclaimer: I'm not an expert on the YAML spec

the bug

":" is a valid character when defining anchors and using aliases.
It is valid to use aliases as keys.

":" is also used to denote a node.
This seems to cause a bug where you are unable to use aliases as keys unless you separate the alias from the ":" with whitespace.

Trailing ":"'s look like they're being included in the alias token by the while loop in loader.readAlias().
I don't know the code very well, but a fix might need some extra logic in loader.composeNode().

some tests

const tests = [
  // working cases  (space before `:`)
  `
    adjective: &adj  stealthy!
    *adj :           box :)
  `,
  `
    adjective: &adj: stealthy!
    *adj: :          box :)
  `,
  `
    adjective: &:    stealthy!
    *: :             box :)
  `,
  // broken cases  (no space)
  `
    adjective: &adj  stealthy!
    *adj:            box :)
  `,
  `
    adjective: &adj: stealthy!
    *adj::           box :)
  `,
  `
    adjective: &:    stealthy!
    *::              box :)
  `,
]
for ( const content of tests )
  try{ console.log(require('js-yaml').load(content)) }
  catch(e) { console.log(e) }

output

{ adjective: 'stealthy!', 'stealthy!': 'box :)' }
{ adjective: 'stealthy!', 'stealthy!': 'box :)' }
{ adjective: 'stealthy!', 'stealthy!': 'box :)' }
{ Error
    at generateError (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:162:10)
    at throwError (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:168:9)
    at readAlias (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1244:5)
    at composeNode (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1336:20)
    at readBlockMapping (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1004:16)
    at composeNode (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1327:12)
    at readDocument (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1489:3)
    at loadDocuments (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1545:5)
    at Object.load (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1562:19)
    at Object.<anonymous> (C:\Users\leigh\repos\puppet\test-site\data\yaml.js:31:25)
  name: 'YAMLException',
  reason: 'unidentified alias "adj:"',
  mark:
   Mark {
     name: null,
     buffer: '\n    adjective: &adj  stealthy!\n    *adj:            box :)\n  \n\u0000',
     position: 41,
     line: 2,
     column: 9 },
  message: 'unidentified alias "adj:" at line 3, column 10:\n        *adj:            box :)\n             ^' }
{ Error
    at generateError (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:162:10)
    at throwError (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:168:9)
    at readAlias (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1244:5)
    at composeNode (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1336:20)
    at readBlockMapping (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1004:16)
    at composeNode (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1327:12)
    at readDocument (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1489:3)
    at loadDocuments (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1545:5)
    at Object.load (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1562:19)
    at Object.<anonymous> (C:\Users\leigh\repos\puppet\test-site\data\yaml.js:31:25)
  name: 'YAMLException',
  reason: 'unidentified alias "adj::"',
  mark:
   Mark {
     name: null,
     buffer: '\n    adjective: &adj: stealthy!\n    *adj::           box :)\n  \n\u0000',
     position: 42,
     line: 2,
     column: 10 },
  message: 'unidentified alias "adj::" at line 3, column 11:\n        *adj::           box :)\n              ^' }
{ Error
    at generateError (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:162:10)
    at throwError (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:168:9)
    at readAlias (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1244:5)
    at composeNode (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1336:20)
    at readBlockMapping (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1004:16)
    at composeNode (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1327:12)
    at readDocument (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1489:3)
    at loadDocuments (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1545:5)
    at Object.load (C:\Users\leigh\repos\puppet\test-site\data\node_modules\js-yaml\lib\js-yaml\loader.js:1562:19)
    at Object.<anonymous> (C:\Users\leigh\repos\puppet\test-site\data\yaml.js:31:25)
  name: 'YAMLException',
  reason: 'unidentified alias "::"',
  mark:
   Mark {
     name: null,
     buffer: '\n    adjective: &:    stealthy!\n    *::              box :)\n  \n\u0000',
     position: 39,
     line: 2,
     column: 7 },
  message: 'unidentified alias "::" at line 3, column 8:\n        *::              box :)\n           ^' }
@perlpunk
Copy link

perlpunk commented Aug 3, 2018

This is an edge case. The spec is not very clear on that.
@flyx mentioned that he had been asking about that on the mailing list two years ago: https://sourceforge.net/p/yaml/mailman/message/34909032/

I would generally add a space after an alias key to make sure it's portable. It should also be noted that libyaml and pyyaml do not support : anywhere in aliases/anchors.

When playing with that, it seems I found a bug in libyaml, pyyaml and snakeyaml:
foo: &a:b bar is parsed the same as foo: &a :b bar

So I would avoid : in aliases completely.

@stealthybox
Copy link
Author

@perlpunk
In personal experience, I have not seen other usage in which people add spaces after their aliases to mitigate this problem, but it's good advice for compat /w this version of js-yaml.

I agree about disallowing : in aliases in the tokenizer.
Since the spec is so lax on this point, it's probably a source of implementation specific divergences like you discovered.

Neat find!

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants