THRIFT-2345 Delphi: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
Patch: Jens Geyer
diff --git a/lib/delphi/src/Thrift.Protocol.JSON.pas b/lib/delphi/src/Thrift.Protocol.JSON.pas
index cce6c3c..6d305d8 100644
--- a/lib/delphi/src/Thrift.Protocol.JSON.pas
+++ b/lib/delphi/src/Thrift.Protocol.JSON.pas
@@ -254,7 +254,6 @@
RBRACKET : TBytes;
QUOTE : TBytes;
BACKSLASH : TBytes;
- ZERO : TBytes;
ESCSEQ : TBytes;
const
@@ -815,7 +814,8 @@
function TJSONProtocolImpl.ReadJSONString( skipContext : Boolean) : TBytes;
var buffer : TMemoryStream;
- ch : Byte;
+ ch : Byte;
+ wch : Word;
off : Integer;
tmp : TBytes;
begin
@@ -832,25 +832,34 @@
if (ch = QUOTE[0])
then Break;
- if (ch = ESCSEQ[0])
- then begin
- ch := FReader.Read;
- if (ch = ESCSEQ[1])
- then begin
- ReadJSONSyntaxChar( ZERO[0]);
- ReadJSONSyntaxChar( ZERO[0]);
- SetLength( tmp, 2);
- Transport.ReadAll( tmp, 0, 2);
- ch := (HexVal(tmp[0]) shl 4) + HexVal(tmp[1]);
- end
- else begin
- off := Pos( Char(ch), ESCAPE_CHARS);
- if off < 1
- then raise TProtocolException.Create( TProtocolException.INVALID_DATA, 'Expected control char');
- ch := Byte( ESCAPE_CHAR_VALS[off]);
- end;
+ // check for escapes
+ if (ch <> ESCSEQ[0]) then begin
+ buffer.Write( ch, 1);
+ Continue;
end;
- buffer.Write( ch, 1);
+
+ // distuinguish between \uNNNN and \?
+ ch := FReader.Read;
+ if (ch <> ESCSEQ[1])
+ then begin
+ off := Pos( Char(ch), ESCAPE_CHARS);
+ if off < 1
+ then raise TProtocolException.Create( TProtocolException.INVALID_DATA, 'Expected control char');
+ ch := Byte( ESCAPE_CHAR_VALS[off]);
+ buffer.Write( ch, 1);
+ Continue;
+ end;
+
+ // it is \uXXXX
+ SetLength( tmp, 4);
+ Transport.ReadAll( tmp, 0, 4);
+ wch := (HexVal(tmp[0]) shl 12)
+ + (HexVal(tmp[1]) shl 8)
+ + (HexVal(tmp[2]) shl 4)
+ + HexVal(tmp[3]);
+ // we need to make UTF8 bytes from it, to be decoded later
+ tmp := SysUtils.TEncoding.UTF8.GetBytes(Char(wch));
+ buffer.Write( tmp[0], length(tmp));
end;
SetLength( result, buffer.Size);
@@ -1174,6 +1183,5 @@
InitBytes( RBRACKET, [Byte(']')]);
InitBytes( QUOTE, [Byte('"')]);
InitBytes( BACKSLASH, [Byte('\')]);
- InitBytes( ZERO, [Byte('0')]);
InitBytes( ESCSEQ, [Byte('\'),Byte('u'),Byte('0'),Byte('0')]);
end.