新規記事投稿
フォロー記事投稿
記事のキャンセル
From: にあ
<nir@mvg.biglobe.ne.jp>
Subject: うぇぶ会議室に存在する2000年問題
Date: 1999/03/06 06:12:50
Reference: mesh.forum.3/00901
3月5日に、かたなさんは書きました。
> 最近ちまたで話題の2000年問題なのですが、この会議室の場合、「contents」
>ファイルに4桁の年を書き込んでいますね。
2000年問題ですか。(^^;;
内部的な時間の扱いは全て4桁年か通し秒数ですので2000年問題は無いのですが、
外部とのインターフェースの部分に一部問題となる部分があります。
> で、そのcgiの231行目に1900+$yearで年を取っているように見られ
>ます。これでは2000年の場合1900になってしまうのでしょうか...
これに付いては、石堂さんがフォローした下さった通り問題無いです。
問題となるのは、user Agentが2桁年を渡してきた場合です。
うぇぶ会議室は If-Modified-Since: リクエストヘッダを見ますが、
この時渡される日時のフォーマットには次の3種があります。
Fri, 05 Mar 1999 20:31:07 GMT ; RFC822による定義 (RFC1123により更新)
Friday, 05-Mar-99 20:31:07 GMT ; RFC850による定義だが、RFC1036により廃棄
Fri Mar 5 20:31:07 1999 ; ANSI C asctime()の書式
サーヴァが自分で返すフォーマットは最初のものが望ましく、HTTP/1.1では最初の
ものでなければならないとされていますが、受ける方は過去との互換性を保つ上で
3種全てを解釈できなくてはなりません。
# うぇぶ会議室の生成する日時のフォーマットは、もちろんRFC1123のものです。(^^)
# ここ(Biglobe)のサーヴァ(Netscape-Commerce/1.12)は古いRFC850のを
# 返すので、ヘッダの日時フォーマットは新旧混ざって出力されていますが。(^^;;
一見して分かるとおり、RFC850の日時のフォーマットは2桁年を使うので2000年問題が
存在します。で、実際 forum.pl の中の解釈ルーティンでは2桁年には単純に1900を
足していたので、2000年には1900年になってしまいます。(^^;;
と、言うことで、forum.pl の 377行付近を以下のように変えて下さい。
$wday = &http'wdaytoi($swday);
$year += 100 if ($year <= 38);
$year -= 1900 if ($year >= 1900);
赤字の行が追加された行です。
つまり、、2桁年が渡された場合には、00〜38年だったら2000〜2038年、
39〜99年だったら1939〜1999年と思おう、と言うことです。
# 少々 ad hoc ではありますが。
をっ、日時ルーティンを眺めていたら、もう一つバグを見つけてしまった。(^^;
ANSI C 対応の日付のマッチングは現在のパターンでは1〜9日にマッチしないですね。
そのチョット前の373行付近の、
($swday, $smon, $mday, $hour, $min, $sec, $year) =
/^(\w+) (\w+) (\d+) (\d+):(\d+):(\d+) (\d+)/ if ($sec eq '');
の所を、
($swday, $smon, $mday, $hour, $min, $sec, $year) =
/^(\w+) (\w+) +(\d+) (\d+):(\d+):(\d+) (\d+)/ if ($sec eq '');
にして下さい。(^^;;;
# まぁ、ほとんどの場合、user agentはRFC1123の日時を渡してくるので、
# 問題は起きないんですけどね。