Skip to content
New issue

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

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

Already on GitHub? Sign in 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!

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

No branches or pull requests

2 participants