swagger-codegen の Ruby クライアントコード生成について調べた
swagger-codegen で API の Ruby クライアントライブラリの生成を試していたところ色々な問題を見つけたメモ。すべて以下のバージョンを対象にしています。
$ java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar version 2.4.2-SNAPSHOT $ git log --oneline -n 1 c4c5c062c Merge pull request #9080 from swagger-api/update-parser-v1
見つけた問題
エスケープ周りが色々とおかしい
ざっくりと言うと、API パラメータに制約を掛ける pattern
や enum
は、クライアントコード生成時にテンプレート展開によって埋め込まれるため、シンタックスエラーやコードインジェクションを避けるためにエスケープしなければならない。
しかし、Ruby クライアントのコードを生成する際に行うエスケープ処理はダブルクォートやバックスラッシュ、改行やタブ文字などしか対象になっていない。このため Ruby の文字列リテラルや正規表現リテラル固有の諸々を考慮できていない。
- エスケープ処理がダブルクォート文字列内で利用されることしか想定されていないので、
pattern
やenum
にシングルクォートを含めると、シングルクォート文字列の中で展開した場合に文字列が切れてしまい、シンタックスエラーやコードインジェクションに繋がる。 #{
をエスケープしていないので、pattern
やenum
に#{...}
を含めると式展開によるコードインジェクションができてしまう。
Ruby クライアントコード生成用のクラスを確認したところ、エスケープ処理メソッド(escapeText
)を override せずデフォルト実装を使いまわしているようなので、Ruby 固有の処理を考慮して override した上でテンプレート内の文字列リテラルをダブルクォートかシングルクォートに統一するとよさそう。(正規表現リテラルでも展開することを考えるとダブルクォート文字列に統一するのがベター?)
エラーメッセージの式展開が動かない
上の issue を調べている過程でシングルクォート文字列内で式展開しようとしてるテンプレートを見つけた。
テンプレート展開を含まない文字列リテラルなので単にダブルクォート文字列に直せばいいだけと判断して PR を出そうとした。が……
同梱しているサンプルがビルドできない
上の issue に対する PR を出そうとして見つけた。
swagger-codegen では Petstore という仮の API を共通のサンプルとして定義しており、レポジトリにはこの API 定義から生成した各言語ごとのクライアントやサーバのコードも commit されている。コードジェネレータやテンプレートを変更する PR を出す際には対応するサンプルも更新することになっているが、Ruby クライアントのサンプルは High Sierra 以上の Mac だと bundle install
ができなかった。
原因はテストに使っている autotest-fsevent
が古いバージョンで lock されているため。最新版に上げることで解消した。
何はなくてもこれを解消しないことには他の PR が出せないので、修正 PR を出した。
ざっと1日眺めただけでも問題が結構見つかったので、#9097 がマージされたら他の issue への対応も考えたいところ……