http://q.hatena.ne.jp/1161872189の考察

http://q.hatena.ne.jp/1161872189 が長くなりそうなのでこちらへ
問題のスクリプト

//メイン
$_SESSION['login']=$password;
if(!$_POST){
$mode=$_GET['mode'];
$id=$_GET['id'];
}else{
extract($_POST);
}
$scriptName=$_SERVER['SCRIPT_NAME'];
$status=" ";
$data=@file("$dataDir/$dataFile")or $status='データがありません';
$id--;

switch($mode){
case'edit'; //編集データ取得
list($title,$text,$date)=explode("?t",rtrim(htmlspecialchars($data[$id])));
list($year,$month,$day)=explode("/",$date);
$text=str_replace("[br /]","?n",$text);
$id++;
$status="No.$id を編集します";
break;

case'write'; //データ書き込み
if(!$title&&!$text){
$status='入力してください';
}elseif(!$title||!$text){
$status='入力されていない項目があります';
}elseif(!preg_match("/?d{4}/",$year)){
$status='更新日(年)が正しくありません';
}else{
if(get_magic_quotes_gpc()){
$title=stripslashes($title);
$text=stripslashes($text);
}
// $title=htmlspecialchars($title);
$text=preg_replace("/?n/","[br /]",$text);
$text=preg_replace("/?r/","",$text);
$formData="$title?t$text?t$year/$month/$day?n";
if($id<0){
array_unshift($data,$formData);
}else{
$data[$id]=$formData;
$id=NULL;
}
DataOut($data);
$status='ファイルに書き出しました';
unset($title,$text,$year,$month,$day,$id);
}
if($id>-1) $id++;
break;

case'delete'; //デリート処理
$data[$id]=NULL;
DataOut($data);
$status='データを削除しました';
$id=NULL;
break;

case'up'; //データ移動(上)
if($id>0){
$temp=array_splice($data,$id-1,1,$data[$id]);
$data[$id]=$temp[0];
DataOut($data);
$id2=$id+1;
$status="No.$id2 と No.$id を入れ替えました";
$id=NULL;
}
break;

case'down'; //データ移動(下)
if(id$value){
$value=addslashes(str_replace("[br /]","
",Tag($value)));
list($title,$text,$date)=explode("?t",rtrim($value));
$output.="info[$key] = new Array(?"$title?",?"$text?",?"$date?");?n";
}
$fp=fopen("$dataDir/$jsFile","w")or exit('データを書き出せません');
flock($fp,LOCK_EX);
fwrite($fp,mb_convert_encoding($output,$encode,'EUC-JP'));
flock($fp,LOCK_UN);
fclose($fp);
$status="{$jsFile} に書き出しました";
unset($title,$text,$year,$month,$day,$id);
}
if($id>-1) $id++;
break;
}

こんな状況が予想されます。
$data を読み込む時にエラー制御演算子@付きで file 関数で読み込んでいるので何かエラーがあった場合も無視してしまう。
一応 $status に読み込むデータが無い事をセットしているけど、処理は中断されていない。つまりエラー処理が不完全な気がします。
なので、$mode に正しい値(今回の場合は 'write' )が渡っている(URL に埋め込んだパラメータだから、当然渡っているはず)と case 節を実行してしまい、読み込みに失敗した $data を使って unshift をしようとする。ー>エラー


あるいは、読み込んだファイルは1行しか無くて、 $data は配列になっていない。だからエラーになる。


確認の為には、$data=@file(... とエラー制御演算子付きなのを、$data=file(... と外してみて、エラーが出るか見てみる。
チャンと予定通りの配列となっているかを switch の前あたりで、var_dump($data); とでもして内容を確認してみる。

で不具合箇所がわかるのでは?