本文介绍了目标多字节代码页中不存在Unicode字符的映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用Delphi 2007构建的肥皂,它可以工作!

i have a soap builded with Delphi 2007 and it work!

在Delphi 10.1 Berlin中进行转换后,我有很多例外:

After a conversion in Delphi 10.1 Berlin i have a lot of exceptions:

原因似乎是,当webbroker HttpApp解析请求参数时,如果请求在查询字符串中包含一些url编码的字符,则会引发此异常,例如:

the cause seem, when webbroker HttpApp parsing the request parameters, it raise this exception if request has some url encoded chars in the query string, eg.:

http://localhost/soap/soap.dll/action?param=%E0

实际上,如果我用%E0(à URL编码的):

in fact if i call URL.Decode() with %E0 (à url encoded):

TNetEncoding.URL.Decode('%E0');

它引发了相同的异常:

方法TURLEncoding.DoDecode(const Input: string): string上的问题似乎为单元System.NetEncoding.此方法尝试仅在UTF-8中转换url编码的字符,而不会在 Windows-1252 .字符串%E0à的Windows-1252编码,但是delphi仅转换UTF-8版本:%C3%A0.

The problem seem unit System.NetEncoding on method TURLEncoding.DoDecode(const Input: string): string. This method try to convert url encoded chars only in UTF-8 without any fallback on Windows-1252. String %E0 is Windows-1252 encoding for à, but delphi only conver UTF-8 version: %C3%A0.

一个小的(不完美,不优雅的)修复方法是添加一个后备功能:

A small (not perfect, not elegant) fix is add a fallback:

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的错误修复列表,它表示此错误已修复:

After a lot of search i founds the Bug fix list for RAD Studio 10.1 Berlin and it says this bug is fixed:

但对我不起作用...

but not work for me...

推荐答案

尝试使用WEB.ReqMulti;

try use WEB.ReqMulti;

当WebBroker在表单中存在多字节字符时,使用WebBroker处理来自网页的POST方法时,我有一个相同的例外.

I have the same exception when I user WebBroker to handle a POST method from a web page when there are multi-byte character in form.

当我在WebBroker的项目中添加使用WEB.ReqMulti之后,该异常消失了.

And after I added use WEB.ReqMulti in WebBroker's project, this exception was gone.

这篇关于目标多字节代码页中不存在Unicode字符的映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-28 03:20
查看更多