record_accessor raises ArgumentError instead of ConfigError for an array index that is not an integer

クローズ 初心者向け
#5,595 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
82/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
ruby
領域
backend

調査の方向性

まず plugin_helper/record_accessor.rb、特に parse_dot_array_op と parse_bracket_notation を確認してください。ここで Integer(index_value) が報告されたエラーを発生させます。近くにある構文エラーの処理を読み、test/plugin_helper/test_record_accessor.rb を実行してください。整数でない配列インデックスが Fluent::ConfigError を発生させ、メッセージに無効なキーが含まれる状態を完了条件とします。

索引モデルが issue の本文から書いたものです。

説明

Describe the bug

A record_accessor key with an array index that is not an integer, such as $.a[x] or $['a'][x], makes Fluentd stop with ArgumentError instead of Fluent::ConfigError. Fluentd stops either way, but the error is not reported as a config error: on 1.20.1 it is logged as "unexpected error" without the file of the configuration, and on 1.16.11 Fluentd exits with a Ruby backtrace.

The cause is Integer(index_value) in plugin_helper/record_accessor.rb (line 143 in parse_dot_array_op and line 183 in parse_bracket_notation, on master af25743e1 and v1.20.1). The other syntax errors next to them, such as a missing ] or an empty [], raise Fluent::ConfigError, but the ArgumentError of Integer() is not converted.

This affects every plugin that uses record_accessor_create for a key from the configuration, for example filter_grep.

To Reproduce

With this configuration:

<source>
  @type sample
  tag t
</source>
<filter t>
  @type grep
  <regexp>
    key $.a[x]
    pattern /x/
  </regexp>
</filter>
<match t>
  @type stdout
</match>

run fluentd --dry-run -c fluent.conf.

The same happens without a configuration file:

require "fluent/version"
require "fluent/plugin_helper/record_accessor"

puts "Fluentd #{Fluent::VERSION}"
["$.a[x]", "$['a'][x]", "$.[bad"].each do |key|
  Fluent::PluginHelper::RecordAccessor::Accessor.new(key)
  puts "#{key}: no error"
rescue => e
  puts "#{key}: #{e.class}: #{e.message}"
end

On master (af25743e1) with Ruby 3.4.12, it prints:

Fluentd 1.20.1
$.a[x]: ArgumentError: invalid value for Integer(): "x"
$['a'][x]: ArgumentError: invalid value for Integer(): "x"
$.[bad: Fluent::ConfigError: '[' found but ']' not found. Invalid syntax: $.[bad

With fluentd --dry-run and the configuration above, with each key in <regexp>:

key master (af25743e1) and 1.20.1 1.16.11
$.a[x] [error]: unexpected error error_class=ArgumentError error="invalid value for Integer(): \"x\"" (exit 1) No log line. Exits with a Ruby backtrace: record_accessor.rb:143:in `Integer': invalid value for Integer(): "x" (ArgumentError) (exit 1)
$['a'][x] (bracket notation) The same ArgumentError The same backtrace, from line 183
$.[bad (for comparison) [error]: config error file="fluent.conf" error_class=Fluent::ConfigError error="'[' found but ']' not found. Invalid syntax: $.[bad" The same config error
Expected behavior

Fluent::ConfigError, like the other syntax errors of a record_accessor key, so that Fluentd reports it as a config error with the file and the key, for example "array index must be an integer. Invalid syntax: $.a[x]".

Your Environment
  • Fluentd version: master (af25743e1), 1.20.1 and 1.16.11
  • Ruby version: 3.4.12 (master, 1.20.1), 3.2.11 (1.16.11)
  • Operating system: Linux (Docker, ruby:3.4 and ruby:3.2)
Your Configuration

The configuration is in "To Reproduce" above.

Your Error Log

Fluentd 1.20.1 and master:

[info]: starting fluentd-1.20.1 as dry run mode ruby="3.4.12"
[error]: unexpected error error_class=ArgumentError error="invalid value for Integer(): \"x\""

Fluentd 1.16.11:

[info]: starting fluentd-1.16.11 as dry run mode ruby="3.2.11"
/usr/local/bundle/gems/fluentd-1.16.11/lib/fluent/plugin_helper/record_accessor.rb:143:in `Integer': invalid value for Integer(): "x" (ArgumentError)

For comparison, key $.[bad gives:

[error]: config error file="fluent.conf" error_class=Fluent::ConfigError error="'[' found but ']' not found. Invalid syntax: $.[bad"
Additional context
  • I tried rescuing the ArgumentError of the two Integer(index_value) calls and raising Fluent::ConfigError on master. The keys above then raise Fluent::ConfigError, and test/plugin_helper/test_record_accessor.rb passes (63 tests). In parse_bracket_notation, the message should use orig_param, as the other errors there do, because param is only the rest of the key at that point.
  • A related but different case: a key that ends with [ or . is accepted without an error, and the end is ignored. $.a[, $.a., $.a.. and $['a'][ all read the key "a", on master, 1.20.1 and 1.16.11. $.a[1 and $.[bad raise "'[' found but ']' not found". In parse_dot_array_op, the loop does not run when nothing follows [, and String#split('.') drops the empty strings at the end. These configurations start today, so making them an error could stop Fluentd after an update; a warning may fit better. I am not asking to change this here, but mention it, as it is next to the code above.
  • This was found in fluent/fluent-plugin-rewrite-tag-filter, which reports the broken settings of its rules together at startup. To report this key with the others, it would have to rescue this ArgumentError by its message.
主要言語
Ruby
スター
13.6k
フォーク
1.4k
平均マージ
1日 1時間
マージ済み PR(30日)
61

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

fluent/fluentd のほかの issue

fluent/fluentd の issue をすべて見る

似ている issue

Ruby の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。