yq icon indicating copy to clipboard operation
yq copied to clipboard

panic: runtime error: index out of range [1] with length 1

Open landure opened this issue 3 years ago • 3 comments

When trying to add a additionnal tag to a xml file, yq crash with the error panic: runtime error: index out of range [1] with length 1.

Version of yq: 4.27.5 Operating system: Ubuntu 22.04 Impish Indri Installed via: binary ( yq_linux_amd64.tar.gz )

Input document

File: /etc/iwatch/iwatch.xml

<config charset="utf-8">
  <guard email="iwatch@localhost" name="iWatch"></guard>
  <watchlist><title>Operating System</title></watchlist>
</config>

Command

sudo yq --inplace --input-format='xml' --output-format='xml' \
  'eval' ".config.watchlist |= . + [ {
      \"title\": \"Some title\"
    } ]" \
  "/etc/iwatch/iwatch.xml"

Actual behavior

panic: runtime error: index out of range [1] with length 1

goroutine 1 [running]:
github.com/mikefarah/yq/v4/pkg/yqlib.addMaps(0xc0002aab80, 0xc00033ac20?, 0x40d51f?)
        /home/runner/work/yq/yq/pkg/yqlib/operator_add.go:189 +0x3c6
github.com/mikefarah/yq/v4/pkg/yqlib.add(0xc000282450?, {0xc00035cb40, 0xc00035cbd0, 0x1, {0x0, 0x0}}, 0xc0002aa800, 0xc0002aa880)
        /home/runner/work/yq/yq/pkg/yqlib/operator_add.go:65 +0x510
github.com/mikefarah/yq/v4/pkg/yqlib.resultsForRHS(0x19?, {0xc00035cb40, 0xc00035cbd0, 0x1, {0x0, 0x0}}, 0x28?, {0x0, 0x0, 0x8bbdd0}, ...)
        /home/runner/work/yq/yq/pkg/yqlib/operators.go:105 +0x62a
github.com/mikefarah/yq/v4/pkg/yqlib.doCrossFunc(0x1d?, {0xc00035cb40, 0xc00035cbd0, 0x1, {0x0, 0x0}}, 0xc000288468, {0x0, 0x0, 0x8bbdd0})
        /home/runner/work/yq/yq/pkg/yqlib/operators.go:142 +0x413
github.com/mikefarah/yq/v4/pkg/yqlib.crossFunctionWithPrefs(0x1?, {0xc00035ca20, 0xc00035c870, 0x1, {0x0, 0x0}}, 0xc00035c8d0?, {0x0, 0x0, 0x8bbdd0})
        /home/runner/work/yq/yq/pkg/yqlib/operators.go:175 +0x3db
github.com/mikefarah/yq/v4/pkg/yqlib.crossFunction(0xc000282450?, {0xc00035ca20, 0xc00035c870, 0x1, {0x0, 0x0}}, 0x0?, 0xc5a5a0?, 0x70?)
        /home/runner/work/yq/yq/pkg/yqlib/operators.go:153 +0x9f
github.com/mikefarah/yq/v4/pkg/yqlib.addOperator(0xc000282450?, {0xc00035c7e0, 0xc00035c870, 0x0, {0x0, 0x0}}, 0x0?)
        /home/runner/work/yq/yq/pkg/yqlib/operator_add.go:46 +0x1c5
github.com/mikefarah/yq/v4/pkg/yqlib.(*dataTreeNavigator).GetMatchingNodes(0xc000282450?, {0xc00035c7e0, 0xc00035c870, 0x0, {0x0, 0x0}}, 0xc000288468)
        /home/runner/work/yq/yq/pkg/yqlib/data_tree_navigator.go:37 +0x25c
github.com/mikefarah/yq/v4/pkg/yqlib.assignUpdateOperator(0xc000282450?, {0xc00035c3f0, 0x0, 0x0, {0x0, 0x0}}, 0xc000288480)
        /home/runner/work/yq/yq/pkg/yqlib/operator_assign.go:52 +0x56e
github.com/mikefarah/yq/v4/pkg/yqlib.(*dataTreeNavigator).GetMatchingNodes(0x0?, {0xc00035c3f0, 0x0, 0x0, {0x0, 0x0}}, 0xc000288480)
        /home/runner/work/yq/yq/pkg/yqlib/data_tree_navigator.go:37 +0x25c
