Skip to content

Specific use of !!binary causes TypeError: Cannot read properties of undefined (reading 'buffer') when .toJS()/.toJSON() #610

Closed

Description

@cxcorp

Describe the bug
The following YAML causes an unhandled error when calling parse() or parseDocument().toJS(), and the error message does not sound like it is intended behavior.

? ? !!binary ? !!binary

To Reproduce

Welcome to Node.js v22.14.0.
Type ".help" for more information.
> const {parse} = require("yaml")
undefined
> parse('? ? !!binary ? !!binary')
Uncaught TypeError: Cannot read properties of undefined (reading 'buffer')
    at Object.stringify (yaml-fuzz/node_modules/yaml/dist/schema/yaml-1.1/binary.js:43:51)
    at Object.stringify (yaml-fuzz/node_modules/yaml/dist/stringify/stringify.js:120:18)
    at Object.stringifyPair (yaml-fuzz/node_modules/yaml/dist/stringify/stringifyPair.js:34:25)
    at Pair.toString (yaml-fuzz/node_modules/yaml/dist/nodes/Pair.js:33:29)
    at Object.stringify (yaml-fuzz/node_modules/yaml/dist/stringify/stringify.js:95:21)
    at stringifyFlowCollection (yaml-fuzz/node_modules/yaml/dist/stringify/stringifyCollection.js:106:29)
    at Object.stringifyCollection (yaml-fuzz/node_modules/yaml/dist/stringify/stringifyCollection.js:10:12)
    at YAMLMap.toString (yaml-fuzz/node_modules/yaml/dist/nodes/YAMLMap.js:136:36)
    at stringifyKey (yaml-fuzz/node_modules/yaml/dist/nodes/addPairToJSMap.js:51:28)
> (node:1635) [TAG_RESOLVE_FAILED] YAMLWarning: Unresolved tag: tag:yaml.org,2002:binary at line 1, column 5:

? ? !!binary ? !!binary
    ^^^^^^^^

(Use `node --trace-warnings ...` to show where the warning was created)
(node:1635) Warning: Keys with collection values will be stringified due to JS Object restrictions: "". Set mapAsMap: true to use object keys.

Expected behaviour
I would expect it to return the JS/JSON representation, or throw a YAMLParseError. I'm not quite sure what the expected value is as I just bumped into this error while fuzzing yaml.

Versions (please complete the following information):

  • Environment: Node v22.14.0
  • yaml: 2.7.0

Activity

  1. cxcorp commented on Mar 15, 2025

    @cxcorp
    Author

    This seems to be something related to using complex keys with tags, as the following also produces an error:

    ? ? !!timestamp ? !!timestamp 2025-03-15T15:35:58.586Z

    e.g. with Node REPL

    > require("yaml").parse('? ? !!timestamp ? !!timestamp 2025-03-15T15:35:58.586Z')
    yaml-fuzz/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js:100
        stringify: ({ value }) => value.toISOString().replace(/(T00:00:00)?\.000Z$/, '')
                                        ^
    
    TypeError: Cannot read properties of undefined (reading 'toISOString')
        at Object.stringify (yaml-fuzz/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js:100:37)
        at Object.stringify (yaml-fuzz/node_modules/yaml/dist/stringify/stringify.js:120:18)
        at Object.stringifyPair (yaml-fuzz/node_modules/yaml/dist/stringify/stringifyPair.js:34:25)
        at Pair.toString (yaml-fuzz/node_modules/yaml/dist/nodes/Pair.js:33:29)
        at Object.stringify (yaml-fuzz/node_modules/yaml/dist/stringify/stringify.js:95:21)
        at stringifyFlowCollection (yaml-fuzz/node_modules/yaml/dist/stringify/stringifyCollection.js:106:29)
        at Object.stringifyCollection (yaml-fuzz/node_modules/yaml/dist/stringify/stringifyCollection.js:10:12)
        at YAMLMap.toString (yaml-fuzz/node_modules/yaml/dist/nodes/YAMLMap.js:136:36)
        at stringifyKey (yaml-fuzz/node_modules/yaml/dist/nodes/addPairToJSMap.js:51:28)
        at Object.addPairToJSMap (yaml-fuzz/node_modules/yaml/dist/nodes/addPairToJSMap.js:24:31)
  2. eemeli commented on Mar 20, 2025

    @eemeli
    Owner

    This was due to a pretty ridiculous combination of factors:

    1. The fallback behaviour when parsing explicit tags that expect scalar values, but are given a collection value, still includes the tag name in the parsed node.
    2. Including a valid YAML 1.1 tag includes the tag in the document's schema.
    3. With the default option value mapAsMap: false, mappings are represented as JS objects, which require a serialization of the keys.
    4. The serialization of !!binary and !!timestamp did not expect to be called on invalid nodes, which is what we got from step 1.

    The warning here is now better, and the TypeError is avoided.

  3. cxcorp commented on Mar 20, 2025

    @cxcorp
    Author

    Wow! Seems like just the kind of thing only a fuzzer would find 😅 Thank you!

  4. added a commit that references this issue on Mar 20, 2025
    9cf06d2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions