Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-40704

JSON_KEYS does not fold duplicate keys when the key name contains an escaped quote

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • 10.11, 11.4, 11.8, 12.3, 13.0
    • None
    • JSON

    Description

      JSON_KEYS returns each key of an object once. A key whose name
      contains an escaped quote is returned as many times as it appears.

      SELECT JSON_KEYS('{"a\"b":1,"a\"b":2}') AS v;
      v
      ["a\"b", "a\"b"]

      Every other escape folds correctly:

      SELECT JSON_KEYS('{"a\\b":1,"a\\b":2}') AS backslash;   -- ["a\\b"]
      SELECT JSON_KEYS('{"a\nb":1,"a\nb":2}')   AS newline;     -- ["a\nb"]

      How to repeat

      SELECT JSON_KEYS('{"a\"b":1,"a\"b":2}') AS two_of_one_key;
      SELECT JSON_LENGTH(JSON_KEYS('{"a\"b":1,"a\"b":2}')) AS how_many;
      -- 2, where the object has one key name
       
      SELECT JSON_KEYS('{"x":1,"a\"b":2,"y":3,"a\"b":4,"z":5}') AS in_company;
      -- ["x", "a\"b", "y", "a\"b", "z"]

      Root cause

      `check_key_in_list()` walks the array of keys built so far, looking for
      a bare quote as the end of each key. A key containing an escaped quote
      ends early by that rule: the comparison is then made over a prefix, and
      the walk resynchronises to an offset that is not the start of the next
      key, so the key already in the list is never recognised.

      The function's own comment states the assumption that fails: *"It
      utilizes the fact the resulting string is in specific format:
      ["key1", "key2"...]"*.

      Note

      The same walk contains an unbounded scan for the closing quote. Several
      escaped-key layouts were traced by hand without going past the end of
      the buffer and no out-of-bounds claim is made here, but given that the
      terminator assumption is now known to be wrong, *this is worth a run
      under ASAN before the report is closed*.

      Affected versions

      JSON_KEYS was added in 10.2.3. The de-duplication itself was
      added for MDEV-12789, and this is a hole in that fix.

      Verified on 10.11 only (10.11.19-MariaDB-debug, commit 1dab253482d).
      Other branches were not tested.

      Note

      Found while auditing the JSON functions against their documented
      contracts. None for escaped keys. The de-duplication is pinned
      only with plain keys at func_json.test:159-160;
      func_json_keys_typed.test:58-61 uses two distinct keys, so the
      comparison path is never taken.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              arcivanov Arcadiy Ivanov
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.