The Daily WTF, part 3

No nie mogę. Ex aequo dzisiejszą nagrodę otrzymuje również zespół dinfo.pl. Jako ich partner, jesteśmy zmuszeni do korzystania z ich API do wykonywania wszelkich operacji na domenach. Właśnie wpisałem o-umlaut do formularza wyszukiwania domen i system zmarł z komunikatem zły assert. Szukałem błędu po swojej stronie, ale ich serwis okazywał się reagować tak samo. Zajrzałem przeto w otchłań bezdenną i wydobyłem z jej czeluści kod ichniej implementacji punycode, czyli systemu tłumaczenia nazw domen na obowiązujący standard IDN:

function punycode($tryb,$tekst)
{ //tryby: "Encode"/"Decode"
	$iso = array(177,230,234,179,241,243,182,188,191,
	161,198,202,163,209,211,166,172,175);

	$uni = array(261,263,281,322,324,243,347,378,380,260,
	262,280,321,323,211,346,377,379);

	$tekst = iconv('utf-8', 'iso-8859-2', $tekst);

	$print_ascii ="\n\n\n\n\n\n\n\n\n\n\n\n\n\n".
	"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n !\"".
	"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJK".
	"LMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrs"
	"tuvwxyz{|}~\n";

	$domenatab=explode(".",$tekst);
	//podzial domeny na tablice(rozdzial z kropek)

	if ($tryb=="Encode") {
		$output="";
		for ($l=0;$l<count($domenatab);$l++){
		//licznik slow miedzy kropkami
			$tekstuni=array();
			$tekst=$domenatab[$l];
			$polskieznaczki=false;
			for ($i=0;$i<strlen($tekst);$i++) {
				$znaleziony=0;
				for ($j=0;$j<count($iso);$j++) {
					if (ord($tekst[$i])==$iso[$j])  {
						$tekstuni[$i]=$uni[$j];
						$znaleziony=1;
						$polskieznaczki=true;
						break;
					}
				}
				if ($znaleziony==0) {
					$tekstuni[$i]=ord($tekst[$i]);
				}
			}

			// Encode: //
			if ($polskieznaczki==true) {
				$output .= "xn--".
				$this->punycode_encode(count($tekstuni), $tekstuni);
			} else {
				$output.=$domenatab[$l];
			}
			if ($l!=count($domenatab)-1) {
				$output.=".";
			}
		} //for l=0....
		$output_length=strlen($output);

		// Convert to native charset and output: //
		for ($j = 0;  $j < $output_length;  ++$j) {
			$c = ord($output[$j]);
			if ($c >= 0 && $c <= 127 && isset($c)) {
				if (ord($print_ascii[$c]) == 0) {
					echo "invalid_input";
				}
				$output[$j] = $print_ascii[$c];
			} else {
				echo "zly assert (246)";
				exit;
			}
		}
		return str_replace("\r","",$output);
	}
	// [..]
}

Przejrzyściej napisanego kodu nie napisałem, mimo wszystko udało mi się dostrzec, że:

  • system potrafi obsługiwać tylko domeny podane w Latin2
  • ma na sztywno wpisanych kilka polskich znaków (pierwsze dwie tablice), a inne skrupulatnie olewa
  • nie ma nic wspólnego z oryginalnym algorytmem punycode (tej części nie wklejałem), którego implementację w PHP na licencji GPL można wygooglać w 10 sekund
  • prześlicznie obsługuje błędy, nie ma to jak zabić skrypt w przypadku wprowadzenia nieobsługiwanych znaków do formularza

7 » odpowiedzi dla wpisu “The Daily WTF, part 3”


  1. 1 nbw

    Wspaniałe!

    Do mnie natomiast niedawno przyszedł "wspaniały, nieoceniony, bezpieczny, szybki, rozszerzalny" CMS klienckiego maga podpisującego się jako IT Specialist.

    System zmarł jak tylko odpaliłem go u siebie. Okazało się, że system nie działa bez register_globals i magic_quotes.

  2. 2 DarkStar blog.krakowiacy.info

    Patrys… czy wklejając ten kod nie złamałeś właśnie prawa? ;] To chyba nie jest Open Source (tzn. nie był ;P)?

  3. 3 Patrys

    System jest dostępny za darmo i nie ma zastrzeżeń odnośnie dystrybucji, więc nie widzę problemu. Poza tym wkleiłem tylko fragment kodu, który raz że nie zdradza żadnej tajemnicy, bo służy do generowania punycode, a dwa, że jest do niczego.

  4. 4 Enleth

    1) Jak autor tego czegoś się znalazł tam gdzie pracuje?

    2) Jak go tam można zastąpić? ;)

  5. 5 listek

    Enleth: szybko ;)

    Patrys podał nazwę firmy więc możesz spróbować… Mnie by pewnie nie chcieli ze względu na wiek :D

  6. 6 Jezuch

    Widziałem coś podobnego w swojej poprzedniej robocie. Dłubaliśmy tam w ASP na IIS5, które to jakoś niechętnie się obchodzą z kodowaniem innym niż US-ASCII, więc jeden sprytny kolega przerabiał kodowania "po swojemu"… [po jakichś dwóch latach w końcu się dogrzebałem, że *da* się to zrobić normalnie, ale było to mocno nieintuicyjne - ktoś zna numery stron kodowych UTF-8, np?. :)]

  7. 7 Jam Łasica RF

    Ja też znalazłem mały WTF

    int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) {

Skomentuj wpis