ошибка в fpjson ?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

ошибка в fpjson ?

Сообщение jsa »

Открыл эту тему вместо темы - Как из строки удалить спец символ xEF (BOM ?)
http://www.freepascal.ru/forum/viewtopi ... =5&t=43898
----

Получаю с телеграмма сообщение с эмодзи.
..."text":"\u2600\ufe0f"}
При преобразовании и сохранении в строку

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

jsonObj:=GetJSON( sResp ) as TJSONObject; 
tele_txt:= jsonObj.Items[i].FindPath(path+'text').AsString; 
Получаю
..."text" : "☀}
т.е. преобразование \u2600\ufe0f дает кракозябру которая к тому же съедает кавычки в строке.

Получается ошибка в fpjson в функции
function JSONStringToString(const S: TJSONStringType): TJSONStringType;

А именно в преобразовании,

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

        Case S[I] of
          '\','"','/'
              : App:=S[I];
          'b' : App:=#8;
          't' : App:=#9;
          'n' : App:=#10;
          'f' : App:=#12;
          'r' : App:=#13;
          'u' : begin
                U2:=BufferHexToInt(PAnsiChar(@S[I+1]));
                if U2=-1 then
                   Raise EJSON.Create('Invalid unicode hex code: '+Copy(S,I+1,4));
                Inc(I,4);
                if (U1<>0) then
                  begin
                  App:={$IFDEF FPC_HAS_CPSTRING}UTF8Encode({$ENDIF}WideChar(U1)+WideChar(U2){$IFDEF FPC_HAS_CPSTRING}){$ENDIF};
                  U2:=0;
                  end
                else
                  U1:=U2;
                end;
        end;                           
Не могу до конца понять что тут происходит, но такое ощущение, что просто не реализована работа с двойным \u для одного символа
sts
энтузиаст
Сообщения: 519
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Сообщение sts »

в TJSONScanner.DoFetchToken другой код, надо попробовать по аналогии с ним сделать
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Сообщение jsa »

Т.к. для работы бота эмодзи видеть нет необходимости, и время поджимало, на скору руку сделал костыль и примотал его.
Две функции J_uS и J_Su
Первая заменяет все \u для кодов НЕкириллицы ( 0400—04FF - кириллица, 0500—052F - Дополнение к кириллице )
потом работаю с json потом для вынутых из него строк делаю обратную замену.

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

{ замена в строке \u на $&$ }
function J_uS(jResp:String):String;
var i, ln, icode:integer; ustr, Rst, ssss:string;
begin
     ln:=Length(jResp);
     i:=1;
     Rst:='';
  try
     while i<=Ln do
     begin
     if (jResp[i]='\')and(i<Ln) then
        begin
        if (jResp[i+1]='u')and(i+1<Ln) then
           begin
           ustr:=Copy(jResp,i+2,4);
           icode:=StrToInt('$'+ustr);
           if  (1024<=iCode)and(iCode<=1279) // 0400—04FF - кириллица
             or(1280<=iCode)and(iCode<=1327) // 0500—052F - Дополнение к кириллице
              then Rst:=Rst+'\u'+ustr
              else Rst:=Rst+'$&$'+ustr;
           i:=i+6;
           end
           else begin Rst:=Rst+jResp[i]+jResp[i+1]; i:=i+2 end;
        end
        else begin Rst:=Rst+jResp[i]; inc(i) end;
     end;
  except
        On E: Exception Do begin writelog.WrLog('Exception "J_uS" --- '+E.ToString+#13+jResp+#13+Rst); end;
  end;
  Result:=Rst;
end;

{ замена в строке $&$ на \u }
function J_Su(jResp: String):String;
begin
     result:= StringReplace( jResp, '$&$', '\u',[rfReplaceAll]);
end; 
Т.е. кириллица декодируется , а все остальное остается как есть.
Аватара пользователя
Ichthyander
энтузиаст
Сообщения: 701
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань
Контактная информация:

Сообщение Ichthyander »

В старых версиях Lazarus был баг в JSONStringToString при работа fpjson с эмодзи, я его еще репортил в свое время в багтрекрер FPC. Как раз были подобные проблемы в моей библиотеке для работы с телеграм, а в мессенджерах эмодзи распрастранены. Но в стабильной и в транковой этой проблемы уже нет. Поправили. Может у Вас старая версия Lazarus/FPC?
jsa
постоялец
Сообщения: 295
Зарегистрирован: 28.11.2017 12:46:04

Сообщение jsa »

Lazarus 2.2.6 (rev lazarus_2_2_6)
FPC 3.2.2 i386-win32-win32/win64
Видимо сильно устарело
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3067
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

Жаль, что это до сих пор не стало железным правилом у паскалистов - прежде чем жаловаться на какие-то баги, обновиться до последних версий. В 99% случаев, от этого баги исчезают...
sts
энтузиаст
Сообщения: 519
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Сообщение sts »

Снег Север писал(а):Жаль, что это до сих пор не стало железным правилом у паскалистов - прежде чем жаловаться на какие-то баги, обновиться до последних версий.
это правило окружения с низким качеством кода, в нормальных окружениях повода для такого правила нет, слишком редко оно срабатывает, паскалисты не привыкли к такому.
iskander
энтузиаст
Сообщения: 627
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

sts писал(а):паскалисты не привыкли к такому
:D

Текущая релизная версия компилятора - 3.2.2, TJsonParser из поставки FPC-3.2.2 парсит строку "\u2600\ufe0f" в

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

#$E2#$98#$80#$EF
в то время как правильный результат

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

#$E2#$98#$80#$EF#$B8#$8F

В транке вроде исправлено, насчёт 3.2.3 не интересовался.
С другой стороны, со следующим релизом компилятора всё довольно туманно и с этим багом счастливым пользователям FpJson придётся какое-то время жить.
Почему бы просто не заменять U-эскейпы входного JSON-а их UTF-8 кодами до передачи его парсеру?
Ответить