Skip to content

Crash (ArgumentError) when query type is given before name (e.g. tdig txt sony.com) #77

Description

@toshi0806

問題

tdig txt sony.com のようにクエリタイプを名前より先に指定すると、DNS パケット生成時に ArgumentError でクラッシュする。

$ ./tdig txt sony.com
** (ArgumentError) construction of binary failed: segment 2 of type 'integer': expected an integer but got: nil
    (tenbin_dns 0.7.0) lib/dns_packet.ex:289: DNSpacket.create_question_item/1
    (elixir 1.19.5) lib/enum.ex:1688: Enum."-map/2-lists^map/1-1-"/2
    (tenbin_dns 0.7.0) lib/dns_packet.ex:278: DNSpacket.create_question/1
    (tenbin_dns 0.7.0) lib/dns_packet.ex:248: DNSpacket.create/1
    (tdig 0.3.0) lib/tdig.ex:54: Tdig.get_response/1
    (tdig 0.3.0) lib/tdig.ex:31: Tdig.resolve/1
    (elixir 1.19.5) lib/kernel/cli.ex:141: anonymous fn/3 in Kernel.CLI.exec_fun/2

原因(裏取り済み)

Tdig.CLI.parse_argv_item/2lib/tdig/cli.ex)が位置引数を順序固定(1個目 → name、2個目 → type、3個目 → class)で解釈しているため:

  • txt が name(txt.)として、sony.com が type として解釈される
  • str2atom("sony.com") が atom :"sony.com" を生成 → tenbin_dns の type コード変換が nil を返す → create_question_item/1 のバイナリ構築で nil を整数セグメントに埋め込もうとしてクラッシュ

再現確認

コマンド 結果
./tdig sony.com txt ✅ 正常(TXT 応答取得)
./tdig sony.com TXT ✅ 正常
./tdig txt sony.com ❌ ArgumentError
./tdig TXT sony.com ❌ ArgumentError
dig txt sony.com(BIND dig) ✅ 正常(TXT 応答取得)

本家 dig は位置引数のトークンが既知の type/class 名なら位置に関係なく type/class として解釈するため、dig txt sony.com は動作する。dig 互換を謳う tdig との差異になっている。

対応

問題は2層あり、両方に対応する:

  1. dig 互換の引数解釈: parse_argv_item/2 で、位置引数が既知の RR type / class 名(case-insensitive)に一致する場合はその位置に関係なく type / class として解釈する(本家 dig と同じ挙動)。名前が type 名と衝突するケース(例: ホスト名 txt)は dig 同様 type 解釈を優先する。
  2. 不正 type のエラーハンドリング: 未知の type が指定された場合、パケット生成まで進んで stacktrace 付きでクラッシュするのではなく、CLI 層で ;; Unknown type: ... のようなメッセージを出して exit する。また str2atom/1String.to_atom/1 は任意入力から atom を生成するため、既知の type/class への membership 判定と組み合わせる。

TDD で、上記の再現ケース(type-first / 未知 type)をテストに起こしてから実装する。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions