OSDN Git Service

BugTrack/2394 Add PHP4 Compatibility on constructor
[pukiwiki/pukiwiki.git] / plugin / paint.inc.php
1 <?php
2 // PukiWiki - Yet another WikiWikiWeb clone
3 //
4 // $Id: paint.inc.php,v 1.20 2011/01/25 15:01:01 henoheno Exp $
5 //
6 // Paint plugin
7
8 /*
9  * Usage
10  *  #paint(width,height)
11  * パラメータ
12  *  キャンバスの幅と高さ
13  */
14
15 // 挿入する位置 1:欄の前 0:欄の後
16 define('PAINT_INSERT_INS',0);
17
18 // デフォルトの描画領域の幅と高さ
19 define('PAINT_DEFAULT_WIDTH',80);
20 define('PAINT_DEFAULT_HEIGHT',60);
21
22 // 描画領域の幅と高さの制限値
23 define('PAINT_MAX_WIDTH',320);
24 define('PAINT_MAX_HEIGHT',240);
25
26 // アプレット領域の幅と高さ 50x50未満で別ウインドウが開く
27 define('PAINT_APPLET_WIDTH',800);
28 define('PAINT_APPLET_HEIGHT',300);
29
30 //コメントの挿入フォーマット
31 define('PAINT_NAME_FORMAT','[[$name]]');
32 define('PAINT_MSG_FORMAT','$msg');
33 define('PAINT_NOW_FORMAT','&new{$now};');
34 //メッセージがある場合
35 define('PAINT_FORMAT',"\x08MSG\x08 -- \x08NAME\x08 \x08NOW\x08");
36 //メッセージがない場合
37 define('PAINT_FORMAT_NOMSG',"\x08NAME\x08 \x08NOW\x08");
38
39 function plugin_paint_action()
40 {
41         global $script, $vars, $pkwk_dtd, $_paint_messages;
42
43         if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing');
44         
45         //戻り値を初期化
46         $retval['msg'] = $_paint_messages['msg_title'];
47         $retval['body'] = '';
48
49         if (array_key_exists('attach_file',$_FILES)
50                 and array_key_exists('refer',$vars))
51         {
52                 $file = $_FILES['attach_file'];
53                 //BBSPaiter.jarは、shift-jisで内容を送ってくる。面倒なのでページ名はエンコードしてから送信させるようにした。
54                 $vars['page'] = $vars['refer'] = decode($vars['refer']);
55
56                 $filename = $vars['filename'];
57                 $filename = mb_convert_encoding($filename,SOURCE_ENCODING,'auto');
58
59                 //ファイル名置換
60                 $attachname = preg_replace('/^[^\.]+/',$filename,$file['name']);
61                 //すでに存在した場合、 ファイル名に'_0','_1',...を付けて回避(姑息)
62                 $count = '_0';
63                 while (file_exists(UPLOAD_DIR.encode($vars['refer']).'_'.encode($attachname)))
64                 {
65                         $attachname = preg_replace('/^[^\.]+/',$filename.$count++,$file['name']);
66                 }
67
68                 $file['name'] = $attachname;
69
70                 if (!exist_plugin('attach') or !function_exists('attach_upload'))
71                 {
72                         return array('msg'=>'attach.inc.php not found or not correct version.');
73                 }
74
75                 $retval = attach_upload($file,$vars['refer'],TRUE);
76                 if ($retval['result'] == TRUE)
77                 {
78                         $retval = paint_insert_ref($file['name']);
79                 }
80         }
81         else
82         {
83                 $message = '';
84                 $r_refer = $s_refer = '';
85                 if (array_key_exists('refer',$vars))
86                 {
87                         $r_refer = pagename_urlencode($vars['refer']);
88                         $s_refer = htmlsc($vars['refer']);
89                 }
90                 $link = "<p><a href=\"$script?$r_refer\">$s_refer</a></p>";;
91
92                 $w = PAINT_APPLET_WIDTH;
93                 $h = PAINT_APPLET_HEIGHT;
94
95                 //ウインドウモード :)
96                 if ($w < 50 and $h < 50)
97                 {
98                         $w = $h = 0;
99                         $retval['msg'] = '';
100                         $vars['page'] = $vars['refer'];
101                         $vars['cmd'] = 'read';
102                         $retval['body'] = convert_html(get_source($vars['refer']));
103                         $link = '';
104                 }
105
106                 //XSS脆弱性問題 - 外部から来た変数をエスケープ
107                 $width = empty($vars['width']) ? PAINT_DEFAULT_WIDTH : $vars['width'];
108                 $height = empty($vars['height']) ? PAINT_DEFAULT_HEIGHT : $vars['height'];
109                 $f_w = (is_numeric($width) and $width > 0) ? $width : PAINT_DEFAULT_WIDTH;
110                 $f_h = (is_numeric($height) and $height > 0) ? $height : PAINT_DEFAULT_HEIGHT;
111                 $f_refer = array_key_exists('refer',$vars) ? encode($vars['refer']) : ''; // BBSPainter.jarがshift-jisに変換するのを回避
112                 $f_digest = array_key_exists('digest',$vars) ? htmlsc($vars['digest']) : '';
113                 $f_no = (array_key_exists('paint_no',$vars) and is_numeric($vars['paint_no'])) ?
114                         $vars['paint_no'] + 0 : 0;
115
116                 if ($f_w > PAINT_MAX_WIDTH)
117                 {
118                         $f_w = PAINT_MAX_WIDTH;
119                 }
120                 if ($f_h > PAINT_MAX_HEIGHT)
121                 {
122                         $f_h = PAINT_MAX_HEIGHT;
123                 }
124
125                 $retval['body'] .= <<<EOD
126  <div>
127  $link
128  $message
129  <applet codebase="." archive="BBSPainter.jar" code="Main.class" width="$w" height="$h">
130  <param name="size" value="$f_w,$f_h" />
131  <param name="action" value="$script" />
132  <param name="image" value="attach_file" />
133  <param name="form1" value="filename={$_paint_messages['field_filename']}=!" />
134  <param name="form2" value="yourname={$_paint_messages['field_name']}" />
135  <param name="comment" value="msg={$_paint_messages['field_comment']}" />
136  <param name="param1" value="plugin=paint" />
137  <param name="param2" value="refer=$f_refer" />
138  <param name="param3" value="digest=$f_digest" />
139  <param name="param4" value="max_file_size=1000000" />
140  <param name="param5" value="paint_no=$f_no" />
141  <param name="enctype" value="multipart/form-data" />
142  <param name="return.URL" value="$script?$r_refer" />
143  </applet>
144  </div>
145 EOD;
146                 // XHTML 1.0 Transitional
147                 if (! isset($pkwk_dtd) || $pkwk_dtd == PKWK_DTD_XHTML_1_1)
148                         $pkwk_dtd = PKWK_DTD_XHTML_1_0_TRANSITIONAL;
149         }
150         return $retval;
151 }
152
153 function plugin_paint_convert()
154 {
155         global $script,$vars,$digest;
156         global $_paint_messages;
157         static $numbers = array();
158
159         if (PKWK_READONLY) return ''; // Show nothing
160
161         if (!array_key_exists($vars['page'],$numbers))
162         {
163                 $numbers[$vars['page']] = 0;
164         }
165         $paint_no = $numbers[$vars['page']]++;
166
167         //戻り値
168         $ret = '';
169
170         //文字列を取得
171         $width = $height = 0;
172         $args = func_get_args();
173         if (count($args) >= 2)
174         {
175                 $width = array_shift($args);
176                 $height = array_shift($args);
177         }
178         if (!is_numeric($width) or $width <= 0)
179         {
180                 $width = PAINT_DEFAULT_WIDTH;
181         }
182         if (!is_numeric($height) or $height <= 0)
183         {
184                 $height = PAINT_DEFAULT_HEIGHT;
185         }
186
187         //XSS脆弱性問題 - 外部から来た変数をエスケープ
188         $f_page = htmlsc($vars['page']);
189
190         $max = sprintf($_paint_messages['msg_max'],PAINT_MAX_WIDTH,PAINT_MAX_HEIGHT);
191
192         $ret = <<<EOD
193   <form action="$script" method="post">
194   <div>
195   <input type="hidden" name="paint_no" value="$paint_no" />
196   <input type="hidden" name="digest" value="$digest" />
197   <input type="hidden" name="plugin" value="paint" />
198   <input type="hidden" name="refer" value="$f_page" />
199   <input type="text" name="width" size="3" value="$width" />
200   x
201   <input type="text" name="height" size="3" value="$height" />
202   $max
203   <input type="submit" value="{$_paint_messages['btn_submit']}" />
204   </div>
205   </form>
206 EOD;
207         return $ret;
208 }
209 function paint_insert_ref($filename)
210 {
211         global $script,$vars,$now,$do_backup;
212         global $_paint_messages,$_no_name;
213
214         $ret['msg'] = $_paint_messages['msg_title'];
215
216         $msg = mb_convert_encoding(rtrim($vars['msg']),SOURCE_ENCODING,'auto');
217         $name = mb_convert_encoding($vars['yourname'],SOURCE_ENCODING,'auto');
218
219         $msg  = str_replace('$msg',$msg,PAINT_MSG_FORMAT);
220         $name = ($name == '') ? $_no_name : $vars['yourname'];
221         $name = ($name == '') ? '' : str_replace('$name',$name,PAINT_NAME_FORMAT);
222         $now  = str_replace('$now',$now,PAINT_NOW_FORMAT);
223
224         $msg = trim($msg);
225         $msg = ($msg == '') ?
226                 PAINT_FORMAT_NOMSG :
227                 str_replace("\x08MSG\x08", $msg, PAINT_FORMAT);
228         $msg = str_replace("\x08NAME\x08",$name, $msg);
229         $msg = str_replace("\x08NOW\x08",$now, $msg);
230
231         //ブロックに食われないように、#clearの直前に\nを2個書いておく
232         $msg = "#ref($filename,wrap,around)\n" . trim($msg) . "\n\n" .
233                 "#clear\n";
234
235         $postdata_old = get_source($vars['refer']);
236         $postdata = '';
237         $paint_no = 0; //'#paint'の出現回数
238         foreach ($postdata_old as $line)
239         {
240                 if (!PAINT_INSERT_INS)
241                 {
242                         $postdata .= $line;
243                 }
244                 if (preg_match('/^#paint/i',$line))
245                 {
246                         if ($paint_no == $vars['paint_no'])
247                         {
248                                 $postdata .= $msg;
249                         }
250                         $paint_no++;
251                 }
252                 if (PAINT_INSERT_INS)
253                 {
254                         $postdata .= $line;
255                 }
256         }
257
258         // 更新の衝突を検出
259         if (md5(join('',$postdata_old)) !== $vars['digest'])
260         {
261                 $ret['msg'] = $_paint_messages['msg_title_collided'];
262                 $ret['body'] = $_paint_messages['msg_collided'];
263         }
264
265         page_write($vars['refer'],$postdata);
266
267         return $ret;
268 }
269