我有一个用 Delphi 2007 制作的肥皂,它可以工作!
在 Delphi 10.1 Berlin 进行转换后,我有很多例外:
目标多字节代码页中不存在 Unicode 字符的映射
原因似乎是,当 webbroker HttpApp 解析请求参数时,如果请求在查询字符串中有一些 url 编码的字符,它会引发此异常,例如:
http://localhost/soap/soap.dll/action?param=%E0
事实上,如果我URL.Decode()
用%E0
(à
url编码)调用:
TNetEncoding.URL.Decode('%E0');
它引发了同样的异常:
目标多字节代码页中不存在 Unicode 字符的映射
问题似乎System.NetEncoding
在方法上TURLEncoding.DoDecode(const Input: string): string
。此方法尝试仅在 UTF-8 中转换 url 编码的字符,而不在Windows-1252上进行任何回退。字符串%E0
是 Windows-1252 编码à
,但 delphi 只转换 UTF-8 版本:%C3%A0
.
一个小的(不完美,不优雅)修复是添加一个后备:
try
Result := TEncoding.UTF8.GetString(Bytes); // original Delphi 10.1 line
except
on E: EEncodingError do Result := string(PChar(Bytes)); // fallback
end;
完整代码:
function TURLEncoding.DoDecode(const Input: string): string;
function DecodeHexChar(const C: Char): Byte;
begin
case C of
'0'..'9': Result := Ord(C) - Ord('0');
'A'..'F': Result := Ord(C) - Ord('A') + 10;
'a'..'f': Result := Ord(C) - Ord('a') + 10;
else
raise EConvertError.Create('');
end;
end;
function DecodeHexPair(const C1, C2: Char): Byte; inline;
begin
Result := DecodeHexChar(C1) shl 4 + DecodeHexChar(C2)
end;
var
Sp, Cp: PChar;
I: Integer;
Bytes: TBytes;
begin
SetLength(Bytes, Length(Input) * 4);
I := 0;
Sp := PChar(Input);
Cp := Sp;
try
while Sp^ <> #0 do
begin
case Sp^ of
'+':
Bytes[I] := Byte(' ');
'%':
begin
Inc(Sp);
// Look for an escaped % (%%)
if (Sp)^ = '%' then
Bytes[I] := Byte('%')
else
begin
// Get an encoded byte, may is a single byte (%<hex>)
// or part of multi byte (%<hex>%<hex>...) character
Cp := Sp;
Inc(Sp);
if ((Cp^ = #0) or (Sp^ = #0)) then
raise EHTTPException.CreateFmt(sErrorDecodingURLText, [Cp - PChar(Input)]);
Bytes[I] := DecodeHexPair(Cp^, Sp^)
end;
end;
else
// Accept single and multi byte characters
if Ord(Sp^) < 128 then
Bytes[I] := Byte(Sp^)
else
I := I + TEncoding.UTF8.GetBytes([Sp^], 0, 1, Bytes, I) - 1
end;
Inc(I);
Inc(Sp);
end;
except
on E: EConvertError do
raise EConvertError.CreateFmt(sInvalidURLEncodedChar, [Char('%') + Cp^ + Sp^, Cp - PChar(Input)])
end;
SetLength(Bytes, I);
// ------> MY FIX <------
try
Result := TEncoding.UTF8.GetString(Bytes); // Original line
except
on E: EEncodingError do Result := string(PChar(Bytes));
end;
// END FIX
end;
经过大量搜索后,我找到了RAD Studio 10.1 Berlin 的错误修复列表,它说这个错误已修复:
Webbroker HttpApp 解析请求参数并收到错误“目标多字节代码页中不存在 Unicode 字符的映射”
但不适合我...