github.com/mikefarah/yq/v4/pkg/yqlib.(*streamEvaluator).Evaluate(0xc000229cf0, {0x7ffc9d60d7f9, 0x16}, {0x93cbe0?, 0xc000286600?}, 0x7f13e90a6cc8?, {0x93ee38, 0xc0002864e0}, {0x0, 0x0}, ...)
        /home/runner/work/yq/yq/pkg/yqlib/stream_evaluator.go:124 +0x363
github.com/mikefarah/yq/v4/pkg/yqlib.(*streamEvaluator).EvaluateFiles(0xc00028a4d0?, {0x7ffc9d60d7bc, 0x3c}, {0xc0002c0010, 0x1, 0xc0002a0800?}, {0x93ee38, 0xc0002864e0}, 0xec?, {0x93e0a8, ...})
        /home/runner/work/yq/yq/pkg/yqlib/stream_evaluator.go:73 +0x30e
github.com/mikefarah/yq/v4/cmd.evaluateSequence(0xc0002a4280?, {0xc0002c0000, 0x2, 0x5})
        /home/runner/work/yq/yq/cmd/evalute_sequence_command.go:132 +0x8a5
github.com/spf13/cobra.(*Command).execute(0xc0002a4280, {0xc0002863c0, 0x5, 0x6})
        /home/runner/go/pkg/mod/github.com/spf13/[email protected]/command.go:872 +0x694
github.com/spf13/cobra.(*Command).ExecuteC(0xc0002a4000)
        /home/runner/go/pkg/mod/github.com/spf13/[email protected]/command.go:990 +0x3bd
github.com/spf13/cobra.(*Command).Execute(...)
        /home/runner/go/pkg/mod/github.com/spf13/[email protected]/command.go:918
main.main()
        /home/runner/work/yq/yq/yq.go:22 +0x1e5

Expected behavior

<config charset="utf-8">
  <guard email="iwatch@localhost" name="iWatch"></guard>
  <watchlist>
    <title>Operating System</title>
  </watchlist>
  <watchlist>
    <title>Some title</title>
  </watchlist>
</config>

Additional context When there is two watchlist tags in the input document, the command works without issue.

<config charset="utf-8">
  <guard email="iwatch@localhost" name="iWatch"></guard>
  <watchlist><title>Operating System</title></watchlist>
  <watchlist><title>Some other title</title></watchlist>
</config>

landure avatar Sep 15 '22 15:09 landure

Ah I see - there are two issues here.

  1. If there's a single item in the XML, yq has no way of knowing that it's an array of one. So watchlist in the first example is a map, but in the second example, it's an array.
  2. I failed to add validation when adding to a map that the right hand side is a map (fix in next release).

To get what you want, you have to wrap watchlist into an array (if it's not one already) and then append to it:

yq  -p=xml -o=xml '.config.watchlist |= (select(tag == "!!seq") // [.]) + [{"x": "y"}]' file.xml

The key bit is: (select(tag == "!!seq") // [.]) which will use watchlist as-is if it's a sequence, otherwise it will wrap it into an array.

mikefarah avatar Sep 15 '22 23:09 mikefarah

Thank you for you help. The only drawback of your command is that when "watchlist" is not present, it add a <watchlist>null</watchlist> tag to the XML in addition to the new content.

I managed to fix this by using:

yq  -p=xml -o=xml '.config.watchlist |= (select(tag == "!!seq") // [ select(length > 0) ]) + [{"x": "y"}]' file.xml

Thank you for your work on yq, it is a great tool to programmatically edit yaml, json and xml files :)

landure avatar Sep 16 '22 06:09 landure

Pleasure :) That's an easy fix as well - I'm not at my pc with yq atm but it will be something like:

yq  -p=xml -o=xml 'select(has(.config.watchlist)) | .config.watchlist |= (select(tag == "!!seq") // [.]) + [{"x": "y"}]' file.xml

mikefarah avatar Sep 16 '22 06:09 mikefarah

Fixed in 4.28.2

mikefarah avatar Oct 24 '22 23:10 mikefarah