Страница 1 из 1

[PHP] вырезать все бинарные (не-UTF8 и не ASCI) символы

Добавлено: 2011-10-19 7:55:45
Alex Keda
собсно, изобретаю костыль.
есть парсер xml, функция начинается так:

Код: Выделить всё

function String_Xml_Parse($String,$IsUseCache = TRUE){
  #-----------------------------------------------------------------------------
  $Length = Mb_StrLen($String);
  #-----------------------------------------------------------------------------
  $IsUseCache = ($IsUseCache && $Length > 1024);
  #-----------------------------------------------------------------------------
  if($IsUseCache){
    #---------------------------------------------------------------------------
    $CacheID = SPrintF('String_XML_Parse[%s]',Md5(Crc32($String)));
    #---------------------------------------------------------------------------
    $Result = MemoryCache_Get($CacheID);
    if(!Is_Error($Result))
      return $Result;
  }
  #-----------------------------------------------------------------------------
  Debug(SPrintF('[String_XML_Parse]: парсирование строки (%u bytes)',$Length));
  #-----------------------------------------------------------------------------
  $XmlParser = Xml_Parser_Create('UTF-8');
  #-----------------------------------------------------------------------------
  if(!Xml_Parser_Set_Option($XmlParser,XML_OPTION_CASE_FOLDING,FALSE))
    return ERROR | Trigger_Error('[String_Xml_Parse]: не удалось установить опцию парсирования (XML_OPTION_CASE_FOLDING)');
  #-----------------------------------------------------------------------------
  if(!Xml_Parser_Set_Option($XmlParser,XML_OPTION_SKIP_WHITE,FALSE))
    return ERROR | Trigger_Error('[String_Xml_Parse]: не удалось установить опцию парсирования (XML_OPTION_SKIP_WHITE)');
  #-----------------------------------------------------------------------------
  if(!Xml_Parse_Into_Struct($XmlParser,$String,$Nodes)){
    #---------------------------------------------------------------------------
    $ByteIndex = Xml_Get_Current_Byte_Index($XmlParser);
    #---------------------------------------------------------------------------
    Debug(Mb_SubStr($String,$ByteIndex-100,$ByteIndex+100));
    #---------------------------------------------------------------------------
    $Buffer = Mb_SubStr($String,0,$ByteIndex);
    #---------------------------------------------------------------------------
    $Line = Preg_Match_All("/(\r\n|\n)/sU",$Buffer,$Matches) + 1;
    #---------------------------------------------------------------------------
    return new gException('XML_PARSE_ERROR',SPrintF('%s в линии %u',Xml_Error_String($XmlParser),$Line));
  }
  #-----------------------------------------------------------------------------
  Xml_Parser_Free($XmlParser);
....................
юзеры любят пихать в подписи, поля паролей, тикеты и прочие текстовые поля - всякий бинарный мусор.
я e; не знаю откуда они его берут, но [классический секс]...

соответственно, вышеприведённый кусок кода срубается на строке парсирования, возвращая ошибку:

Код: Выделить всё

return new gException('XML_PARSE_ERROR',SPrintF('%s в линии %u',Xml_Error_String($XmlParser),$Line));
тексты, на которых оно срубается, выглядят так:

Код: Выделить всё

отчёт с http://host-tracker.com/check_res_ajx/8924189-0/
Полученные результаты: 56 Ошибка(ок) 	Average: 	- 	- 	 
Bangkok, Thailand 	Failure("Domain lookup failure:www. \00191 \00181?X? 8 \00190 8- \00181 9 \00190? 8.? 8?Z Exception:Not_found") 	  	  	  	  	Chaiyo Hosting
Los Angeles, CA, US 	Failure("Domain lookup failure:www. \00191 \00181?X? 8 \00190 8- \00181 9 \00190? 8.? 8?Z Exception:Not_found") 	  	  	  	  	West Cost Hosting
Kiev, Ukraine 	Failure("Domain lookup failure:www. \00191 \00181?X? 8 \00190 8- \00181 9 \00190? 8.? 8?Z Exception:Not_found") 	  	  	  	  	ITQua
как бы вырезать из текста весь мусор? оставить только текст, собстно...

Re: [PHP] вырезать все бинарные (не-UTF8 и не ASCI) символы

Добавлено: 2011-10-19 7:57:00
Alex Keda
да, текст тут в форуме отображается не совсем так как у меня в блокнотике сохранено...
сдаётся мне, тут это уже реализовали как-то...

Re: [PHP] вырезать все бинарные (не-UTF8 и не ASCI) символы

Добавлено: 2011-10-19 8:00:09
Alex Keda
ну и собсно выхлоп:

Код: Выделить всё

[07:33:18.53][19706] [String_XML_Parse]: парсирование строки (1475 bytes)
[07:33:18.54][19706]  ^O9 \00190? 8.? 8?Z Exception:Not_found")                                         Chaiyo Hosting<BR />Los Angeles, CA, US         Failure("Domain lookup failure:www. \00191 \00181?X? 8 \00190 ^O8- \00181 ^O9 \00190? 8.? 8?Z Exception:Not_found")                                     West Cost Hosting<BR />Kiev, Ukraine    Failure("Domain lookup failure:www. \00191 \00181?X? 8 \00190 ^O8- \00181 ^O9 \00190? 8.? 8?Z Exception:Not_found")                                     ITQua</SPAN>
   <HR />
   <PRE style="font-size:10px;">C уважением, Егор.</PRE>
  </TD>
 </TR>
</NOBODY>
[07:33:18.54][19706] [Exception]: [XML_PARSE_ERROR]=(Unknown в линии 18)

Re: [PHP] вырезать все бинарные (не-UTF8 и не ASCI) символы

Добавлено: 2011-10-22 6:35:30
zg
Alex Keda писал(а):function String_Xml_Parse
странная какая-то функция... зачем она?
Alex Keda писал(а):return new gException('XML_PARSE_ERROR',SPrintF('%s в линии %u',Xml_Error_String($XmlParser),$Line));
эммм... первый раз вижу чтоб эксепшин возвращали, а не кидали

Re: [PHP] вырезать все бинарные (не-UTF8 и не ASCI) символы

Добавлено: 2011-10-24 9:30:54
Alex Keda
zg писал(а):
Alex Keda писал(а):function String_Xml_Parse
странная какая-то функция... зачем она?
х.з... чё-то делает
я XML эти не понимаю вообще =(
дикий я =)
zg писал(а):
Alex Keda писал(а):return new gException('XML_PARSE_ERROR',SPrintF('%s в линии %u',Xml_Error_String($XmlParser),$Line));
эммм... первый раз вижу чтоб эксепшин возвращали, а не кидали
в смысле - "а не кидали"?
если собаку прилепить, и эксцепшен убрать, то будет пустой текст. это не есть гуд...

Re: [PHP] вырезать все бинарные (не-UTF8 и не ASCI) символы

Добавлено: 2011-10-24 17:52:43
zg
Alex Keda писал(а):в смысле - "а не кидали"?
обычно их кидают, чтобы прекратить выполнение какого-то куска кода

Код: Выделить всё

if (!...)
   throw new Exception(...)
Alex Keda писал(а):х.з... чё-то делает
я XML эти не понимаю вообще =(
выложи её полностью

Re: [PHP] вырезать все бинарные (не-UTF8 и не ASCI) символы

Добавлено: 2011-10-24 21:46:32
Alex Keda
Здоровая, 7k

Код: Выделить всё

dc7700p$ cat hosts/root/system/libs/auto/String.lib
<?php
#-------------------------------------------------------------------------------
/** @author Бреславский А.В. (Joonte Ltd.) */
#-------------------------------------------------------------------------------
function Translit($String) {
  #-----------------------------------------------------------------------------
  $Template = Array('Москва'=>'Moscow','ОАО'=>'PC','ЗАО'=>'c.c.','ООО'=>'Ltd.','Ґ'=>'G','Ё'=>'Yo','Є'=>'E','Ї'=>'Yi','І'=>'I','і'=>'i','ґ'=>'g','ё'=>'yo','№'=>'#','є'=>'e','ї'=>'yi','А'=>'A','Б'=>'B','В'=>'V','Г'=>'G','Д'=>'D','Е'=>'E','Ж'=>'Zh','З'=>'Z','И'=>'I','Й'=>'Y','К'=>'K','Л'=>'L','М'=>'M','Н'=>'N','О'=>'O','П'=>'P','Р'=>'R','С'=>'S','Т'=>'T','У'=>'U','Ф'=>'F','Х'=>'H','Ц'=>'TS','Ч'=>'CH','Ш'=>'SH','Щ'=>'Sch','Ъ'=>'','Ы'=>'Yi','Ь'=>'','Э'=>'E','Ю'=>'Yu','Я'=>'Ya','а'=>'a','б'=>'b','в'=>'v','г'=>'g','д'=>'d','е'=>'e','ж'=>'zh','з'=>'z','и'=>'i','й'=>'y','к'=>'k','л'=>'l','м'=>'m','н'=>'n','о'=>'o','п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u','ф'=>'f','х'=>'kh','ц'=>'ts','ч'=>'ch','ш'=>'sh','щ'=>'sch','ъ'=>'','ы'=>'yi','ь'=>'','э'=>'e','ю'=>'yu','я'=>'ya');
  #-----------------------------------------------------------------------------
  return StrTr($String,$Template);
}
#-------------------------------------------------------------------------------
function String_Xml_Parse($String,$IsUseCache = TRUE){
  #-----------------------------------------------------------------------------
  $Length = Mb_StrLen($String);
  #-----------------------------------------------------------------------------
  $IsUseCache = ($IsUseCache && $Length > 1024);
  #-----------------------------------------------------------------------------
  if($IsUseCache){
    #---------------------------------------------------------------------------
    $CacheID = SPrintF('String_XML_Parse[%s]',Md5(Crc32($String)));
    #---------------------------------------------------------------------------
    $Result = MemoryCache_Get($CacheID);
    if(!Is_Error($Result))
      return $Result;
  }
  #-----------------------------------------------------------------------------
  Debug(SPrintF('[String_XML_Parse]: парсирование строки (%u bytes)',$Length));
  #-----------------------------------------------------------------------------
  $XmlParser = Xml_Parser_Create('UTF-8');
  #-----------------------------------------------------------------------------
  if(!Xml_Parser_Set_Option($XmlParser,XML_OPTION_CASE_FOLDING,FALSE))
    return ERROR | Trigger_Error('[String_Xml_Parse]: не удалось установить опцию парсирования (XML_OPTION_CASE_FOLDING)');
  #-----------------------------------------------------------------------------
  if(!Xml_Parser_Set_Option($XmlParser,XML_OPTION_SKIP_WHITE,FALSE))
    return ERROR | Trigger_Error('[String_Xml_Parse]: не удалось установить опцию парсирования (XML_OPTION_SKIP_WHITE)');
  #-----------------------------------------------------------------------------
  if(!Xml_Parse_Into_Struct($XmlParser,$String,$Nodes)){
    #---------------------------------------------------------------------------
    $ByteIndex = Xml_Get_Current_Byte_Index($XmlParser);
    #---------------------------------------------------------------------------
    Debug(Mb_SubStr($String,$ByteIndex-100,$ByteIndex+100));
    #---------------------------------------------------------------------------
    $Buffer = Mb_SubStr($String,0,$ByteIndex);
    #---------------------------------------------------------------------------
    $Line = Preg_Match_All("/(\r\n|\n)/sU",$Buffer,$Matches) + 1;
    #---------------------------------------------------------------------------
    return new gException('XML_PARSE_ERROR',SPrintF('%s в линии %u',Xml_Error_String($XmlParser),$Line));
  }
  #-----------------------------------------------------------------------------
  Xml_Parser_Free($XmlParser);
  #-----------------------------------------------------------------------------
  $Root = new Tag('__ROOT__');
  #-----------------------------------------------------------------------------
  $Links = Array(&$Root);
  #-----------------------------------------------------------------------------
  foreach($Nodes as $Node){
    #---------------------------------------------------------------------------
    $Current = $Links[Count($Links)-1];
    #---------------------------------------------------------------------------
    switch($Node['type']){
      case 'open':
        #-----------------------------------------------------------------------
        $Tag = new Tag($Node['tag']);
        #-----------------------------------------------------------------------
        if(IsSet($Node['attributes']))
          $Tag->AddAttribs($Node['attributes']);
        #-----------------------------------------------------------------------
        if(IsSet($Node['value'])){
          #---------------------------------------------------------------------
          $Value = $Node['value'];
          #---------------------------------------------------------------------
          if(Trim($Value))
            $Tag->AddChild(new Tag('CDATA',$Value));
        }
        #-----------------------------------------------------------------------
        $Current->Childs[] = $Tag;
        #-----------------------------------------------------------------------
        $Links[] = &$Current->Childs[Count($Current->Childs)-1];
      break;
      case 'cdata':
        #-----------------------------------------------------------------------
        $Value = $Node['value'];
        #-----------------------------------------------------------------------
        if(Trim($Value)){
          #---------------------------------------------------------------------
          $Tag = new Tag('CDATA',$Value);
          #---------------------------------------------------------------------
          $Current->Childs[] = $Tag;
        }
      break;
      case 'complete':
        #-----------------------------------------------------------------------
        $Tag = new Tag($Node['tag']);
        #-----------------------------------------------------------------------
        if(IsSet($Node['attributes']))
          $Tag->AddAttribs($Node['attributes']);
        #-----------------------------------------------------------------------
        if(IsSet($Node['value']))
          $Tag->AddText($Node['value']);
        #-----------------------------------------------------------------------
        $Current->Childs[] = $Tag;
      break;
      case 'close':
        Array_Pop($Links);
      break;
      default:
        # No more...
    }
  }
  #-----------------------------------------------------------------------------
  if($IsUseCache)
    MemoryCache_Add($CacheID,$Root);
  #-----------------------------------------------------------------------------
  return $Root;
}
#-------------------------------------------------------------------------------
?>

Re: [PHP] вырезать все бинарные (не-UTF8 и не ASCI) символы

Добавлено: 2011-10-26 16:57:39
zg
приложи плз файлом пример xml, на котором парсер валится

Re: [PHP] вырезать все бинарные (не-UTF8 и не ASCI) символы

Добавлено: 2011-10-27 8:12:26
Alex Keda
нету xml
там оно на лету формируется
(биллинг это хост-фудовский - он внутри один сплошной xml )

Re: [PHP] вырезать все бинарные (не-UTF8 и не ASCI) символы

Добавлено: 2011-10-27 13:51:37
hizel
хост-фудовский xml-генератор генерирует невалидный xml? xml-мэны вздрогнули

Re: [PHP] вырезать все бинарные (не-UTF8 и не ASCI) символы

Добавлено: 2011-10-28 13:59:38
Alex Keda
хм...
а это тема.
я и не подумал про другую сторону медали