Утренний разнос GPC.

WP

^_^
Утренний разнос GPC.

Такая вроде бы простая вещь как прием данных GPC (Get-Post-Cookie) при рассмотрении оказывается не такой простой.
Я считаю что magic_quotes_*, register_globals это зло, и что любой нормальный человек посторается их выключить или иным способом избавиться. Но к сожалению доступ к настройкам есть не везде, а нужно добиться максимальной портируемости - поэтому нужно обращать действие magic_quotes_* уже в скрипте. А также стоит напомнить о %uXXXX (это разновидность urlencode): ее использует javascript и воизбежание проблем нужно обрабатывать такие последовательности в скрипте. Если воспользоваться лежащим на поверхности решением пройдясь по массивам $_GET/$_POST/$_COOKIE - появится такая проблема: если отправить %25u1234 то PHP преобразует это в %u1234, а наш скрипт декодирует, в результате запрос будет неправильно обработан. Поэтому нужно обрабатывать QUERY_STRING для GET. А POST-данные из - HTTP_RAW_POST_DATA.
HTTP_RAW_POST_DATA доступна не всегда, поэтому ее можно опустить и при обычных запросах (не от спец. библеотеки JS) не обрабатывать %uXXXX.
В результате:
PHP:
function unicode_urldecode_callback($m)
{
 $dec = hexdec($m[1]);
 $utf = '';
 if ($dec < 0xFF) {$utf = chr($dec);}
 elseif ($dec < 2048)
 {
  $utf = chr(192 + (($dec - ($dec % 64)) / 64));
  $utf .= chr(128 + ($dec % 64));
 }
 else
 {
  $utf = chr(224 + (($dec - ($dec % 4096)) / 4096)).
		 chr(128 + ((($dec % 4096) - ($dec % 64)) / 64)).
		 chr(128 + ($dec % 64));
 }
 return $utf;
}
function unicode_urldecode_mixed($mixed)
{
 if (is_array($mixed)) {return array_map('unicode_urldecode_mixed',$mixed);}
 return preg_replace_callback('~%u([a-f\d]{4})~i','unicode_urldecode_callback',$mixed);
}

function _gpc_decode(&$var,$u = FALSE)
{
 if (is_array($var))
 {
  foreach ($var as $k => $v)
  {
   _gpc_decode($var[$k],$u);
   $nk = $u?unicode_urldecode_mixed($k):$k;
   if (get_magic_quotes_gpc())
   {
    $nk = stripslashes($nk);
    if ($nk != $k) {$var[$nk] = $var[$k]; unset($var[$k]);}
   }
  } 
 }
 else
 {
  if ($u) {$var = unicode_urldecode_mixed($var);}
  if (get_magic_quotes_gpc()) {$var = stripslashes($var);}
 }
}
function _parse_str($string,&$array)
{
 $string = preg_replace('~%(?!5B)(?!5D)([a-f\d]{2})~si','%u00$1',$string);
 parse_str($string,$array);
}
_parse_str($_SERVER['QUERY_STRING'],$_GET);
if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {_parse_str($GLOBALS['HTTP_RAW_POST_DATA'],$_POST);}
_gpc_decode($_GET,TRUE);
_gpc_decode($_POST,isset($GLOBALS['HTTP_RAW_POST_DATA']));
_gpc_decode($_COOKIE);
if (get_magic_quotes_gpc())
{
 if (isset($_SERVER['PHP_AUTH_USER'])) {$_SERVER['PHP_AUTH_USER'] = stripslashes($_SERVER['PHP_AUTH_USER']);}
 if (isset($_SERVER['PHP_AUTH_PW']))   {$_SERVER['PHP_AUTH_PW']   = stripslashes($_SERVER['PHP_AUTH_PW']);}
}
$_REQUEST = $_GET + $_POST + $_COOKIE;
Это нужно использовать всегда. Реализации встроенные в серверные части AJAX следует закомментировать.

Принимаются замечания/дополнения. Спасибо за внимание.

-~{}~ 18.12.06 08:24:

З.Ы. надеюсь с выходом PHP 6 код полностью потеряет актуальность: magic_quotes уже убрали, осталось лишь добавить поддержку %uXXXX.
 

Андрейка

Senior pomidor developer
однозначно не хватает такого куска
PHP:
if (function_exists('apache_request_headers')===true) {
  $headers = apache_request_headers();
  $cookies= !empty($headers['Cookie'])?explode('; ',$headers['Cookie']):array();
  $_COOKIE = array();
  foreach($cookies as $cookie) {
     _parse_str($cookie, $cookieVars);
     foreach($cookieVars as $cookieName=>$cookieVar) {
             if (!empty($_COOKIE[$cookieName]) && is_array($_COOKIE[$cookieName]) && is_array($cookieVar)) {
                $_COOKIE[$cookieName][key($cookieVar)] = current($cookieVar);
             } else {
                $_COOKIE[$cookieName] = $cookieVar;
             }
     }

  }
}
ЗЫ. так и знал, что рефомы в сфере здравохранения до добра не доведут...
 

WP

^_^
Андрейка
А нафига этот кусок кода? Кукам достаточно stripslashes() сделать Imho.
> ЗЫ. так и знал, что рефомы в сфере здравохранения до добра не доведут...
Да =( Некоторые сильно рискуют быть найденными на помойке с головой в заднице.
 

WP

^_^
Андрейка
Тебе когда-нибудь JavaScript присылал куку с %uXXXX?
 

WP

^_^
Андрейка
Где траву берешь?

// Блин, всю тему загадили.
 

Андрейка

Senior pomidor developer
WP
дык ты объяснил бы лучше почему эта хрень может попасть в POST, но не в кукисы?
 
Сверху