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