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

List like [[":,"]] is not parsed properly #56

Closed
rix0rrr opened this issue Dec 10, 2018 · 5 comments
Closed

List like [[":,"]] is not parsed properly #56

rix0rrr opened this issue Dec 10, 2018 · 5 comments
Labels
bug Something isn't working

Comments

@rix0rrr
Copy link

rix0rrr commented Dec 10, 2018

I wrote a property-based check for the yaml library using fast-check (https://github.com/dubzzz/fast-check) and it uncovered the following error:

> const YAML = require('yaml');
undefined
> YAML.stringify([[':,']])
'- - :,\n'
> YAML.parse('- - :,\n')
YAMLSyntaxError: Document is not valid YAML (bad indentation?)

I don't think this issue will impact us anytime soon, but you might want to be aware of it.


Here's my code (TypeScript) if you want to experiment more. Right now it will trigger mostly on the [[":,"]] bug and so will not make a lot of progress. I can only continue testing once that bug is fixed.

import fc = require('fast-check');
import YAML = require('yaml');
import deepEqual = require('deep-equal');
import { Arbitrary } from 'fast-check';

// Unfortunately it's hard to generate fully recursive type definitions
// so we'll unroll by hand a couple of times

function makeRecord<T, U>(a: Arbitrary<T>) {
  return fc.record({
    key1: a,
    key2: a
  });
}

const arbitraryJson0 = fc.oneof<string|number|boolean|null>(
  fc.string(),
  fc.integer(),
  fc.float(),
  fc.boolean(),
  fc.constant(null),
);


const arbitraryJson1 = fc.oneof<any>(
  arbitraryJson0,
  fc.array(arbitraryJson0),
  makeRecord(arbitraryJson0)
);

const arbitraryJson2 = fc.oneof<any>(
  arbitraryJson1,
  fc.array(arbitraryJson1),
  makeRecord(arbitraryJson1),
);

const arbitraryJson3 = fc.oneof<any>(
  arbitraryJson2,
  fc.array(arbitraryJson2),
  makeRecord(arbitraryJson2),
);


// Property #1: validate that stringifying and parsing are each other's inverse
// Do a manual sampling and test so that we can continue even if we find failing cases.
function isReversible(original: any) {
    const rendered = YAML.stringify(original);
    try {
      const parsed = YAML.parse(rendered);
      return deepEqual(original, parsed);
    } catch(e) {
      // Throwing is also bad
      return false;
    }
}

const N = 10000;

fc.assert(fc.property(arbitraryJson3, isReversible), {
  numRuns: N
});
@rix0rrr
Copy link
Author

rix0rrr commented Dec 10, 2018

To be clear, here's my package.json:

{
  "name": "testyaml",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@types/node": "^10.12.12",
    "deep-equal": "^1.0.1",
    "fast-check": "^1.8.1",
    "typescript": "^3.2.2",
    "yaml": "^1.0.3"
  }
}

When source saved to index.ts, run as:

tsc index && node index

@eemeli eemeli added the bug Something isn't working label Dec 11, 2018
@eemeli eemeli closed this as completed in dfac964 Dec 11, 2018
@eemeli
Copy link
Owner

eemeli commented Dec 11, 2018

Thank you for finding this! This was a bug in the parser, which was not properly checking the flow-in/flow-out context when parsing plain values that start with :,, which are only allowed outside of flow collections.

dubzzz added a commit to dubzzz/yaml that referenced this issue Dec 20, 2018
This commit is a follow up of the issues opened by @rix0rrr recently:
- eemeli#56
- eemeli#57
- eemeli#59
@dubzzz
Copy link
Contributor

dubzzz commented Dec 20, 2018

@rix0rrr @eemeli
Following the recent issues spotted by @rix0rrr and to prevent eventual regressions, I adapted a test of js-yaml using property based for your repo: dubzzz@3a8cb0a (I can issue a PR if you consider it can help detect problems earlier in the future)
Regards ;)

@eemeli
Copy link
Owner

eemeli commented Dec 20, 2018

@dubzzz Sure, do send in a PR: The test looks pretty good, and appears not to take too long to run. Presumably the inputs will vary between runs? As a small stylistic fix, the yaml prefixes on all the vars are a bit useless.

@dubzzz
Copy link
Contributor

dubzzz commented Dec 21, 2018

@eemeli

Indeed the inputs will vary from one run to another.
In case the test fails, it will give you back the seed causing the problem. You can reproduce the faulty run by simply re-using this seed - fc.assert(/* property */, { seed }).

In case of failure, the aim of such technic is to give you the minimal failing case and not horrible objects with thousands entries. So you might expect to have very clear and simple corner case to investigate if it happens to find an issue in the future.

eemeli pushed a commit that referenced this issue Dec 23, 2018
This commit is a follow up of the issues opened by @rix0rrr recently:
- #56
- #57
- #59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants