POTI-boardのセキュリティを高めるために

poti-boardというPHPスクリプトをサイトに設置したいのですが、設置手順通... - Yahoo!知恵袋

このスクリプトはPHP5であるにも関わらず
extract($_POST);
extract($_GET);
extract($_COOKIE);
と、register_globals同等のことを自らやっているので、相変わらず脆弱性はあります。
PHP: extract - Manual

警告
ユーザーの入力、例えば $_GET や $_FILES のような、 信頼できないデータに extract() を使用しないでください。
今後も使い続けるために書き直す事にしました。
といっても、何がGETで何がPOSTなのかわからないところから検索して調べて…ですから、この人POSTとGETの違いがわからないのに掲示板をいじっていたの?と思われても仕方がない状態…からの書き直しとなりました。

extract($_POST); の問題点
extract($_POST);を使っていたら…。第三者がChromeのデベロッパーツールなどを使って、フォームの入力欄を変更すると任意の変数を設定できてしまいます。
ここでは、useneoの筈のところを改変してusenoeにしています。

extract($_POST); の問題点
var_dump($_POST);で確認してみると…。usenoe が on。
extract($_POST);なら、$usenoe=true;に。
そうならないように、あらかじめ設定した変数しか入らないように書き直しました。

extract($_GET); の問題点
extract($_GET);はもっと大変で、ブラウザのアドレスバーへの入力で任意の変数が作成できてしまいます。
また、?res=105 のような数字が入る事を期待している箇所にhtmlを入力すると入ってしまいます。

extract($_GET); の問題点
HTMLやjavaScriptが入力されたら、HTMLネームエンティティにエンコードして無害化するように書き直しました。
一部対応しきれなかったので穴がありますが、URLパラメータを入力するだけでは変数を設定できなくなりましたからかなりの改善…だと思います。

効率よく短くまとめる事ができるはずなのですが、技術も知識もないのでGitHub - sakots/noe: noe-board, the new oekaki BBS for php7のコードを拝借して、必要な変数を一個づつ追加していきました。
3行だった箇所が100行以上に膨れ上がりましたが、処理速度は速くなりました。

