Skip to content

Replace the yaml.js library with another YAML parser #165

Description

@generalmimon

So far we've been using jeremyfa/yaml.js to parse YAML in the Web IDE. However, it is more or less abandoned. Last release 0.3.0 was published on 2017-06-24 and there's a note at the top of its README that it is unlikely to receive new features or bugfixes (https://github.com/jeremyfa/yaml.js/tree/efe8ce18704ae43383e4177aa7de1a2619bd4e67#readme):

Development of this library has slowed-down

(...) I don't have much bandwidth to actively provide support to the posted issues asking for new features or bugfixes that don't affect my own use cases of the library. If this situation is an issue for you, I suggest you use js-yaml which is a great and pretty feature-complete yaml parser and dumper for javascript.

But more importantly, we've encountered a number of real problems with jeremyfa/yaml.js in the Web IDE over time (more on that in following comments). So it has long been clear that it's time to switch to another library.

As described at https://philna.sh/blog/2023/02/02/yaml-document-from-hell-javascript-edition/#yaml-in-javascript, there are 3 JavaScript libraries available for YAML parsing:

  1. https://github.com/jeremyfa/yaml.js
  2. https://github.com/nodeca/js-yaml
  3. https://github.com/eemeli/yaml

I wasn't sure whether option 2 or 3 would be a better choice, so I wanted to do some tests. Also, @GreyCat mentioned in https://github.com/kaitai-io/kaitai_struct_webide/pull/84/files#r276498978 that he'd want to make sure that the new YAML parsing library addresses the issues of the old one:

This is actually a pretty big deal, as replacement of this library means that we'll need to re-evaluate all the complaints about YAML parsing - like #63

Please at least put a note about this library change - what exactly is changing and why - into PR info.

So I wrote a few scripts for testing and comparing the parsing results and put them in a repo: https://github.com/generalmimon/js-yaml-parsers-test

Both libraries seem to be pretty solid, definitely better than jeremyfa/yaml.js that we've been using. They both solve many pain points of jeremyfa/yaml.js - I'll list below the issues solved by switching to either library.

Legend to all diffs below:

--- 1/results/yamljs.txt
+++ 2/results/js-yaml.txt
@@ ... @@
  1. No more broken hex literal parsing

  2. No more parsing YAML 1.1 binary literals (0b...) or YAML 1.2 octal literals (0o...) as 0

  3. Flow-style multi-line strings don't trigger a parse error and are parsed correctly as per the spec (i.e. single newlines should not translate to \n in the output string, a double newline is needed for this, see https://yaml-multiline.info/#flow-scalars-plain)

  4. A mapping key-value pair of a mapping indented more than the previous one is considered an error, not included in the value of the previous key-value pair

  5. The notorious colon : as part of the ternary operator in an unquoted string is no longer allowed, which is consistent with the SnakeYAML library used in the JVM compiler (and it is in fact correct behavior according to the YAML spec, see https://matrix.yaml.info/details/ZCZ6.html and https://matrix.yaml.info/details/ZL4Z.html)

  6. Duplicate mapping keys are rejected with an error (this is the default behavior in both nodeca/js-yaml and eemeli/yaml), not silently allowed as in jeremyfa/yaml.js, where only the first entry is kept (i.e. resulting in a data loss, which tends to be surprising for many people that don't know this property of YAML)

    Details
    meta:
      id: yaml_dup_keys
    seq:
      - id: foo
        type: u1
    seq:
      - id: bar
        type: u1
    -{ meta: { id: 'yaml_dup_keys' }, seq: [ { id: 'foo', type: 'u1' } ] }
    +ERROR:
    +> YAMLException: duplicated mapping key in "input.ksy" (6:1)
    +>
    +>  3 | seq:
    +>  4 |   - id: foo
    +>  5 |     type: u1
    +>  6 | seq:
    +> -----^
    +>  7 |   - id: bar
    +>  8 |     type: u1

    (see https://github.com/generalmimon/js-yaml-parsers-test/blob/662870c1c092b8092f458f8ad94c23b3ad62f93c/results-diffs/yamljs_vs_js-yaml.diff#L151-L170)

    Note that this behavior has been suggested several times before:

    In 0.9, the feature of treating duplicate keys as errors was enabled in SnakeYAML used in JVM compiler builds: Multiple type declarations behaviour kaitai_struct#641 (comment)

  7. Comment lines do not suspend counting of line numbers displayed in error messages like they do in jeremyfa/yaml.js

    • Fixes Invalid line number while parsing YAML if comments are used #62

      Details
      # Line 1
      # Line 2
      # Line 3
      # Line 4
      types:
        animal:
            doc: An animal species
          seq:  # line 8, but yaml.js says line 4!
            - id: species
              type: s4
      -> <ParseException> Indentation problem. (line 4: '  seq:  # line 8, but yaml.js says line 4!')
      +> YAMLException: bad indentation of a mapping entry in "input.ksy" (8:5)
      +>
      +>  5 | types:
      +>  6 |   animal:
      +>  7 |       doc: An animal species
      +>  8 |     seq:  # line 8, but yaml.js says ...
      +> ---------^
      +>  9 |       - id: species
      +>  10 |         type: s4
  8. JSON is accepted

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions