<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>m1chu.eu - another devblog &#187; Bugtrack</title>
	<atom:link href="http://m1chu.eu/category/ogolne/bugtrack/feed/" rel="self" type="application/rss+xml" />
	<link>http://m1chu.eu</link>
	<description>we live, as we dream... alone - another devblog</description>
	<lastBuildDate>Sun, 14 Nov 2010 11:07:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Ciąg dalszy problemów z przekazywaniem tablic w phpBB by Przemo 1.12.5</title>
		<link>http://m1chu.eu/2008/03/22/ciag-dalszy-problemow-z-przekazywaniem-tablic-w-phpbb-by-przemo-1125/</link>
		<comments>http://m1chu.eu/2008/03/22/ciag-dalszy-problemow-z-przekazywaniem-tablic-w-phpbb-by-przemo-1125/#comments</comments>
		<pubDate>Sat, 22 Mar 2008 18:04:22 +0000</pubDate>
		<dc:creator>m1chu</dc:creator>
				<category><![CDATA[Bugtrack]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpBB]]></category>
		<category><![CDATA[memberlist]]></category>
		<category><![CDATA[phpbb by przemo]]></category>
		<category><![CDATA[tablice]]></category>

		<guid isPermaLink="false">http://m1chu.eu/bugtrack/ciag-dalszy-problemow-z-przekazywaniem-tablic-w-phpbb-by-przemo-1125</guid>
		<description><![CDATA[Jeszcze w wigilię roku poprzedniego opisywałem rozwiązanie drobnego problemu z przekazywaniem tablic w jednym z plików forum phpBB by Przemo. Co ciekawsze na zasadzie tak jak poprzednio doszliśmy do wniosku, że skrypt ten w większości przypadków filtrowania danych wejściowych nie pozwala na poprawne filtrowanie przekazywanych tablic. Dla przykładu podam kilka konkretnych błędnych elementów kodu wraz [...]]]></description>
			<content:encoded><![CDATA[<p>Jeszcze w wigilię roku poprzedniego <a href="http://m1chu.eu/bugtrack/przekazywanie-tablic-w-memberlistphp-phpbb-by-przemo-1125"  title="Przekazywanie tablic w memberlist.php">opisywałem</a> rozwiązanie drobnego problemu z przekazywaniem tablic w jednym z plików forum <a target="_blank" href="http://przemo.org"  title="Strona skryptu">phpBB by Przemo</a>. Co ciekawsze na zasadzie tak jak poprzednio doszliśmy do wniosku, że skrypt ten w większości przypadków filtrowania danych wejściowych nie pozwala na poprawne filtrowanie przekazywanych tablic.</p>
<p><span id="more-34"></span></p>
<p>Dla przykładu podam kilka konkretnych błędnych elementów kodu wraz z jednym z rozwiązań poprawkowych. Dodam na wstępie, że wszelkie podane bugi dotyczą elementu tablicy globalnej o nazwie <strong>mode</strong> lub <strong>folder</strong> występujących w kilku osobnych plikach. Kolejno &#8211; <strong>privmsg.php</strong> standardowo może przyjmować domyślnie w tym elemencie wartości takie jak <strong>birthday</strong>, <strong>newpm</strong>, czy <strong>read</strong>. Co jeśli ktoś zażyczy sobie np. dla testu przekazać wartość w postaci elementu tablicy?</p>
<pre class="brush: php; title: ;">if ( !empty($HTTP_POST_VARS['mode']) || !empty($HTTP_GET_VARS['mode']) )
{
	$mode = ( !empty($HTTP_POST_VARS['mode']) ) ? $HTTP_POST_VARS['mode'] : $HTTP_GET_VARS['mode'];
	$mode = htmlspecialchars($mode);
}
else
{
	$mode = '';
}</pre>
<p>To kod odpowiadający za podstawowe filtrowanie wprowadzanych danych. Niestety nie sprawdza się on w wypadku, gdy w adresie forum wprowadzimy np. poniższy adres:</p>
<blockquote><p>/privmsg.php?mode[]=1,2,3</p></blockquote>
<p>Niby w tym przykładzie oprócz wizualnych większych szkód nie ma, nie mniej jest to bug. Teoretycznie można by wprowadzić dwa rodzaje korekt w tym kodzie. Jeden w stylu mojego ostatniego wpisu z tej tematyki, a mianowicie:</p>
<pre class="brush: php; title: ;">if ( is_array($HTTP_POST_VARS['mode']) || is_array($HTTP_GET_VARS['mode']) )
{
	$mode = '';
}
else if ( !empty($HTTP_POST_VARS['mode']) || !empty($HTTP_GET_VARS['mode']) )
{
	$mode = ( !empty($HTTP_POST_VARS['mode']) ) ? $HTTP_POST_VARS['mode'] : $HTTP_GET_VARS['mode'];
	$mode = htmlspecialchars($mode);
}
else
{
	$mode = '';
}</pre>
<p> Dodałem w tym wypadku po prostu pierwszy warunek który sprawdza czy przesyłane przez <strong>$_GET</strong> lub <strong>$_POST</strong> wartości nie są tablicą, a jeżeli są to zmienna <strong>$mode</strong> staje się pusta. Jest to o tyle bezpieczna wersja poprawki, że wyklucza przekazywanie jakichkolwiek tablic w tym przypadku. Druga wersja poprawki to taka, która pozwala na przekazywanie tablic, ale filtruje je w taki sposób, aby odebrane przez skrypt były jako <strong>string</strong>.</p>
<pre class="brush: php; title: ;">if ( is_array($HTTP_POST_VARS['mode']) || is_array($HTTP_GET_VARS['mode']) )
{
	$mode = ( !empty($HTTP_POST_VARS['mode']) ) ? $HTTP_POST_VARS['mode'] : $HTTP_GET_VARS['mode'];
	$mode = htmlspecialchars($mode[0]);
}
else if ( !empty($HTTP_POST_VARS['mode']) || !empty($HTTP_GET_VARS['mode']) )
{
	$mode = ( !empty($HTTP_POST_VARS['mode']) ) ? $HTTP_POST_VARS['mode'] : $HTTP_GET_VARS['mode'];
	$mode = htmlspecialchars($mode);
}
else
{
	$mode = '';
}</pre>
<p> Adekwatnie sprawa wygląda w plikach <strong>profile.php</strong> i <strong>modcp.php</strong>, a także w <strong>privmsg.php</strong> w związku z elementem <strong>folder</strong>. Ciut inna sytuacja występuje za to w <strong>posting.php</strong>. Tam filtrowane są w pętli wszystkie niezbędne elementy tablic.</p>
<pre class="brush: php; title: ;">$params = array('submit' =&gt; 'post', 'preview' =&gt; 'preview', 'delete' =&gt; 'delete', 'poll_delete' =&gt; 'poll_delete', 'poll_add' =&gt; 'add_poll_option', 'poll_edit' =&gt; 'edit_poll_option', 'mode' =&gt; 'mode');
while( list($var, $param) = @each($params) )
{
	if ( !empty($HTTP_POST_VARS[$param]) || !empty($HTTP_GET_VARS[$param]) )
	{
		$$var = ( !empty($HTTP_POST_VARS[$param]) ) ? htmlspecialchars($HTTP_POST_VARS[$param]) : htmlspecialchars($HTTP_GET_VARS[$param]);
	}
	else
	{
		$$var = '';
	}
}</pre>
<p>Co możemy zamienić tak jak w pierwszym przypadku na:</p>
<pre class="brush: php; title: ;">//
// Check and set various parameters
//
$params = array('submit' =&gt; 'post', 'preview' =&gt; 'preview', 'delete' =&gt; 'delete', 'poll_delete' =&gt; 'poll_delete', 'poll_add' =&gt; 'add_poll_option', 'poll_edit' =&gt; 'edit_poll_option', 'mode' =&gt; 'mode');
while( list($var, $param) = @each($params) )
{
	if ( is_array($HTTP_POST_VARS[$param]) || is_array($HTTP_GET_VARS[$param]) )
	{
		$$var = '';
	}
	else if ( !empty($HTTP_POST_VARS[$param]) || !empty($HTTP_GET_VARS[$param]) )
	{
		$$var = ( !empty($HTTP_POST_VARS[$param]) ) ? htmlspecialchars($HTTP_POST_VARS[$param]) : htmlspecialchars($HTTP_GET_VARS[$param]);
	}
	else
	{
		$$var = '';
	}
}</pre>
<p> lub</p>
<pre class="brush: php; title: ;">//
// Check and set various parameters
//
$params = array('submit' =&gt; 'post', 'preview' =&gt; 'preview', 'delete' =&gt; 'delete', 'poll_delete' =&gt; 'poll_delete', 'poll_add' =&gt; 'add_poll_option', 'poll_edit' =&gt; 'edit_poll_option', 'mode' =&gt; 'mode');
while( list($var, $param) = @each($params) )
{
	if ( is_array($HTTP_POST_VARS[$param]) || is_array($HTTP_GET_VARS[$param]) )
	{
		$$var = ( !empty($HTTP_POST_VARS[$param]) ) ?  htmlspecialchars($HTTP_POST_VARS[$param][0]) :  htmlspecialchars($HTTP_GET_VARS[$param][0]);
	}
	else if ( !empty($HTTP_POST_VARS[$param]) || !empty($HTTP_GET_VARS[$param]) )
	{
		$$var = ( !empty($HTTP_POST_VARS[$param]) ) ? htmlspecialchars($HTTP_POST_VARS[$param]) : htmlspecialchars($HTTP_GET_VARS[$param]);
	}
	else
	{
		$$var = '';
	}
}</pre>
<p>Są to tylko przykłady błędów. Reasumując całą sytuację należałoby względnie tych przykładów pozmieniać filtrując w taki sposób wszelkie zmienne wejściowe (z tablic superglobalnych <strong>$_GET</strong>, <strong>$_POST</strong>) przy których jesteśmy pewni, że nie będziemy przekazywać w nich żadnych wartości tablicowych. Uchroni nas to od błędów typu:</p>
<blockquote><p>Warning: htmlspecialchars() expects parameter 1 to be string, array given in /adres/modcp.php on line 116</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://m1chu.eu/2008/03/22/ciag-dalszy-problemow-z-przekazywaniem-tablic-w-phpbb-by-przemo-1125/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Przekazywanie tablic w memberlist.php &#8211; phpBB by Przemo 1.12.5</title>
		<link>http://m1chu.eu/2007/12/24/przekazywanie-tablic-w-memberlistphp-phpbb-by-przemo-1125/</link>
		<comments>http://m1chu.eu/2007/12/24/przekazywanie-tablic-w-memberlistphp-phpbb-by-przemo-1125/#comments</comments>
		<pubDate>Mon, 24 Dec 2007 11:41:58 +0000</pubDate>
		<dc:creator>m1chu</dc:creator>
				<category><![CDATA[Bugtrack]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpBB]]></category>
		<category><![CDATA[memberlist]]></category>
		<category><![CDATA[phpbb by przemo]]></category>
		<category><![CDATA[tablice]]></category>

		<guid isPermaLink="false">http://m1chu.eu/bugtrack/przekazywanie-tablic-w-memberlistphp-phpbb-by-przemo-1125</guid>
		<description><![CDATA[Dziś napisał do mnie d3d!k z prośbą o rejestrację na pewnym forum, na którym jestem technicznym adminem. Zaproszenie otrzymał i kilka minut później przekazał mi tekst błędu występującego na nim. I tutaj zaczyna się sens mojego wpisu&#8230; Błąd jest standardowym bugiem występującym w phpBB by Przemo w wersji 1.12.5. Polega on na tym, że w [...]]]></description>
			<content:encoded><![CDATA[<p>Dziś napisał do mnie <strong>d3d!k</strong> z prośbą o rejestrację na pewnym forum, na którym jestem technicznym adminem. Zaproszenie otrzymał i kilka minut później przekazał mi tekst błędu występującego na nim. I tutaj zaczyna się sens mojego wpisu&#8230;</p>
<p><span id="more-30"></span></p>
<p>Błąd jest standardowym bugiem występującym w <strong>phpBB by Przemo</strong> w wersji <strong>1.12.5</strong>. Polega on na tym, że w wypadku przekazywania parametru <strong>mode</strong> w pliku <strong>memberlist.php</strong> w postaci tablicy otrzymujemy błąd argumentu funkcji <strong>htmlspecialchars</strong> w stylu:</p>
<pre class="brush: php; title: ;">Warning: htmlspecialchars() expects parameter 1 to be string, array given in /home/adres</pre>
<p>Dzieje się tak z prostego powodu. Funkcja powyższa w podstawowej formie przyjmuje <strong>jeden</strong> parametr, który musi być string-iem. W wypadku kiedy chcielibyśmy przekazać tablicę musielibyśmy każdy z jej elementów np. poprzez wpuszczenie w pętlę przefiltrować. Skrypt, a dokładniej jego autorzy nie przewidzieli takiej opcji.</p>
<p><strong>D3d!k</strong> dał mi też pewien rodzaj zabezpieczenia. Nie wdając się w dyskusję na temat jego formy, powiem tylko, że nie było one prawidłowe. Pozbawiało skrypt w tym elemencie jakiegokolwiek zabezpieczenia.</p>
<p>Moja propozycja jest następująca. A mianowicie, należy znaleźć w pliku <strong>memberlist.php</strong>:</p>
<pre class="brush: php; title: ;">if ( isset($HTTP_GET_VARS['mode']) || isset($HTTP_POST_VARS['mode']) )
{
	$mode = ( isset($HTTP_POST_VARS['mode']) ) ? htmlspecialchars($HTTP_POST_VARS['mode']) : htmlspecialchars($HTTP_GET_VARS['mode']);
}
else
{
	$mode = 'joined';
}</pre>
<p>Po czym zamienić na:</p>
<pre class="brush: php; title: ;">if ( (isset($HTTP_GET_VARS['mode']) || isset($HTTP_POST_VARS['mode'])) &amp;&amp; ( is_array($HTTP_POST_VARS['mode']) || is_array($HTTP_GET_VARS['mode']) ) )
{
	$mode = 'joined';
}
else if ( isset($HTTP_GET_VARS['mode']) || isset($HTTP_POST_VARS['mode']) )
{
	$mode = ( isset($HTTP_POST_VARS['mode']) ) ? htmlspecialchars($HTTP_POST_VARS['mode']) : htmlspecialchars($HTTP_GET_VARS['mode']);
}
else
{
	$mode = 'joined';
}</pre>
<p>Doszedł jak widać jeden warunek. Sprawdza on czy został ustawiony parametr <strong>mode</strong> jednej z tablic superglobalnych <strong>$_POST</strong> lub <strong>$_GET</strong> po czym dodatkowo sprawdza czy którakolwiek z nich jest tablicą. Jeśli tak to ustawia <strong>$mode</strong> na standardową opcję. Jeśli nie, tzn. że przekazywana nie jest tablica i dalej sprawdza już wg. starej instrukcji.</p>
<p>Podziękowania dla <strong>d3d!ka</strong> za ukazanie błędu.</p>
<p>Także z tego miejsca chciałbym Wam życzyć Wesołych Świąt, hucznego Sylwestra, a także pomyślności w nowym &#8211; już <strong>2008</strong> roku. A powyżej macie drobny prezent.</p>
]]></content:encoded>
			<wfw:commentRss>http://m1chu.eu/2007/12/24/przekazywanie-tablic-w-memberlistphp-phpbb-by-przemo-1125/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>bbGeSHi &#8211; A better syntax highlighter 0.7.5</title>
		<link>http://m1chu.eu/2007/09/30/bbgeshi-a-better-syntax-highlighter-075/</link>
		<comments>http://m1chu.eu/2007/09/30/bbgeshi-a-better-syntax-highlighter-075/#comments</comments>
		<pubDate>Sun, 30 Sep 2007 18:44:25 +0000</pubDate>
		<dc:creator>m1chu</dc:creator>
				<category><![CDATA[Bugtrack]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpBB]]></category>
		<category><![CDATA[bbgeshi]]></category>
		<category><![CDATA[modyfikacja]]></category>
		<category><![CDATA[phpbb3]]></category>

		<guid isPermaLink="false">http://m1chu.eu/informatyka/bugtrack/bbgeshi-a-better-syntax-highlighter-075/</guid>
		<description><![CDATA[Kolejny mod do nowej wersji phpBB3 w którym zauważyłem drażniący błąd. I pomimo, że i skrypt i modyfikacje do niego są w wersji rozwojowej to zbędne parsowanie (co najważniejsze tylko niektórych) tagów bbcode w znaczniku code było dla mnie nazbyt uciążliwe i coś było trzeba z tym zrobić. Dla uwidocznienia problemu przedstawiam screena: W wypadku [...]]]></description>
			<content:encoded><![CDATA[<p>Kolejny mod do nowej wersji phpBB3 w którym zauważyłem drażniący błąd. I pomimo, że i skrypt i modyfikacje do niego są w wersji rozwojowej to zbędne parsowanie (co najważniejsze tylko niektórych) tagów bbcode w znaczniku <strong>code</strong> było dla mnie nazbyt uciążliwe i coś było trzeba z tym zrobić.</p>
<p><span id="more-20"></span></p>
<p>Dla uwidocznienia problemu przedstawiam screena:</p>
<p style="text-align: center;"><img src="http://farm4.static.flickr.com/3026/2842486593_52beae99e5.jpg" alt="bbGesHi 0.7.5 - bug parsowania" style="width: 500px; height: 200px;" /></p>
<p>W wypadku znacznika <strong>code</strong> jego zawartość nie powinna być parsowana. Nie mniej jednak autor skryptu bez względu na typ zastosowanego tagu parsuje jego zawartość metodami wbudowanymi w silnik GeSHi. Ominąć ten problem można na wiele sposobów, np. poprzez użycie funkcji <strong>str_replace</strong> w celu wydzielenia poszczególnych znaków na encje html lub po prostu zastosowanie jakieś wbudowanej funkcji. Osobiście przedstawię drugą wersję.</p>
<p>Przede wszystkim w momencie inicjalizacji klasy obsługującej silnik GeSHi przekazując w parametrze zmienną (<strong>$code</strong>) zawierającą zawartość znacznika należy przekonwertować znaki bbcode na encję html. Adekwatnie znajdujemy:</p>
<pre class="brush: php; title: ;">	function bbcode_highlight($code, $stx)
{
[...]
}</pre>
<p>W celu konwersji możemy posłużyć się metodą <strong>bbcode_specialchars</strong> której jedynym parametrem jest zmienna tekstowa. Należy wyszukać:</p>
<pre class="brush: php; title: ;">		$geshi = new GeSHi($code, $stx);</pre>
<p>I zamienić np. na:</p>
<pre class="brush: php; title: ;">		$geshi = new GeSHi((( $stx == 'text' ) ? $this-&gt;bbcode_specialchars($code) : $code), $stx);</pre>
<p>To niestety nie koniec. Przy parsowaniu GeSHi należy także rozróżnić, czy parsowany będzie znacznik <strong>code</strong>, czy inny. W wypadku tego pierwszego po sparsowaniu musi nastąpić konwersja zwrotna z encji na znaki. Nie można po prostu ominąć parsowania GeSHi, co też mogłoby rozwiązać problem z np. wyświetlaniem grafik w znaczniku <strong>code</strong> z tego powodu, że albo otrzymamy w wyniku encje html, albo opcja numerowania i ukrywania nie będzie działać.</p>
<p>Tak więc należy tym razem znaleźć:</p>
<pre class="brush: php; title: ;">		$result = $geshi-&gt;parse_code());</pre>
<p>I zamienić np. na:</p>
<pre class="brush: php; title: ;">		$result = (( $stx == 'text' ) ? htmlspecialchars_decode($geshi-&gt;parse_code(), ENT_NOQUOTES) : $geshi-&gt;parse_code());</pre>
<p>W celu zachowania bezpieczeństwa należało by także w powyższym przykładzie utworzyć tablicę z dozwolonymi znacznikami do konwersji zwrotnej. W tym wypadku bardziej odpowiednią metodą (bezpieczniejszą) byłoby użycie pierwszej metody z wymienionych wcześniej.<br />
Może się zdarzyć, że niektóre gotowe posty będą wyświetlały nie kod, a wynik parsowania &#8211; należy je w takim wypadku zedytować i zapisać znowu.</p>
<p>PS. sposób ten będzie działał na wersji php5 równej lub większej niż 5.1. W starszych wersjach można użyć wspomnianego już <strong>str_replace</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://m1chu.eu/2007/09/30/bbgeshi-a-better-syntax-highlighter-075/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Raz-Captcha (WordPress anti-spambot plugin)</title>
		<link>http://m1chu.eu/2007/09/26/raz-captcha-wordpress-anti-spambot-plugin/</link>
		<comments>http://m1chu.eu/2007/09/26/raz-captcha-wordpress-anti-spambot-plugin/#comments</comments>
		<pubDate>Wed, 26 Sep 2007 19:07:46 +0000</pubDate>
		<dc:creator>m1chu</dc:creator>
				<category><![CDATA[Bugtrack]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[anti-spambot]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[raz-captcha]]></category>
		<category><![CDATA[token]]></category>

		<guid isPermaLink="false">http://m1chu.eu/informatyka/bugtrack/raz-captcha-wordpress-anti-spambot-plugin/</guid>
		<description><![CDATA[Kilka dni temu zauważyłem (co chyba na tego typu skryptach nie jest niczym niesamowitym) pełną ofensywę botów na stronie w postaci ich rejestracji. Z braku czasu dopiero dziś udało mi się wprowadzić kilka udoskonaleń które mam nadzieję, że pomogą w pozbyciu się zbędnych robotów. Oczywiście z wyżej podanego powodu wprowadziłem gotowe rozwiązania, a mianowicie m.in. [...]]]></description>
			<content:encoded><![CDATA[<p>Kilka dni temu zauważyłem (co chyba na tego typu skryptach nie jest niczym niesamowitym) pełną ofensywę botów na stronie w postaci ich rejestracji. Z braku czasu dopiero dziś udało mi się wprowadzić kilka udoskonaleń które mam nadzieję, że pomogą w pozbyciu się zbędnych robotów.</p>
<p><span id="more-19"></span></p>
<p>Oczywiście z wyżej podanego powodu wprowadziłem gotowe rozwiązania, a mianowicie m.in. <a href="http://raz-soft.com/display-english-posts-only/wordpress-plugin-login-register-anti-spambots-captcha/" title="Raz-Captcha" onclick="this.target='_blank'" >Raz-Captcha</a>. Część osób miało problem z systemem weryfikacji graficznej, które autor modyfikacji w dziwny sposób tłumaczył zerowaniem elementu <em>$_SESSION</em> odpowiedzialnego za przekazanie zahashowanej wartości wygenerowanego tokena, a druga część twierdziła, że mod działa (jakim sposobem nie wiem). Miałem podobny problem jak ta pierwsza grupa i dlatego postanowiłem przyjrzeć się problemowi ciut dokładniej.</p>
<p>Zakładam z góry, że nie jest to wina WordPressa, czy zastosowanego stylu. Nie widzę powodu aby tak twierdzić, tym bardziej że z samego kodu który zanalizowałem wynika, że bug jest uzasadniony i dotyczy opcji silnika captcha dla <strong>PNG-phpBB3 8bit Grey</strong> i <strong>PNG-phpBB3 Advanced</strong>. I pomimo, że pomyłka jest naprawdę znikoma w sensie objętości to przysparza ona wielu problemów. W czym tkwi błąd?</p>
<p>Pozwolicie, że zanalizuje go na opcji <strong>PNG-phpBB3 8bit Grey</strong>, gdyż problem z drugim silnikiem jest adekwatny do tego, dotyczy tylko następnego warunku (<em>else if</em>) w pliku który zaraz omówię. Na początek należy otworzyć <strong>raz-captcha.php</strong> i około linijki <em>193</em> znaleźć:</p>
<pre class="brush: php; title: ;">else if ($option['rca_engine'] ==3) // phpBB3 no-gd bw png engine
{
	require_once(&quot;engines/phpbb-nogd.php&quot;);
	$captcha = new captcha();
	$password=gen_rand_string(mt_rand(5, 8));
	$captcha-&gt;execute($password, time());
	$_SESSION['raz_captcha_gen']=md5($password);
	exit();
}</pre>
<p>Kod ten odpowiada za inicjalizację funkcji, metod i przypisywanie zmiennych odpowiedzialnych za końcowe wyświetlenie tokena w opcji którą opisuję. I tutaj pojawia się błąd. Domyślnie autor modyfikacji najpierw odwołuje się do metody <em>execute</em>, a dopiero później przypisuje do danej sesji zahashowany wygenerowany token (dokładniej jego znaki).</p>
<pre class="brush: php; title: ;">$captcha-&gt;execute($password, time());
$_SESSION['raz_captcha_gen']=md5($password);</pre>
<p>Jeśli otworzymy teraz plik <strong>phpbb-nogd.php</strong> to około linijki <em>134</em> możemy zobaczyć, że po wykonaniu metody <strong>execute</strong> tej klasy i po wyświetleniu wyniku następuje brutalne zatrzymanie skryptu i wszystko co ma dziać się dalej np. w pliku <strong>raz-captcha.php</strong> zostaje przerwane.</p>
<pre class="brush: php; title: ;">	header('Content-Type: image/png');
	header('Cache-control: no-cache, no-store');
	echo $image;
	exit;
}</pre>
<p>I tu jest nasz bug. W pliku który otwieraliśmy na początku wystarczy zamienić linijkami wywołanie metody z przypisaniem do sesji naszego ciągu znaków, tak aby cały warunek wyglądał tak:</p>
<pre class="brush: php; title: ;">else if ($option['rca_engine'] ==3) // phpBB3 no-gd bw png engine
{
	require_once(&quot;engines/phpbb-nogd.php&quot;);
	$captcha = new captcha();
	$password=gen_rand_string(mt_rand(5, 8));
	$_SESSION['raz_captcha_gen']=md5($password);
	$captcha-&gt;execute($password, time());
	exit();
}</pre>
<p>Nasz problem powinien zniknąć. Adekwatnie na poniższym warunku możemy też poprawić błąd programisty.</p>
<pre class="brush: php; title: ;">else if ($option['rca_engine'] ==4) // phpBB3 Advanced
{ </pre>
<p>Zaznaczam, że problem testowany był na WordPressie w wersji 2.2.3.</p>
]]></content:encoded>
			<wfw:commentRss>http://m1chu.eu/2007/09/26/raz-captcha-wordpress-anti-spambot-plugin/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Edycja wpisów w ShoutBox &#8211; phpBB by Przemo</title>
		<link>http://m1chu.eu/2007/09/07/edycja-wpisow-w-shoutbox-phpbb-by-przemo/</link>
		<comments>http://m1chu.eu/2007/09/07/edycja-wpisow-w-shoutbox-phpbb-by-przemo/#comments</comments>
		<pubDate>Thu, 06 Sep 2007 22:29:15 +0000</pubDate>
		<dc:creator>m1chu</dc:creator>
				<category><![CDATA[Bugtrack]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpBB]]></category>
		<category><![CDATA[cgi]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[phpbb by przemo]]></category>
		<category><![CDATA[shoutbox]]></category>
		<category><![CDATA[zlib]]></category>

		<guid isPermaLink="false">http://m1chu.eu/informatyka/bugtrack/edycja-wpisow-w-shoutbox-phpbb-by-przemo/</guid>
		<description><![CDATA[Pierwszy wpis w tej kategorii. Pierwszy opisywany przeze mnie bug. Przyznaję, nie jest on żadnych wysokich lotów &#8211; nie mniej jednak tak jak zawsze z tego typu lub cięższymi sprawami dzieliłem się bezpośrednio z danymi osobami, tak teraz postanowiłem je pisać. Może dlatego, że mam gdzie. Sprawa jest na tyle nieskomplikowana, że dłużej dociekałem przyczyny, [...]]]></description>
			<content:encoded><![CDATA[<p>Pierwszy wpis w tej kategorii. Pierwszy opisywany przeze mnie bug. Przyznaję, nie jest on żadnych wysokich lotów &#8211; nie mniej jednak tak jak zawsze z tego typu lub cięższymi sprawami dzieliłem się bezpośrednio z danymi osobami, tak teraz postanowiłem je pisać. Może dlatego, że mam gdzie.</p>
<p>Sprawa jest na tyle nieskomplikowana, że dłużej dociekałem przyczyny, niż ją naprawiałem. Błąd wykryłem przypadkiem, dzięki użytkownikom mojego forum. Wiem, że znany był on wcześniej, a nawet niektórzy próbowali go naprawiać, ale jednoznacznego rozwiązania nie widziałem nigdzie. Na czym polega bug? <strong>Na tym, że w przypadku jeśli <a href="http://pl.wikipedia.org/wiki/PHP"  onclick="this.target='_blank'" title="PHP">PHP</a> wspomagane jest obsługą <a href="http://pl.wikipedia.org/wiki/CGI"  onclick="this.target='_blank'" title="CGI">CGI</a> z wyłączonym <strong>zlib.output_compression</strong> w czasie edycji wpisów w shoutboxie jest wysyłany tekst przed wysłaniem nagłówków powodujący błąd skryptu</strong>. Problem ten dotyczy wersji <em>1.12.5</em>, z tego co wiem podobne problemy były zauważane w wersjach <em>1.9.x</em>.</p>
<p><span id="more-16"></span></p>
<p>Jak wygląda to od strony technicznej? W <a href="http://przemo.org"  onclick="this.target='_blank'" title="phpBB by Przemo">phpBB by Przemo</a> takie akcje jak edycja, czy usuwanie wpisów z <a href="http://pl.wikipedia.org/wiki/Shoutbox"  onclick="this.target='_blank'" title="Shoutbox">shoutboxa</a> są wykonywane w pliku <strong>shoutbox_view.php</strong>. W momencie kiedy w Panelu Administracyjnym ustawimy, aby skrypt korzystał z kompresji <a href="http://pl.wikipedia.org/wiki/Gzip"  onclick="this.target='_blank'" title="gzip">gzip</a> w pliku w zależności od typu przeglądarki ustawiane jest standardowe buforowanie wyjścia, wysyłany nagłówek szyfrowania treści strony, wyliczana suma kontrolnej i w końcu kompresowanie lub po prostu ustawienie buforowania wyjścia z atrybutem kompresji gzipa.</p>
<pre class="brush: php; title: ;">// Gecko
@ob_start('ob_gzhandler');</pre>
<pre class="brush: php; title: ;">// Opera
$do_gzip_compress = TRUE;
@ob_start();
@ob_implicit_flush(0);

@header('Content-Encoding: gzip');</pre>
<pre class="brush: php; title: ;">$gzip_contents = @ob_get_contents();
@ob_end_clean();

$gzip_size = strlen($gzip_contents);
$gzip_crc = @crc32($gzip_contents);

$gzip_contents = @gzcompress($gzip_contents, 9);
$gzip_contents = substr($gzip_contents, 0, strlen($gzip_contents) - 4);

echo &quot;x1fx8bx08x00x00x00x00x00&quot;;
echo $gzip_contents;
echo pack('V', $gzip_crc);
echo pack('V', $gzip_size);</pre>
<p>W tym drugim przypadku <strong>dotyczącym przeglądarek opartych na silniku Gecko</strong> każda próba edycji jakiegokolwiek wpisu kończy się wyświetleniem białej strony, w przypadku pierwszym <strong> dotyczącym Opery</strong> edycja jest możliwa, ale zamiast listowania wiadomości otrzymujemy ciąg skompresowanych danych, w postaci różnorodnych znaków. Co najdziwniejsze przynajmniej na Internet Explorerze w wersji siódmej wszystko działa dobrze ;]</p>
<p>Jak już napisałem prawie na początku problem stwarza fakt, że przy podanej wcześniej przeze mnie konfiguracji parsera PHP wysyłanie tekstu przed wysłaniem nagłówków powoduje automatyczne zatrzymanie i zerowanie zawartości sparsowanego pliku. Jeśli posiadamy własny serwer lub po prostu mamy możliwość konfiguracji naszego konta np. poprzez zmianę php.ini sprawa jest stosunkowo prosta. Możemy dla przykładu ustawić <strong>zlib.output_compression</strong> i <strong>zlib.output_compression_level</strong> na <strong>1</strong>. Na przykład poprzez użycie PHP w wersji co najmniej <em>4.3</em>:</p>
<pre class="brush: php; title: ;">ini_set('zlib.output_compression', true);
ini_set('zlib.output_compression_level', '1');</pre>
<p>Natomiast jeśli nie mamy takich możliwości konfiguracyjnych wystarczy, że znajdziemy poniższy kod.</p>
<pre class="brush: php; title: ;">$do_gzip_compress = FALSE;
if ( $board_config['gzip_compress'] &amp;&amp; !@headers_sent() )
{
	$phpver = phpversion();
	$useragent = (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT'])) ? $HTTP_SERVER_VARS['HTTP_USER_AGENT'] : getenv('HTTP_USER_AGENT');
	$is_ob_gzhandler_started = false;
	if ( @ini_get('zlib.output_compression') &amp;&amp; (int)@ini_get('zlib.output_compression') != 0 &amp;&amp; strtolower(@ini_get('zlib.output_compression')) != 'off' )
	{
		$is_ob_gzhandler_started = true;
	}
	else if ( @ini_get('output_handler') &amp;&amp; strtolower(@ini_get('output_handler'))=='ob_gzhandler' )
	{
		$is_ob_gzhandler_started = true;
	}
	if ( $phpver&gt;= '4.0.4pl1' &amp;&amp; ( strstr($useragent,'compatible') || strstr($useragent,'Gecko') ) )
	{
		if ( extension_loaded('zlib') &amp;&amp; !$is_ob_gzhandler_started )
		{
			@ob_start('ob_gzhandler');
		}
	}
	else if ( $phpver&gt; '4.0' )
	{
		if ( strstr($HTTP_SERVER_VARS['HTTP_ACCEPT_ENCODING'], 'gzip') )
		{
			if ( extension_loaded('zlib') &amp;&amp; !$is_ob_gzhandler_started )
			{
				$do_gzip_compress = TRUE;
				@ob_start();
				@ob_implicit_flush(0);
				@header('Content-Encoding: gzip');
			}
		}
	}
}</pre>
<p>I przeniesiemy go powyżej następującego kodu.</p>
<pre class="brush: php; title: ;">// ShoutBox auth
$is_jr_admin = ($userdata['user_jr']) ? true : false;
$is_mod = ($userdata['user_level'] == MOD) ? true : false;</pre>
<p>W takim wypadku niezbędne do kompresji gzip nagłówki zostaną wysłane przed wyświetleniem tekstu i wszelkie związane z tą przypadłością błędy zostaną zaniechane.</p>
]]></content:encoded>
			<wfw:commentRss>http://m1chu.eu/2007/09/07/edycja-wpisow-w-shoutbox-phpbb-by-przemo/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