計測は、PHPの処理速度を計測 - Qiitaで…。
$usercode = ( isset($_COOKIE["usercode"]) === true ) ? ($_COOKIE["usercode"]): false;//falseならuser-codeを発行
//user-codeの発行
//if(!isset($usercode)){
if(!$usercode){//falseなら発行
$usercode =
動作確認に何日もかかった箇所。
user-codeのcookieが取得できない…。
isset($_COOKIE["usercode"])のところで未定義なら空文字となり、空文字でも定義ずみだからuser-codeを発行しないとなっていたただけでした。

もし未定義ならfalse、falseならuser-codeを発行するようにしました。
この箇所が今回の書き直しの最大の難関…でした。

そして、php5.2で動作確認してみると…文字化け。
$buf = charconvert(HtmlTemplate::t_buffer($template,$dat),'utf-8');
文字コードをutf-8に統一する時に4に置換したのがいけなかったようです。utf-8で出力するように書き直したところ、php5.2からphp7.2まで正常に動作するようになりました。

php4では動作しなくなっているので、動作するphpのバージョンを
if(phpversion()>="5.2.0"){
としました。

そして、@を使ったエラー制御があまりにも多かったので、@を外しました。
@を外したところディレクトリが存在しているからディレクトリを作れないというWarningが発生。
もし、ディレクトリが無かった時は作るとしました。
@mkdir(IMG_DIR,0777);chmod(IMG_DIR,0777);
if(!is_dir(realpath(IMG_DIR))){
mkdir(IMG_DIR,0777);chmod(IMG_DIR,0777);
}
に書き直し。

書き直した行数があまりにも多いので、プログラムを書くのが大変だった…でも間違いではないのですが、どちらかというと動作確認に時間がかかって大変…でした。

今でもメンテナンスされていて、誰でも開発に参加できるお絵かき掲示板のスクリプトはnoeを除くとPOTI-board改だけです。誰でも設置できるお絵かき掲示板の最後の砦になってしまいました。

この変更はPOTI-board改 v1.50.0に反映されました。

お絵かき掲示板交流サイトはこちら。

POTI-boardの処理速度をあげるために

PHP: for - Manual

for($i = 0; $i < count($people); ++$i) {
$people[$i]['salt'] = mt_rand(000000, 999999);
}
このコードは実行速度が遅くなることでしょう。 というのも、配列のサイズを毎回取得しているからです。 サイズが変わることはありえないのだから、これは簡単に最適化することができます。 配列のサイズを変数に格納して使うようにすれば、 何度も count() を呼ばずに済むのです。
他のfor文では変数に格納して処理しているのに、その他のfor文で同じ処理を変数に格納しないで行っているのは…整理したほうがいいので…。
//ここでcount($tree)を使うとループの回数分countする。$counttree = count($tree);で定義ずみ。
for($i = 0; $i < $counttree ; $i+=PAGE_DEF){
//中略
}
変数に置き換える事ができる箇所がそのほかにもあったので書き換えました。
念のため、
var_dump($counttree);
var_dump(count($tree));
が同じ結果になる事を確認しました。
var_dump($counttree);
var_dump(count($tree));
if($counttree > $next){
$dat['next'] = PHP_SELF.'?mode=catalog&amp;page='.$next;
}
POTI-board カタログモード var_dump($counttree); var_dump(count($tree));
どちらも(int)554。
はじめから
$counttree=count($tree);
for($i = 0;$i<$counttree;$i++){
//中略
}
となっている箇所もありました。

お絵かき掲示板交流サイトのPOTI-boardの該当箇所を書き直しました。

POTI-board改にこれからプルリクエスト…。

お絵かき掲示板はこちら。

POTI-boardのエラーを減らすために メール通知クラス編

POTI-boardの、メール投稿通知機能に使われているnoticemail.incというメール通知クラスから非推奨のエラーがでていました。
potiboard.phpに
ini_set( 'error_reporting', E_ALL );
を追加して、すべてのエラーを表示するように設定して調べた筈では?
投稿の直後に一瞬ちらっとみえるエラーが気になったので、「画面を切り替えます」の表示秒数を1秒から10秒に変更して確認してみたところ
Deprecated: Non-static method noticemail::send() should not be called statically in C:\xampp\htdocs\hoge\test\potiboard.php on line 1276
htmltemplate.incで発生していたのと同じエラーでした。
static 宣言されていないメソッドに対する static 呼び出しが非推奨となりました。 将来的には削除される見込みです
static 宣言すればエラーはでなくなるのですが…。本当にそれでいいのかどうかは、phpのバージョンがあがってみないとわからないという…。
とりあえずstatic 宣言して、E_DEPRECATEDが発生しないようにする事はできましたが…。実は動きませんだと困りますね…。
public static function send($data,$usemb="1"){
public staticをつけただけ…です。

そして、Noticeはもうでなくなった筈だったのですが…。

お絵かき掲示板 POTI-board 画像なし二重投稿の時に発生するNoticeお絵かき掲示板 POTI-board 画像なし二重投稿の時に発生するNotice

画像なしにチェックが入っていて二重投稿のエラーになる時にNoticeが発生していました。
if(isset($com)){
if(isset($textonly) && $textonly){//画像なしの時
$dest="";
}
switch文の手前だったので、画像なし=textonlyの時は画像に関する変数に空文字がはいるようにしました。
しかし、今度は…。

お絵かき掲示板 POTI-board 画像なしの時に発生するNoticeお絵かき掲示板 POTI-board 画像なしの時に発生するNotice
画像なしにチェックをいれてテキストの投稿に成功した時にNoticeが発生…。
たしか対策済みだった筈…と思って該当行をみてみると、
if(!isset($dest)){
$dest=$ext=$W=$H=$chk="";
}
もし、$destが未定義なら変数を空文字にとしていたため、$destに空文字がはいって定義済みの空文字となり、他の変数が空文字にならなくなっていました。

画像なしにチェックが入っている…という段階で、画像に関する変数が空文字になっても問題ない筈なので、
if(isset($textonly) && $textonly){
$dest=$ext=$W=$H=$chk="";
}
に書き換えました。

お絵かき、画像アップロード、レスでお絵かき、レス画像アップロード。
画像なしテキストのみ、レス画像なしテキストのみの組み合わせで1時間ほどテストして、お絵かき掲示板交流サイトのPOTI-boardに組み込みました。

この変更は、POTI-board改 v1.45.6 lot.181202に反映されました。

POTI-boardのログファイルの上限を2MBに

ぷち的ココロ♪

総レス数がまだ2800を超えた程度なのに、親記事のナンバーの低いスレが消えてしまっていました。
親記事ナンバー+5000レスをスレの消える寿命に設定するにはどうしたらいいのでしょうか?

スクリプトをちょっと見ただけなので間違いかもしれませんが
バッファに1000000byte読み込む処理があったので
logファイルの上限がおそらく約1Mbyteだと思います。
その上限を超えたので2800でレスが消えたのではないでしょうか
POTI-boardのログファイルの上限の1000000byteは15年前に設定されたものです。
パソコンに搭載されているメモリはこの15年で…。
今ではメモリ4GB…それでも少ないという時代になりましたが、15年前はハードディスクが8GBだったり…。
2倍の2MBに拡張しても問題なさそうな気がしたので、2倍の2000000byte…だと2MB以下になってしまうので該当箇所を
$buf=fread($fp,2097152);
$buf=fread($tp,2097152);
に書き換えました。
5MBのログに書き込み処理を行うと、2MBになる事を確認しました。

お絵かき掲示板交流サイトで使っているPOTI-boardのログの上限は5MBですが動作が重くなるようならログをリセットして運用するつもりです。
配布するスクリプトも5MB…だと、無料のサーバなどで問題がでるかもしれませんし、動作が重くなるかもしれません。
2倍の2MBならという判断です。

お絵かき掲示板 POTI-board Notice削減お絵かき掲示板 POTI-board Notice削減
if(isset($savepng)){
$dat['savetypes'].= "<option value='PNG'".$savepng.">PNG</option>\n";
}
if(isset($savejpeg)){
$dat['savetypes'].= "<option value='JPEG'".$savejpeg.">JPEG</option>\n";
}
保存形式をAUTO、PNG、JPEGから選択するテンプレートは今はほとんど使われていません。NEOでは何を選択してもPNGになるのであまり意味がありません。しかし、しぃペインターでは有効な設定なので、テンプレートに選択項目が無くてもNoticeが出ないように書き直しました。

お絵かき掲示板 POTI-board Notice削減お絵かき掲示板 POTI-board Notice削減
// if(!$com&&!@is_file($dest)) error(MSG008,$dest);

if(!$com&&!@is_file($dest)) error(MSG008);
画像が無い事を確認してエラー画面を表示しているのに、画像に関する処理をしようとしてNoticeがでていたので書き直しました。
<!--(// しぃで反映されない上にお絵かき画面でパレット変更できるのでコメント化
パレット<select name=palette><option value="" selected> デフォルト</option>
{$palette}
</select>
)-->
v1.32の MONO WHITEでコメントアウトされ、そのほかのテンプレートでも使用されていない機能でNoticeがでていたので、
//v1.32のMONO WHITEでコメントアウト、対応テンプレートが無いパレット選択用データ(selectタグ用option配列)
// $lines = file(PALETTEFILE);
// foreach ( $lines as $line ) {
// $line=preg_replace("/[\t\r\n]/","",$line);
// list($pid,$pname,) = explode(",", $line);
//if(isset($palette)){
// $dat['palette'] .= '<option value="'.$pid.'">'.CleanStr($pname)."</option>\n";
//}
// }
該当箇所をコメントアウトしました。

お絵かき掲示板 POTI-board Notice削減お絵かき掲示板 POTI-board Notice削減
if(isset($textonly) && $textonly){//画像なしの時
$upfile=$upfile_name=$pictmp=$picfile="";
if(!isset($resto)){$resto="";}
}
画像アップロード画面で、画像なしにチェックを入れた時に、Noticeが発生していたので、textonlyの時は画像に関する変数を空文字に。
また、変数が定義されていてtrueの時は…という処理をifの入れ子にしていましたが&&でつなぐだけで良かったので書き直しました。

お絵かき、レスでお絵かき、画像アップロード、レス画像アップロード、文字だけ…。
数時間テストしましたがとりあえずNoticeなし。
ただし、設置時にできる[1]を削除しないとNoticeが出ます。
ログの形式が[1]だけ異なっている事が原因なので、それを修正できればでなくなる筈なのですが…。
そして、管理画面で記事を削除するとNoticeが発生…。
2行程度ですが…。

この変更は、POTI-board改 v1.45.5 lot.181129に反映されました。

お絵かき掲示板はこちら。

POTI-boardのエラーを減らすために 動画再生編

PaintBBS NEOが動画の記録と再生に対応したので、絵板に動画へのリンクが増えて来ました。

動画を見ようとしてクリックすると…。

POTI-board お絵かき掲示板の改造

動画ファイルが存在しないというWarningが発生する事例が何件が…。
リロードしても動画ファイルは見当たらないまま…。

POTI-boardの動画再生のurlは画像のファイル名と紐付けられているので、続きから描いて画像のファイル名が変われば動画のurlも変わってしまいます。

つまり、掲示版を開いて動画のリンクをクリックしたタイミングによっては動画のファイルが無いかもしれません。
Google検索結果から動画のリンクを開いた時にも、動画がなくてWarningが発生していました。
if(file_exists($pchfile)){//動画が差し換えられていた時
$datasize = filesize($pchfile);
$size = getimagesize($picfile);
if(!$sp) $sp = PCH_SPEED;
$picw = $size[0];
$pich = $size[1];
$w = $picw;
$h = $pich + 26;
if($w < 200){$w = 200;}
if($h < 226){$h = 226;}
}
else{
$w=$h=$picw=$pich=$datasize="";
}
file_existsでファイルの存在を確認してから処理するようにしました。

POTI-board お絵かき掲示板の改造
動画が無い時は表示しないだけなのですが…。

POTI-board お絵かき掲示板の改造

.htaccessで、キャッシュの有効期限を過去にすればキャッシュされなくなるので問題ないのですが、投稿してもリロードしないと画面が更新されない、これはバグだ…と言われてしまったりもしているので、urlパラメータを追加してキャッシュを表示しないように。

さくらのブログの管理画面から記事を見るのリンクをクリックした時にurlのあとにつく、
?1542988451と同じ形式のurlパラメータです。
投稿するたびに変化するurlパラメータで、ブラウザに別のurlと認識させて、キャッシュを表示しないようにします。
<Files ~ "\.html?$">
<IfModule mod_headers.c>
Header set Pragma no-cache
Header set Cache-Control no-cache
Header set Expires "Thu, 01 Dec 1994 16:00:00 GMT"
</IfModule>
</Files>
.htaccessの使い方がわかっている方なら、これをコピペしてPOTI-boardのフォルダに入れるだけでHTMLファイルをキャッシュしないようにする事ができます。
サーバによってはうまくいかない場合もあるようですがさくらのレンタルサーバはこの設定で問題ありませんでした。
.htaccessでキャッシュの有効期限を過去にしたほうが、見た目もスマートだし掲示版を開いた時にキャッシュが表示される事もありません。
.htaccessで設定できない場合には有効かもしれない機能の追加…でした。

この変更は、POTI-board改 v1.45.3 lot.181122に反映されました。

お絵かき掲示板はこちら。

POTI-boardのエラーを減らすために 設置直後のNotice編

お絵かき掲示板交流サイトに4種類の掲示版を設置していましたが、PaintBBS NEOの描画アニメに対応できて、TwitterやFacebookに投稿した画像を表示できる仕組みも利用できるのはPOTI-boardだけだったので、6つの絵板をすべてPOTI-boardにしました。

そうなると…。
お絵かき掲示板の改造で注力するべきは、POTI-board…という事でNoticeを減らすための作業をすすめる事に。
前回の作業で、大量のNoticeはでなくなった筈だったのですが…。

POTI-board お絵かき掲示板の改造

まだログが20行存在していないのに過去の20行の二重投稿をチェックしようとしてNoticeが発生。
// 連続・二重投稿チェック (v1.32:仕様変更)
if($countline >= 21){//存在する行数のみチェック
$chkline=20;
}
else{
$chkline=$countline-1;
}
// for($i=0;$i<20;$i++){
for($i=0;$i<$chkline;$i++){
ログファイルが何行あるのかチェックして存在する行の数だけループするように書き換えました。

POTI-board お絵かき掲示板の改造

二重投稿のチェックが有効で、かつNoticeが出ない事を確認。
設置時にできる[1]のログの書式が他のものとは異なるため、[1]が残っているとNoticeが2行発生しますが、画面が埋まるほどのNoticeが発生する訳ではないので、許容範囲…ですね。

POTI-board お絵かき掲示板の改造

まだログが200行存在していないのに、過去の200行の画像重複をチェックしようとしてNoticeが発生。
// アップロード処理
if(isset($dest)){//未定義エラー対策
$countline=(count($line));
if($countline >= 201){//存在する行数のみチェック
$chkline=200;
}
else{
$chkline=$countline-1;
}
if($dest&&@file_exists($dest)){
// for($i=0;$i<200;$i++){ //画像重複チェック
for($i=0;$i<$chkline;$i++){ //画像重複チェック
こちらも、ログファイルが何行あるのかチェックして存在する行の数だけループするように書き換えました。

POTI-board お絵かき掲示板の改造

画像重複のチェックが有効で、かつNoticeが出ない事を確認しました。
// if($tree[$i]==""){
//空文字ではなく未定義になっている
if(!isset($tree[$i])){
また、カタログモードの時に、Noticeが発生していたのでしらべてみたら、空文字ではなく、未定義になっていたので書き直しました。

この変更は、POTI-board改 v1.45.3 lot.181122に反映されました。

お絵かき掲示板はこちら。

POTI-boardのメタタグにリンクのタグが入ると表示されてしまう

POTI-board メタタグにリンクのタグ

上のほうに、https://pbbs.sakura.ne.jp/のURLがでてしまっていますが…。
<meta property="og:description" content="<a href="https://pbbs.sakura.ne.jp/" target="_blank">https://pbbs.sakura.ne.jp/</a>">
のようのように、og:descriptionにリンクのタグが入るとこうなります。
コメントを表示するための変数からタグを除去して、別な変数として設定する事にしました。
//メタタグに使うコメントから
//タグを除去
$descriptioncom=strip_tags($com);

// 親記事格納
$dat['oya'][$oya] = compact('src','srcname','size','painttime','pch','continue','thumb','imgsrc','w','h','no','sub','name','now','com','descriptioncom','limit','skipres','resub','url','email','id','updatemark','trip','tab','fontcolor');
// 変数クリア
unset($src,$srcname,$size,$painttime,$pch,$continue,$thumb,$imgsrc,$w,$h,$no,$sub,$name,$now,$com,$descriptioncom,$limit,$skipres,$resub,$url,$email);
タグを除去したあと、テンプレートで別な変数として使えるようにしないといけないので、変数の一覧も変更しました。
<!--{each oya}-->
<meta property="og:description" content="{$oya/descriptioncom}" />
<!--{/each}-->
のように書けばスレッドの親のコメントからタグを除去したものをテンプレートに使う事ができるようになります。
使用例。
<!--SNS-->
<!--{def sharebutton}-->
<!--{each oya}-->
<meta name="Description" content="{$oya/descriptioncom}">

<meta name="twitter:card" content="summary" />
<meta property="og:title" content="[{$oya/no}] {$oya/sub} by {$oya/name} - {$title}" />
<meta property="og:type" content="article" />
<meta property="og:url" content="{$rooturl}{$self}?res={$oya/no}" />
<!--{def oya/src}-->
<meta property="og:image" content="{$rooturl}{$oya/imgsrc}" />
<!--{/def}-->
<meta property="og:site_name" content="" />
<meta property="og:description" content="{$oya/descriptioncom}" />
<!--{/each}-->
<!--{/def}-->

<!--/SNS-->

POTI-board用テンプレート PINK を配布します。: STP^3

配布しているテンプレートはこの変数に対応しています。
タグを除去した親のコメントをTwitterカードに表示できるようになります。
このSNS用のメタタグは、config.phpでシェアボタンを使う設定しないと出てきません。
積極的にお絵かき掲示板の存在をアピールしたい人もいればひっそりと描きたい人もいる筈なので切り替えられるようにしておきました。

この変更は、POTI-board改v1.45.2 lot.181110に反映されました。

お絵かき掲示板はこちら。

POTI-boardでしぃペインターを使う時の幅と高さを変更

お絵かき掲示板交流サイトは、Googleで「しぃペインター」で検索すると上位に出てきます。
でも、Javaの有償化とか…Macで唯一の頼りだったSafariがJavaの対応を終了したり…。
おそらくもう使う事ができなくなって終わりだろう…と思っていました。
ところが、CheerpJ Applet RunnerというChromeのプラグインを使えば、動作するらしい…。
以下はお絵かき掲示板Art.netのテキスト掲示版のそとさんの書き込みを抜粋したものです。
SetEnvIfNoCase Request_URI \.jar$ no-gzip dont-vary

と、記入した.htaccessファイルを作成して、
relmフォルダに配置することで動きました。(Apache2.2)
<script>
function cheerpJLoad() {
var jEnabled = navigator.javaEnabled();
if(!jEnabled){
var sN = document.createElement("script");
sN.src = "https://cjrtnc.leaningtech.com/latest/loader.js";
var s0 = document.getElementsByTagName("script")[0];
s0.parentNode.insertBefore(sN, s0);
sN.addEventListener("load", function(){ cheerpjInit(); }, false);
}
}
window.addEventListener("load", function() { cheerpJLoad(); }, false);
</script>
今後も必要になるので転載させていただきました。
ということは、今後もJavaアプレットが動くかもしれない…という事ですね。
POTI-boardでしぃペインターを使ってみると…。

CheerpJでしぃペインター

レイヤーやテクスチャなどのパレットがキャンバスを覆ってしまいます。
窓ボタンを押せば全画面表示になりますが動的パレットを使う事ができません。
BBSNoteには、アプレットフィットボタンがあるので横幅をモニターに合わせる事ができるのですが…。

しぃペインターの時の幅と高さをPaintBBSとは違う値に設定して調整する事にしました。
// $w = $picw + 150;
if(!$useneo && $shi){
$w = $picw + 465;//しぃぺの時の幅
$h = $pich + 120;//しぃぺの時の高さ
}
else{
$w = $picw + 150;//PaintBBSの時の幅
$h = $pich + 170;//PaintBBSの時の高さ
}

CheerpJでしぃペインター CheerpJでしぃペインター

しぃペインターのパレットを快適に使うには、最低でもこれだけの幅は必要…と判断しました。
また、しぃペインターではアプレットの高さをやや低めに設定しないと、投稿ボタンがキャンバスより上の位置になるためボタンを押しにくくなってしまいます。
そのあたりも考慮しました。

この変更は、POTI-board改v1.45.2 lot.181110に反映されました。

お絵かき掲示板はこちら。

POTI-boardのエラーを減らすためにE_NOTICE削減編

Noticeが投稿時に300行以上発生していたので修正しました。
また、設置時にできる[1]を編集すると、その後の書き込みでWarningが発生するので修正しました。

数値にNULLが入るので、(int)で処理

[1]を編集すると、連続投稿の時間を計算している箇所にNULLが入りWarningが発生するので…。
//文字列を整数に
$ltime = (int)$ltime;
if(RENZOKU && $time - $ltime < RENZOKU){error(MSG020,$dest);}
if(RENZOKU2 && $time - $ltime < RENZOKU2 && $upfile_name){error(MSG021,$dest);}

数値にNULLが入るので、(int)で処理

空文字だったところがint(0)になりました。

Warningが出ていますが、var_dump()で変数を確認すると出る箇所なので仕方がありません。通常の使用では発生しません。

投稿時に大量のNoticeが発生するのを修正投稿時に大量のNoticeが発生するのを修正

投稿時に大量のNoticeが発生。
ログがあまり多くなかった時にはあまり気にならなかったのですが、運営中のレス数が1600件ほどあるPOTI-boardではレスを送信するたびに300行以上のNoticeが発生しました。
// レス記事一括格納
if(isset($rres)){//未定義エラー対策
$dat['oya'][$oya]['res'] = $rres[$oya];
}

レスがついていないスレッドの数だけエラーが出るので、未定義の場合は処理しないように書き直しました。
その他、画像アップロードの時と、お絵かきの投稿の時と、文字だけの投稿の時に、それぞれ未定義になる変数が存在していたので空文字を入れるようにしました。
//未定義エラー対策
if(isset($picfile)){//お絵かきの時
$upfile=$upfile_name="";
if(!isset($resto)){$resto="";}//レスではなかった時
}
elseif(isset($upfile)){//画像アップロードの時
$pictmp=$picfile="";
if(!isset($resto)){$resto="";}
}
else{//文字だけの時
$upfile=$upfile_name=$pictmp=$picfile="";
if(!isset($resto)){$resto="";}
}
regist($name,$email,$sub,$com,$url,$pwd,$upfile,$upfile_name,$resto,$pictmp,$picfile);

htmltemplate.incの79行目で発生するNoticeも投稿時にくりかえし出てきます。
まず、var_dump()で変数の内容を確認。

投稿時に大量のNoticeが発生するのを修正
//未定義エラー対策
if(isset($match[1])){
$ind=$this->getIndex($match[1],$multilabels);
}
else{
$ind=$this->getIndex("",$multilabels);
}
($match[1]))が未定義の時は、代わりに空文字が入るようにしました。
この変更を行っても$indに入る文字列は同じである事を確認しました。

気を使った点…。
変数に空文字を入れて対処した事で動作がおかしくなっていないか?
画像アップロードに必要な変数に空文字が入れば画像がありませんとなるし、お絵かきの投稿の時に必要な変数に空文字が入ればやはり画像がありませんになってしまいます。

新規スレッドに画像アップロード、お絵かき、文字だけの投稿。
レスで画像アップロード、お絵かき、文字だけの投稿。
続きから描く、動画表示。
ひととおりテストして、運営している絵板サイトにも導入してトラブルが起きていない事を確認したので、公開版の候補にする事にしました。
それから…。
salt パラメータは必須ではありませんが、これを省略すると crypt() が作るハッシュが弱いものになってしまいます。 PHP 5.6 以降は、このパラメータを省略した場合に E_NOTICE が発生するようになりました。
time()をsaltに使い差し換え時の動作に問題がないことを確認しました。
//差し換え時の認識コード追加
if($type=='rep'){
// $repcode = substr(crypt(md5($no.getenv("REMOTE_ADDR").$pwd.date("Ymd", time()))),-8);
$repcode = substr(crypt(md5($no.getenv("REMOTE_ADDR").$pwd.date("Ymd", time())),time()),-8);
この変更は、POTI-board改v1.45.2 lot.181110に反映されました。

お絵かき掲示板はこちら。

POTI-boardのエラーを減らすために htmltemplate.inc編

potiboard.phpに
ini_set( 'error_reporting', E_ALL );
を追加して、すべてのエラーを表示するように設定。
E_DEPRECATEDレベルのエラーが大量に発生しているのを確認しました。
POTI-boardで使っているhtmltemplate.incに問題があるようです。

POTI-board htmltemplate.inc php7 E_DEPRECATED
PHP: PHP 7.0.x で推奨されなくなる機能 - Manual

PHP 4 形式のコンストラクタ
非 static メソッドに対する static 呼び出し
将来のバージョンでは動作しなくなるので今のうちに警告…という事ですね。
PHP 4 形式のコンストラクタ (クラス名と同じ名前のメソッドを定義するもの) が非推奨
__construct() メソッドを実装していれば、この警告は発生しません。
該当する箇所は…。

POTI-board htmltemplate.inc php7 E_DEPRECATED
class StandardParser extends TemplateParser{
// function StandardParser(){
function __construct(){
class htmltemplate{
private $parser;
// the constructor
// private function htmltemplate(){
private function __construct(){
の2箇所でした。
static 宣言されていないメソッドに対する static 呼び出しが非推奨となりました。 将来的には削除される見込みです。
それなら…static 宣言すれば、という事で、

POTI-board htmltemplate.inc php7 E_DEPRECATED
public static function add($tag){
// This method is obsolete.Use addTag() instead.
$inst=&htmltemplate::getInstance();
$inst->parser->add($tag);
}
POTI-board htmltemplate.inc php7 E_DEPRECATED POTI-board htmltemplate.inc php7 E_DEPRECATED

左、htmltemplate.inc書き直し前、右、書き直し後。
とりあえず、エラーがでなくなるところまで何とか。
PHP 5からPHP 7へ移行する際に気を付けるべきポイント (1/4):CodeZine(コードジン)

staticメソッドとして宣言したメソッドをインスタンスメソッドとして実行するにはワーニングなどが表示されないようですが、こちらも良いコードとは言えませんので、もしそのようなコードがあればこの機会に対応することをおすすめします。

インスタンスを使っているのに静的というのはおかしいという事なのでしょうね…。
staticなプロパティの使いどころ - PHPで翻訳三昧

PHP5からは、static を指定したプロパティは
インスタンス化しなくてもアクセス出来るよう変わりました。

php5ではもっと簡単にわかりやすく書ける…みたいです。

GitHub - sakots/poti-kai: POTI-board, the oekaki BBSサ骨さんによるオープンソースプロジェクトです。
phpのプログラムを書き慣れている方なら、おそらくhtmltemplate.incの問題の箇所を修正できると思います…。

どこが問題なのか、コメント行にも書いておきましたのでよろしくお願いいたします。
これから、サ骨さんのところにアップします…。

POTI-boardのログファイルを解析するphp

phpでお絵かき掲示板の最新画像を表示: STP^3のphpで呼び出した画像を元に、POTI-boardのログファイルを開いて、その画像の該当スレッドへのリンクと、タイトル、作者名を呼び出すphpの改良版です。

運営しているお絵かき掲示板では、レスでお絵かきを許可する設定にしていないので、ここまでする必要は無かったのですが、レスでお絵かきを使っていても、正確に該当スレッドへのリンクになるようにしておきたかったので工夫してみました。

プログラムの最初の行にコメントアウトしたファイル名がならんでいますが、本来はphpで呼び出すところを手動で入力してみて期待した動作になるかどうかテストをしたあとです。

設置しているPOTI-boardによって、この画像ファイルのURLや番号は変わりますので、このプログラムをそのまま設置しても動作しません。
使う場合は、入れ替えるべき箇所を入れ替える必要があります。
<?php
//画像のパスとファイル名
$imgno = 'poti/src/OB1529126099132.png';
//$imgno = 'poti/src/OB1532687964328.png';
//$imgno = 'poti/src/OB1515724311525.png';
//$imgno = 'poti/src/OB1516791076735.png';
//$imgno = 'poti/src/1525238233707.png';
//13桁のUNIX timeにする
$imgno = substr($imgno, -17,-4);
$fp = fopen("poti/img.cgi", "r"); //ログファイルの場所
while ($line = fgets($fp)) {
//ログファイルの書式から変数を取得
list($no,$now,$name,$email,$sub,$com,$url,
$host,$pwd,$ext,$w,$h,$time,$chk,$ptime,$fcolor) = explode(",", $line);
//KASIRAで指定した文字列を取り除く
//OBを取って13桁のUNIX timeにする
// $time = ltrim($time, 'OB');
//後ろから13桁のほうが確実なので書き直した
$time = substr($time, -13);
//取得したファイル名の
//13桁のUNIX time
//と$timeが同じならスレッドの番号は$no?
if ($time == $imgno){
$resno = $no;
break;
}
}
//レス画像かもしれないので、tree.logを見に行く
fclose($fp);
$fp = fopen("poti/tree.log", "r"); //ログファイルの場所
while ($line = fgets($fp)) {
//ログファイルの書式から変数を取得
$tree = explode(",", $line);//コンマ区切り形式のログの解析
$i=0;
$a=mb_substr_count("$line", ",")+1; //レスの数
//コンマ区切りなのでコンマの数+1。
while ($i < $a) {//0からレスの数までループ
if(rtrim($tree[$i], "\n")==$resno){
$resno=rtrim($tree[0], "\n");//スレッドの番号は$tree[0]
$count_end=true;//カウント終了
break;
}
if($count_end){break;}//レス先が見つかったのでbreak
echo "$i</br>";//確認用、実際には使わない。
$i++;
}
}

fclose($fp);
//掲示板のレス送信画面にリンク
echo '<a href="poti/potiboard.php?res='.$resno.'">掲示板</a></br>';
//タイトルを表示
echo "$sub</br>";
//投稿者名を表示
echo "$name</br>";
?>
なんども、無限ループになって青ざめましたが、なんとかここまで。レスの数だけループして番号を探すようにしたので、無駄にループする事がなく、またループの数が足りないという事もおそらく起きない…と思います。
$i=0;
$a=mb_substr_count("$line", ",")+1; //レスの数
//コンマ区切りなのでコンマの数+1。
while ($i < $a) {//0からレスの数までループ

何度も失敗しながらやっとここまでたどり付いた問題の箇所。
ループ文の中でループしているので、ループの条件を明確にしないと無限ループになりかねない、簡単そうでおそろしい箇所でした。

お絵かき掲示板のログ処理 php

テストプログラムなので、実行結果はあじけないこんな感じの画面です。
縦にならんでいる数字は、tree.logを読み込んだ回数です。ここが1とか2とか3ならサーバにそれほど負荷がかからないと思いますが、1000とか5000になると負荷がかかりすぎてプログラムが終了したり、高負荷になってサーバの制限がかかるかもしれません。
間近の画像を呼び出しているだけなら、それほど高い負荷にはならないはずですが、管理画面でリソースのチェックをして大丈夫かどうか確認したほうがいいのかもしれません。

プログラムを書ける人なら、こんなサンプルプログラムは必要ないのかもしれないし、書けない人には意味がわからないかもしれない。
さらにPOTI-boardのログを別のphpで使うプログラムなので、絵板を設置をするだけなら関係ない。
そんな、お絵かき掲示板をいくつも設置しているサイトのトップページに使う事を想定したプログラムですが、せっかく書いたので、サーバから消す前にブログにまとめておこうと思いました。

お絵かき掲示板はこちら。

javaScriptでURIエンコードしてaタグのテキストリンクを作る

お絵かき掲示板にツイートボタンをつけました。
アイキャッチ画像が投稿したイラストになるのは、今のところPOTI-boardだけで、その他の掲示板は、固定されたOGPイメージの表示になりますが、お絵かき掲示板の個別スレッドのリンクを観てもらう事はできます。

以下は、お絵かき掲示板にツイートボタンを設置するために試行錯誤した記録です。ツイートボタンのカスタマイズ方法を探している方はこんな記事を読む暇があったら
ツイートボタンのカスタマイズまとめ。 - freefielder.jp
にいますぐ移動する事をおすすめします。(ダメじゃん
twitterのツイートボタンを作るためのリンクshareとintent/tweet

ツイートボタンをaタグで作成するための基本的な情報…なのですが、URIエンコード済みである事が前提なので、テキストがShiftjisだと文字化けします。

urlの途中に、&が入っていると正しく動作しません。Bracketsの右クリック拡張のURIエンコードを使えば対応できる場合もありますが…。

また、人から見るとURIエンコードされたURLは、文字化けした文字列になるので可読性がよくありません。
seesaaブログに「twitterにつぶやくボタン」を簡単に設置する方法 | kira-ism
URIエンコードができて、aタグでリンク。文字化けしないしURLに&が入っていてもURIエンコードされているので機能します。
<a href="javascript:window.location='https://twitter.com/intent/tweet?status='+encodeURIComponent('No.$LOGNO $TITLE by $NAME #お絵かき掲示板')+' '+encodeURIComponent('https://pbbs.sakura.ne.jp/cgi/relm/relm.cgi?mode=res&no=$LOGNO')+' (via @satopian)';" onclick="window.open(this.href, 'relmtweet$LOGNO', 'width=650, height=470, personalbar=0, toolbar=0, scrollbars=1, sizable=1'); return false;" rel="nofollow" class="twitter-link">
<span class="icon-twitter"></span>tweet</a>
ところが…ブラウザ側の問題なのか
href属性値にスクリプトは書けません(といっておく)
という事なのか、IE11とSafariでは動作しない事がわかりました。

ツイートボタンのカスタマイズ Javascript

javascript:window.locationで始まるリンクは動作しない?
ChromeとFirefoxでは動作するので、もしかするとレガシーなブラウザでは動作しないだけなのかもしれないのですが…。

URIエンコードをして、それをaタグのリンクにするには…。

URIエンコードはできるか?
できる。
それを文字列とつなげたら?
動かない。

文字列と変数を一緒に書く方法がわからなかったので、文字列も変数にして、変数+変数+変数のようにしてみました。
<script>
tweetmessage=encodeURIComponent('No.$LOGNO $TITLE by $NAME #お絵かき掲示板');
tweeturl=encodeURIComponent('https://pbbs.sakura.ne.jp/cgi/relm/relm.cgi?mode=res&no=$LOGNO');

//リンクのタグ
twlink1="<a target=\"_blank\" href=\"https://twitter.com/share?text=";
twlink2="&url=";
twlink3="&\""
twlink4="<span class=\"icon-twitter\"></span>tweet</a>"
tweettags=twlink1+tweetmessage+twlink2+tweeturl+twlink3+twlink4;

document.write(tweettags);
</script>

ツイートボタンのカスタマイズ Javascript

やった…動いた…と思ったのですが…。

ツイートボタンのカスタマイズ Javascript

左から1番めのようになりました。
twitterの鳥アイコンが2つならんでしまいます。

ツイートボタンのカスタマイズ Javascript

デベロッパーツールで問題の箇所を確認してみたりもしたのですが…。
なぜtwitterのアイコンが二重になるのか、さっぱり…。
<script>
(function(){
var url = encodeURIComponent('https://pbbs.sakura.ne.jp/cgi/relm/relm.cgi?mode=res&no=$LOGNO'); //ページURL。一応エンコード
var title = encodeURIComponent('No.$LOGNO $TITLE by $NAME #お絵かき掲示板'); //ページタイトル。同上。
document.write( '<a target="_blank" href="https://twitter.com/intent/tweet?&text=' + title + '&url=' + url + '"><span class="icon-twitter"></span>tweet</a> <a target="_blank" class="fb btn" href="http://www.facebook.com/share.php?u=' + url + '"><span class="icon-facebook2"></span>share</a>' );
})();
</script>

JavaScriptを使った原始的な方法ならばこんな感じ。ボタンを表示したい場所に以下のコードを書きます。を参考にして、書き換えたものですが99%コピペですね…。

functionとdocument.writeを組み合わせたらいいのかな…となんとなく思ってはいたのですが、そのものズバリの答え…でした。

Chrome、Firefox、IE11で動作する事を確認しました。
javaScriptが実行された結果HTMLに出力されるのはaタグのテキストリンクなので、facebookのシェアボタンにも使ってみました。

ツイートボタンのカスタマイズ Javascript

facebookのシェアのリンクも動作しているみたいです…。みたい…というのはfacebookのアカウントが無いので、おそらく動くはずの書き方をしただけだからです…。

ツイートボタンを設置したお絵かき掲示板はこちら。

Chrome68 オートフィルを抑止したいだけなのに新規パスワード生成メニューが出る

Chrome68で、
autocomplete="new-password"
が設定されたパスワード入力欄をクリックすると…。

0827_001.png

Chromeが生成したパスワードをおすすめします…というメッセージ。
これまでは、オートフィルを抑止するだけで、右クリックするとChromeで記憶しているパスワードを呼び出す事ができたのですが…。
新規パスワードなのに記憶したパスワードを使う?という判断をするようになったようです。
フォームの自動補完を無効にするには - ウェブセキュリティ | MDN

他人のパスワードを指定するようなユーザー管理ページを定義していて、パスワード欄のオートフィルを抑止したい場合は、 autocomplete="new-password" を使用することができます。ただし、この機能はまだ Firefox に実装されていません。

この記事を参考にして、autocomplete="new-password"を使っていたのですが、元の記事も加筆されていて、他人のパスワードを指定するような時…となっていますね。

POTI-boardの編集・削除用のメンテナンス欄は数字+パスワードなのですが…。

0827_002.png

数字のところに、ユーザー名=名前がオートフィルで入ってしまって…。
ここは数字なのだから、明確にこの入力欄には数字しか入らないようにできないのかな…と思って検索してみたら…。HTML5には、input type="number" が…。
<input type="number" min="1" name="del[]" autocomplete="off" class="edit_number">

無指定だとマイナスの数字も入ってしまうので、最小値を1に設定しました。

0827_003.png

数字の入力欄をクリックすると、ユーザー名として記憶されている名前がでてきますが、全角文字なので数字の入力欄には入らない。パスワードは記事の投稿時に記憶したものが入るので、編集・削除の時に困らない。
とりあえずは…これで何とか。

もしかしたら、もっといい方法があるのかもしれないのですが…。

POTI-board用テンプレート PINK を配布します。: STP^3

配布しているテンプレートも修正してバージョンアップしておきました。

POTI-boardのエンコードをutf-8に固定

potiboard.phpの80行目付近のswitch文をコメントアウトして、utf-8にするところまでは、運営している絵板サイトでもやっていました…。
//switch(CHARSET_OUT){
// case 1 : $charset="EUC-JP";break;
// case 2 : $charset="Shift_JIS";break;
// case 3 : $charset="ISO-2022-JP";break;
// case 4 : $charset="UTF-8";break;
// default : $charset=CHARSET_OUT;
//}
define('CHARSET_HTML', "UTF-8");
でも、確かconfig.phpの
define('CHARSET_OUT', '4');
define('CHARSET_IN', '4');
を4以外に変更すると、問題が起きたような…。
思っていたよりも、面倒な作業だと思ったので、途中でやめていたのですが…。
GitHub - sakots/poti-kai: POTI-board, the oekaki BBS

[2018/08/22] v1.44.3 lot.180822【仕様変更】 文字コードをUTF-8に固定
utf-8固定になりました。

POTI-board

define('CHARSET_OUT', '2');
2:Shift_JISにすると文字化け…。
この設定はまだ生きているようです。

POTI-board

define('CHARSET_IN', '2');
2:Shift_JISにすると投稿できなくなりました。
この設定もまだ生きているようです。

POTI-board

$charsetが未定義になっているような気がしたので、echo $charset;
すると、CHARSET_IN、CHARSET_OUTそれぞれの値がレス返信モードの時に表示されました。
$charsetが4にならないと、期待した動作にならないようです。

対処。

POTI-board

define('CHARSET_CONVERT', '0');
という事は、 if(CHARSET_CONVERT) return $str; のif文は必要ないのでコメントアウト。続くswitch文も無効にして、utf-8に固定。

potiboard.php内の、CHARSET_OUTと、CHARSET_INを4に置換。

config.phpで設定を変更しても無効になる事を確認するため、
設定項目そのものをコメントアウト。

数時間テストしてみましたが…これで問題ないようです。
お絵かき掲示板交流サイトで使っているPOTI-boardに導入しました。

文字エンコードの設定項目がなくても、utf-8で正常動作するようになった…と本人は思っていますが…。
本人以外のほうが気が付きやすいのがバグですから、おかしな動作をしているようでしたら教えてください。

この仕様は、POTI-board改 v1.44.4 lot.180825に反映されました。

お絵かき掲示板はこちら。

お絵かき掲示板交流サイトのSSL/TLS対応作業を行いました

お絵かき掲示板 SSLお絵かき掲示板 SSL

google Chrome。
左、保護されていません、右、保護された通信。

お絵かき掲示板 SSLお絵かき掲示板 SSL

Firefox。
左、この接続は安全ではありません、右、警告表示なし。

https;// なのに、 http:// の画像がまぎれこんでいると混在表示コンテンツになり、すりかえられた画像の可能性があるという警告がでますが、秀丸エディタのgrepして置換で処理。

アクセスログのための1pxの画像を、 http:// から、// に書き換えて、https:// でも、http:// でも対応できるようにしました。
何ページ分あっても、同じタグの書き換えなので、grepして置換すれば数秒で終わります。

さくらのブログはSSLに対応していませんが画像はhttps://でも呼び出す事ができるので、RSSからブログの画像を取得するphpを書き換えました。
<?php
//SSL対応 http:を取り除く
$image = $item->thumbnail;
$image = ltrim($image, "http:");
?>
PHP: ltrim - Manual

ltrim − 文字列の最初から空白 (もしくはその他の文字) を取り除く
ltrimで、画像のURLからhttp:を取り除きました。

何もかもスムーズにいく…と思ったのですが…。
TLS 1.0/1.1無効化のメンテナンスによる影響 – さくらのサポート情報

通信の安全性を確保するため、 「弊社レンタルサーバで運営されているお客様のウェブページ」
における「TLS1.0/1.1」による暗号化通信を無効化いたします。
.htaccessでリダイレクトをかけたところ、Mac OS10.6、Windows XPで投稿している方がアクセス不能に…。
リダイレクトをかけるのをやめました。

https://から、sを取ってもらい、http:// で掲示板を使ってもらう事に…。
でも、Windows7以降ならTLS1.2に対応したブラウザを使う事ができるから何も意識しなくても大丈夫…と思ったら、コメントの投稿時に「〜を待機しています」が長く続き「このページは動作していません」が頻発。

20回に一回の割合で画面がかたまってしまいました。
〜を待機していますが長時間続きエラーになる時は | 気軽にお絵かき | お絵かき掲示板交流サイト

セキュリティ対策ソフトの影響によりgoogle Chromeなどで、「pbbs.sakura.ne.jpを待機しています」という表示が長く続き、「このページは動作していません」というエラーになる事があります。
一部のSSLサイト(「https://」で始まるWebページ)が表示できない | ESETサポート情報
軽いから使っていたNOD32アンチウイルスが原因でした…。
「SSL/TLSプロトコルフィルタリング」機能からChromeを除外したところ、Pawooで頻発していたトゥートボタンを押した時に固まる事がある問題も解決しました。

他にもESETのセキュリティ対策ソフトを使っている方がいる筈ですから、設定の変更をお願いしなければならなくなってしまいました…。

そして、SSLにしたら、検索順位が下がって表示できなくなってしまったコンテンツ…。
いつかは元に戻るのでは?と思いながら何度も検索。

思っていたより労力が必要でした…。

お絵かき掲示板はこちら。