Apache Commons-Net 1.4.1 の FTPClient#listFiles で 2/29 のタイムスタンプを持つファイルが取れない
うるう年ネタが来ましたよ。ああ、見事に踏んださ。
FTPClient#listFiles returns null element when file's timestamp is "02/29"
https://issues.apache.org/jira/browse/NET-188
- Unix 系 OS では、ファイルのタイムスタンプは直近のやつ (直近6ヶ月?) は "Feb 29 11:30" のように表記される
- '年'が表記されないのがポイント
- FTPClient#listFiles で内部的に呼ばれている FTPTimestampParserImpl#parseTimestamp では、日付のパースに SimpleDateFormat#parse を使っている
- SimpleDateFormat に、 "Feb 29 11:30" のような '年' が入っていない文字列を与えると、勝手に 1970 年であるとしてパースする
- 1970 年はうるう年ではないので ParseException が発生
- たぶん ParseException を呼び出し元でキャッチして null にして配列に突っ込んでる
- FTPClient#listFiles で取ってきた配列をループで回して該当ファイルを参照しようとすると null が入っている
- めでたく NullPointerException thrown
だそうです。
手元の環境で SimpleDateFormat の挙動をチェックしましたが、JIRA での指摘どおり ParseException を吐いてくれました。
っていうか、この部分のソース読んだけど、1.4.1 の実装はちょっと不安なような気もする。ゴニョゴニョとチェックして年を -1 してる処理があるんだけど、それも Client と Server の時刻がきちんと同期されていることが前提だし。それはさすがに危なくないか? 下手すると 10秒くらい Client が遅れてるだけで 1 年前の日付が付いてしまう気がする(まぁタイムスタンプなんぞ信用しちゃいかんという話もあるのかも知れんけど)。*1
2.0-SNAPSHOT では、この FTP のパッケージ全体にかなり手が入ってるようだけど、こいつがリリースされるのは当分先だろうしなぁ。
まぁ、運用中の保守プロジェクトについては、ソースにパッチ当ててリビルドでしょう。
*1:この問題への対応については、2.0-SNAPSHOT のソースを確認したところパッチがあたっていました。