Skip to content
Snippets Groups Projects
  1. Feb 04, 2021
  2. Dec 19, 2020
    • Markus Armbruster's avatar
      qobject: Make QString immutable · 4ac76ba4
      Markus Armbruster authored
      
      The functions to modify a QString's string are all unused now.  Drop
      them, and make the string immutable.  Saves 16 bytes per QString on my
      system.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201211171152.146877-21-armbru@redhat.com>
      4ac76ba4
    • Markus Armbruster's avatar
      json: Use GString instead of QString to accumulate strings · 68af4cc1
      Markus Armbruster authored
      
      QString supports modifying its string, but it's quite limited: you can
      only append.  The remaining callers use it for building an initial
      string, never for modifying it later.
      
      Change parse_string() to do build the initial string with GString.
      This is another step towards making QString immutable.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201211171152.146877-18-armbru@redhat.com>
      68af4cc1
    • Markus Armbruster's avatar
      qobject: Factor JSON writer out of qobject_to_json() · 998da0b1
      Markus Armbruster authored
      
      We have two JSON writers written in C: qobject/qjson.c provides
      qobject_to_json(), and migration/qjson.c provides a more low level
      imperative interface.  They don't share code.  The latter tacitly
      limits numbers to int64_t, and strings contents to characters that
      don't need escaping.
      
      Factor out qobject_to_json()'s JSON writer as qobject/json-writer.c.
      Straightforward, except for numbers: since the writer is to be
      independent of QObject, it can't use qnum_to_string().  Open-code it
      instead.  This is actually an improvement of sorts, because it
      liberates qnum_to_string() from JSON's needs: its JSON-related FIXMEs
      move to the JSON writer, where they belong.
      
      The next commit will replace migration/qjson.c.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201211171152.146877-16-armbru@redhat.com>
      998da0b1
    • Markus Armbruster's avatar
      qobject: Factor quoted_str() out of to_json() · 91f54d92
      Markus Armbruster authored
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201211171152.146877-15-armbru@redhat.com>
      91f54d92
    • Markus Armbruster's avatar
      qobject: Drop qstring_get_try_str() · b3119b08
      Markus Armbruster authored
      
      No users left outside tests/, and the ones in tests/ can just as well
      use qstring_get_str().  Do that, and drop the function.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201211171152.146877-14-armbru@redhat.com>
      b3119b08
    • Markus Armbruster's avatar
      qobject: Drop qobject_get_try_str() · 808ac365
      Markus Armbruster authored
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201211171152.146877-13-armbru@redhat.com>
      808ac365
    • Markus Armbruster's avatar
      qobject: Move internals to qobject-internal.h · 80d71121
      Markus Armbruster authored
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201211171152.146877-9-armbru@redhat.com>
      80d71121
    • Markus Armbruster's avatar
      Revert "qstring: add qstring_free()" · 88e25b1e
      Markus Armbruster authored
      
      This reverts commit 164c374b.
      
      A free function for a reference-counted object is in bad taste.
      Fortunately, this one is now also unused.  Drop it.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201211171152.146877-7-armbru@redhat.com>
      88e25b1e
    • Markus Armbruster's avatar
      qobject: Change qobject_to_json()'s value to GString · eab3a467
      Markus Armbruster authored
      
      qobject_to_json() and qobject_to_json_pretty() build a GString, then
      covert it to QString.  Just one of the callers actually needs a
      QString: qemu_rbd_parse_filename().  A few others need a string they
      can modify: qmp_send_response(), qga's send_response(), to_json_str(),
      and qmp_fd_vsend_fds().  The remainder just need a string.
      
      Change qobject_to_json() and qobject_to_json_pretty() to return the
      GString.
      
      qemu_rbd_parse_filename() now has to convert to QString.  All others
      save a QString temporary.  to_json_str() actually becomes a bit
      simpler, because GString provides more convenient modification
      functions.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201211171152.146877-6-armbru@redhat.com>
      eab3a467
    • Markus Armbruster's avatar
      qobject: Use GString instead of QString to accumulate JSON · f1cc129d
      Markus Armbruster authored
      
      QString supports modifying its string, but it's quite limited: you can
      only append.  The remaining callers use it for building an initial
      string, never for modifying it later.
      
      Use of GString for building the initial string is actually more
      convenient here.  Change qobject_to_json() & friends to do that.
      
      Once all such uses are replaced this way, QString can become immutable.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201211171152.146877-5-armbru@redhat.com>
      f1cc129d
    • Markus Armbruster's avatar
      qobject: Make qobject_to_json_pretty() take a pretty argument · 6589f459
      Markus Armbruster authored
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201211171152.146877-4-armbru@redhat.com>
      6589f459
    • Markus Armbruster's avatar
      qobject: Fix qnum_to_string() to use sufficient precision · f917eed3
      Markus Armbruster authored
      
      We should serialize numbers to JSON so that they deserialize back to
      the same number.  We fail to do so.
      
      The culprit is qnum_to_string(): it uses format %f with trailing '0'
      trimmed.  Results in pretty output for "nice" numbers, but is prone to
      nasty rounding errors.  For instance, numbers between 0 and 0.0000005
      get flushed to zero.
      
      Where exactly the incorrect rounding can bite is tiresome to gauge.
      Here's my take.
      
      * In QMP output, type 'number':
      
        - query-blockstats value avg_rd_queue_depth
      
        - QMP query-migrate values mbps, cache-miss-rate, encoding-rate,
          busy-rate, compression-rate.
      
        Relatively harmless, I guess.
      
      * In tracing QMP input.  Harmless.
      
      * In qemu-ga output, type 'number': guest-get-users value login-time.
        Harmless.
      
      * In output of HMP qom-get.  Harmless.
      
      Not affected, because double values don't actually occur there (I
      think):
      
      * QMP output, type 'any':
      
        * qom-get value
      
        * qom-list, qom-list-properties value default-value
      
        * query-cpu-model-comparison, query-cpu-model-baseline,
          query-cpu-model-expansion value props.
      
      * qemu-img --output json output.
      
      * "json:" pseudo-filenames generated by bdrv_refresh_filename().
      
      * The rbd block driver's "=keyvalue-pairs" hack.
      
      * In -object help on property default values.  Aside: use of JSON
        feels inappropriate here.
      
      * Output of HMP qom-get.
      
      * Argument conversion to QemuOpts for qdev_device_add() and HMP with
        qemu_opts_from_qdict()
      
        QMP and HMP device_add, virtio-net failover primary creation,
        xen-usb "usb-host" creation, HMP netdev_add, object_add.
      
      * The uses of qobject_input_visitor_new_flat_confused()
      
        As far as I can tell, none of the visited types contain double
        values.
      
      * Dumping ImageInfoSpecific with dump_qobject()
      
      Fix by formatting with %.17g.  17 decimal digits always suffice for
      IEEE double.
      
      The change to expected test output illustrates the effect: the
      rounding errors are gone, but some seemingly "nice" numbers now get
      converted to not so nice strings, e.g. 0.42 to "0.41999999999999998".
      This is because 0.42 is not representable exactly in double.  It's
      more accurate in this example than strictly necessary, though.
      
      If ugly accuracy bothers us, we can we can try using the least number
      of digits that still converts back to the same double.  In this
      example, "0.42" would do.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201210161452.2813491-7-armbru@redhat.com>
      f917eed3
  3. Nov 17, 2020
    • Alex Chen's avatar
      json: Fix a memleak in parse_pair() · 922d42bb
      Alex Chen authored
      
      In qobject_type(), NULL is returned when the 'QObject' returned from parse_value() is not of QString type,
      and this 'QObject' memory will leaked.
      So we need to first cache the 'QObject' returned from parse_value(), and finally
      free 'QObject' memory at the end of the function.
      Also, we add a testcast about invalid dict key.
      
      The memleak stack is as follows:
      Direct leak of 32 byte(s) in 1 object(s) allocated from:
          #0 0xfffe4b3c34fb in __interceptor_malloc (/lib64/libasan.so.4+0xd34fb)
          #1 0xfffe4ae48aa3 in g_malloc (/lib64/libglib-2.0.so.0+0x58aa3)
          #2 0xaaab3557d9f7 in qnum_from_int qemu/qobject/qnum.c:25
          #3 0xaaab35584d23 in parse_literal qemu/qobject/json-parser.c:511
          #4 0xaaab35584d23 in parse_value qemu/qobject/json-parser.c:554
          #5 0xaaab35583d77 in parse_pair qemu/qobject/json-parser.c:270
          #6 0xaaab355845db in parse_object qemu/qobject/json-parser.c:327
          #7 0xaaab355845db in parse_value qemu/qobject/json-parser.c:546
          #8 0xaaab35585b1b in json_parser_parse qemu/qobject/json-parser.c:580
          #9 0xaaab35583703 in json_message_process_token qemu/qobject/json-streamer.c:92
          #10 0xaaab355ddccf in json_lexer_feed_char qemu/qobject/json-lexer.c:313
          #11 0xaaab355de0eb in json_lexer_feed qemu/qobject/json-lexer.c:350
          #12 0xaaab354aff67 in tcp_chr_read qemu/chardev/char-socket.c:525
          #13 0xfffe4ae429db in g_main_context_dispatch (/lib64/libglib-2.0.so.0+0x529db)
          #14 0xfffe4ae42d8f  (/lib64/libglib-2.0.so.0+0x52d8f)
          #15 0xfffe4ae430df in g_main_loop_run (/lib64/libglib-2.0.so.0+0x530df)
          #16 0xaaab34d70bff in iothread_run qemu/iothread.c:82
          #17 0xaaab3559d71b in qemu_thread_start qemu/util/qemu-thread-posix.c:519
      
      Fixes: 532fb532 ("qapi: Make more of qobject_to()")
      Reported-by: default avatarEuler Robot <euler.robot@huawei.com>
      Signed-off-by: default avatarAlex Chen <alex.chen@huawei.com>
      Signed-off-by: default avatarChen Qun <kuhn.chenqun@huawei.com>
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20201113145525.85151-1-alex.chen@huawei.com>
      [Commit message tweaked]
      922d42bb
  4. Sep 17, 2020
  5. Aug 21, 2020
    • Paolo Bonzini's avatar
      libqemuutil, qapi, trace: convert to meson · a81df1b6
      Paolo Bonzini authored
      
      This shows how to do some "computations" in meson.build using its array
      and dictionary data structures, and also a basic usage of the sourceset
      module for conditional compilation.
      
      Notice the new "if have_system" part of util/meson.build, which fixes
      a bug in the old build system was buggy: util/dbus.c was built even for
      non-softmmu builds, but the dependency on -lgio was lost when the linking
      was done through libqemuutil.a.  Because all of its users required gio
      otherwise, the bug was hidden.  Meson instead propagates libqemuutil's
      dependencies down to its users, and shows the problem.
      
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      a81df1b6
  6. Apr 30, 2020
  7. Apr 07, 2020
  8. Jan 24, 2020
  9. Aug 21, 2019
  10. Jun 11, 2019
  11. Mar 26, 2019
  12. Jan 24, 2019
    • Christophe Fergeau's avatar
      json: Fix % handling when not interpolating · bbc0586c
      Christophe Fergeau authored
      Commit 8bca4613 added support for %% in json strings when interpolating,
      but in doing so broke handling of % when not interpolating.
      
      When parse_string() is fed a string token containing '%', it skips the
      '%' regardless of ctxt->ap, i.e. even it's not interpolating.  If the
      '%' is the string's last character, it fails an assertion.  Else, it
      "merely" swallows the '%'.
      
      Fix parse_string() to handle '%' specially only when interpolating.
      
      To gauge the bug's impact, let's review non-interpolating users of this
      parser, i.e. code passing NULL context to json_message_parser_init():
      
      * tests/check-qjson.c, tests/test-qobject-input-visitor.c,
        tests/test-visitor-serialization.c
      
        Plenty of tests, but we still failed to cover the buggy case.
      
      * monitor.c: QMP input
      
      * qga/main.c: QGA input
      
      * qobject_from_json():
      
        - qobject-input-visitor.c: JSON command line option arguments of
          -display and -blockdev
      
          Reproducer: -blockdev '{"%"}'
      
        - block.c: JSON pseudo-filenames starting with "json:"
      
          Reproducer: https://bugzilla.redhat.com/show_bug.cgi?id=1668244#c3
      
      
      
        - block/rbd.c: JSON key pairs
      
          Pseudo-filenames starting with "rbd:".
      
      Command line, QMP and QGA input are trusted.
      
      Filenames are trusted when they come from command line, QMP or HMP.
      They are untrusted when they come from from image file headers.
      Example: QCOW2 backing file name.  Note that this is *not* the security
      boundary between host and guest.  It's the boundary between host and an
      image file from an untrusted source.
      
      Neither failing an assertion nor skipping a character in a filename of
      your choice looks exploitable.  Note that we don't support compiling
      with NDEBUG.
      
      Fixes: 8bca4613
      Cc: qemu-stable@nongnu.org
      Signed-off-by: default avatarChristophe Fergeau <cfergeau@redhat.com>
      Message-Id: <20190102140535.11512-1-cfergeau@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Tested-by: default avatarRichard W.M. Jones <rjones@redhat.com>
      [Commit message extended to discuss impact]
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      bbc0586c
  13. Dec 13, 2018
  14. Oct 26, 2018
  15. Sep 24, 2018
    • Markus Armbruster's avatar
      json: Eliminate lexer state IN_WHITESPACE, pseudo-token JSON_SKIP · 1e960b46
      Markus Armbruster authored
      
      The lexer ignores whitespace like this:
      
               on whitespace      on non-ws   spontaneously
          IN_START --> IN_WHITESPACE --> JSON_SKIP --> IN_START
                          ^    |
                           \__/  on whitespace
      
      This accumulates a whitespace token in state IN_WHITESPACE, only to
      throw it away on the transition via JSON_SKIP to the start state.
      Wasteful.  Go from IN_START to IN_START on whitespace directly,
      dropping the whitespace character.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20180831075841.13363-7-armbru@redhat.com>
      1e960b46
    • Markus Armbruster's avatar
      json: Eliminate lexer state IN_ERROR · 2ce4ee64
      Markus Armbruster authored
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20180831075841.13363-6-armbru@redhat.com>
      2ce4ee64
    • Markus Armbruster's avatar
      json: Nicer recovery from lexical errors · 0f07a5d5
      Markus Armbruster authored
      
      When the lexer chokes on an input character, it consumes the
      character, emits a JSON error token, and enters its start state.  This
      can lead to suboptimal error recovery.  For instance, input
      
          0123 ,
      
      produces the tokens
      
          JSON_ERROR    01
          JSON_INTEGER  23
          JSON_COMMA    ,
      
      Make the lexer skip characters after a lexical error until a
      structural character ('[', ']', '{', '}', ':', ','), an ASCII control
      character, or '\xFE', or '\xFF'.
      
      Note that we must not skip ASCII control characters, '\xFE', '\xFF',
      because those are documented to force the JSON parser into known-good
      state, by docs/interop/qmp-spec.txt.
      
      The lexer now produces
      
          JSON_ERROR    01
          JSON_COMMA    ,
      
      Update qmp-test for the nicer error recovery: QMP now reports just one
      error for input %p instead of two.  Also drop the newline after %p; it
      was needed to tease out the second error.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20180831075841.13363-5-armbru@redhat.com>
      [Conflict with commit ebb4d82d resolved]
      0f07a5d5
    • Markus Armbruster's avatar
      json: Make lexer's "character consumed" logic less confusing · c0ee3afa
      Markus Armbruster authored
      
      The lexer uses macro TERMINAL_NEEDED_LOOKAHEAD() to decide whether a
      state transition consumes the input character.  It returns true when
      the state transition is defined with the TERMINAL() macro.  To detect
      that, it checks whether input '\0' would have resulted in the same
      state transition, and the new state is not IN_ERROR.
      
      Why does that even work?  For all states, the new state on input '\0'
      is either IN_ERROR or defined with TERMINAL().  If the state
      transition equals the one we'd get for input '\0', it goes to IN_ERROR
      or to the argument of TERMINAL().  We never use TERMINAL(IN_ERROR),
      because it makes no sense.  Thus, if it doesn't go to IN_ERROR, it
      must be defined with TERMINAL().
      
      Since this isn't quite confusing enough, we negate the result to get
      @char_consumed, and ignore it when @flush is true.
      
      Instead of deriving the lookahead bit from the state transition, make
      it explicit.  This is easier to understand, and a bit more flexible,
      too.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20180831075841.13363-4-armbru@redhat.com>
      c0ee3afa
    • Markus Armbruster's avatar
      json: Clean up how lexer consumes "end of input" · 852dfa76
      Markus Armbruster authored
      
      When the lexer isn't in its start state at the end of input, it's
      working on a token.  To flush it out, it needs to transit to its start
      state on "end of input" lookahead.
      
      There are two ways to the start state, depending on the current state:
      
      * If the lexer is in a TERMINAL(JSON_FOO) state, it can emit a
        JSON_FOO token.
      
      * Else, it can go to IN_ERROR state, and emit a JSON_ERROR token.
      
      There are complications, however:
      
      * The transition to IN_ERROR state consumes the input character and
        adds it to the JSON_ERROR token.  The latter is inappropriate for
        the "end of input" character, so we suppress that.  See also recent
        commit a2ec6be7 "json: Fix lexer to include the bad character in
        JSON_ERROR token".
      
      * The transition to a TERMINAL(JSON_FOO) state doesn't consume the
        input character.  In that case, the lexer normally loops until it is
        consumed.  We have to suppress that for the "end of input" input
        character.  If we didn't, the lexer would consume it by entering
        IN_ERROR state, emitting a bogus JSON_ERROR token.  We fixed that in
        commit bd3924a3.
      
      However, simply breaking the loop this way assumes that the lexer
      needs exactly one state transition to reach its start state.  That
      assumption is correct now, but it's unclean, and I'll soon break it.
      Clean up: instead of breaking the loop after one iteration, break it
      after it reached the start state.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20180831075841.13363-3-armbru@redhat.com>
      852dfa76
    • Markus Armbruster's avatar
      json: Fix lexer for lookahead character beyond '\x7F' · 2a96042a
      Markus Armbruster authored
      
      The lexer fails to end a valid token when the lookahead character is
      beyond '\x7F'.  For instance, input
      
          true\xC2\xA2
      
      produces the tokens
      
          JSON_ERROR     true\xC2
          JSON_ERROR     \xA2
      
      This should be
      
          JSON_KEYWORD   true
          JSON_ERROR     \xC2
          JSON_ERROR     \xA2
      
      instead.
      
      The culprit is
      
          #define TERMINAL(state) [0 ... 0x7F] = (state)
      
      It leaves [0x80..0xFF] zero, i.e. IN_ERROR.  Has always been broken.
      Fix it to initialize the complete array.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20180831075841.13363-2-armbru@redhat.com>
      2a96042a
  16. Aug 24, 2018
    • Markus Armbruster's avatar
      json: Update references to RFC 7159 to RFC 8259 · 37aded92
      Markus Armbruster authored
      
      RFC 8259 (December 2017) obsoletes RFC 7159 (March 2014).
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Message-Id: <20180823164025.12553-59-armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      37aded92
    • Markus Armbruster's avatar
      json: Support %% in JSON strings when interpolating · 8bca4613
      Markus Armbruster authored
      
      The previous commit makes JSON strings containing '%' awkward to
      express in templates: you'd have to mask the '%' with an Unicode
      escape \u0025.  No template currently contains such JSON strings.
      Support the printf conversion specification %% in JSON strings as a
      convenience anyway, because it's trivially easy to do.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20180823164025.12553-58-armbru@redhat.com>
      8bca4613
    • Markus Armbruster's avatar
      json: Improve safety of qobject_from_jsonf_nofail() & friends · 16a48599
      Markus Armbruster authored
      
      The JSON parser optionally supports interpolation.  This is used to
      build QObjects by parsing string templates.  The templates are C
      literals, so parse errors (such as invalid interpolation
      specifications) are actually programming errors.  Consequently, the
      functions providing parsing with interpolation
      (qobject_from_jsonf_nofail(), qobject_from_vjsonf_nofail(),
      qdict_from_jsonf_nofail(), qdict_from_vjsonf_nofail()) pass
      &error_abort to the parser.
      
      However, there's another, more dangerous kind of programming error:
      since we use va_arg() to get the value to interpolate, behavior is
      undefined when the variable argument isn't consistent with the
      interpolation specification.
      
      The same problem exists with printf()-like functions, and the solution
      is to have the compiler check consistency.  This is what
      GCC_FMT_ATTR() is about.
      
      To enable this type checking for interpolation as well, we carefully
      chose our interpolation specifications to match printf conversion
      specifications, and decorate functions parsing templates with
      GCC_FMT_ATTR().
      
      Note that this only protects against undefined behavior due to type
      errors.  It can't protect against use of invalid interpolation
      specifications that happen to be valid printf conversion
      specifications.
      
      However, there's still a gaping hole in the type checking: GCC
      recognizes '%' as start of printf conversion specification anywhere in
      the template, but the parser recognizes it only outside JSON strings.
      For instance, if someone were to pass a "{ '%s': %d }" template, GCC
      would require a char * and an int argument, but the parser would
      va_arg() only an int argument, resulting in undefined behavior.
      
      Avoid undefined behavior by catching the programming error at run
      time: have the parser recognize and reject '%' in JSON strings.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20180823164025.12553-57-armbru@redhat.com>
      16a48599
    • Markus Armbruster's avatar
      json: Keep interpolation state in JSONParserContext · ada74c3b
      Markus Armbruster authored
      
      The recursive descent parser passes along a pointer to
      JSONParserContext.  It additionally passes a pointer to interpolation
      state (a va_alist *) as needed to reach its consumer
      parse_interpolation().
      
      Stuffing the latter pointer into JSONParserContext saves us the
      trouble of passing it along, so do that.
      
      Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
      Reviewed-by: default avatarEric Blake <eblake@redhat.com>
      Message-Id: <20180823164025.12553-56-armbru@redhat.com>
      ada74c3b
Loading