[Delphi] HTTPApp.HTMLEncodeの不具合

HTTPAppユニットにあるHTMLEncodeが正常なHTML文字列を出力してくれない。
文字列の中に & < > " があればそれぞれ&amp; &lt; &gt; &quot; に変換してくれるはずなのだがどうもうまく変換してくれない。

 

仕方がないのでソースを見てみることに。
該当のHTMLEncodeは下記のようになっていた。

function HTMLEncode(const AStr: String): String;
const
  Convert = ['&','<','>','"'];
var
  Sp, Rp: PChar;
begin
  SetLength(Result, Length(AStr) * 10);
  Sp := PChar(AStr);
  Rp := PChar(Result);
  while Sp^ <> #0 do
  begin
    case Sp^ of
      '&': begin
             FormatBuf(Rp^, 5, '&', 5, []);
             Inc(Rp,4);
           end;
      '<',
      '>': begin
             if Sp^ = '<' then
               FormatBuf(Rp^, 4, '<', 4, [])
             else
               FormatBuf(Rp^, 4, '>', 4, []);
             Inc(Rp,3);
           end;
      '"': begin
             FormatBuf(Rp^, 6, '"', 6, []);
             Inc(Rp,5);
           end;
    else
      Rp^ := Sp^
    end;
    Inc(Rp);
    Inc(Sp);
  end;
  SetLength(Result, Rp - PChar(Result));
end;

よく見てるとFormatBufのところが正しく動いていないようだ。ということで、FormatBufの不具合を疑ったのだが、どうやらFormatBufに渡しているパラメータがまずいらしい。
FormatBufに渡すパラメータはバイト単位で文字数ではないのだが、文字数で渡していたみたい。AnsiStringの際には半角英数は1文字1バイトであったので、正しく動いていたのであろうということが伺える。処理がUnicode16になったことで半角英数も1文字2バイトになったので、あわせてパラメータを2倍して渡してみたところ正常に動作した。

function HTMLEncode(const AStr: String): String;
const
  Convert = ['&','<','>','"'];
var
  Sp, Rp: PChar;
begin
  SetLength(Result, Length(AStr) * 10);
  Sp := PChar(AStr);
  Rp := PChar(Result);
  while Sp^ <> #0 do
  begin
    case Sp^ of
      '&': begin
             FormatBuf(Rp^, 10, '&', 10, []);
             Inc(Rp,4);
           end;
      '<',
      '>': begin
             if Sp^ = '<' then
               FormatBuf(Rp^, 8, '<', 8, [])
             else
               FormatBuf(Rp^, 8, '>', 8, []);
             Inc(Rp,3);
           end;
      '"': begin
             FormatBuf(Rp^, 12, '"', 12, []);
             Inc(Rp,5);
           end;
    else
      Rp^ := Sp^
    end;
    Inc(Rp);
    Inc(Sp);
  end;
  SetLength(Result, Rp - PChar(Result));
end;

Unicode文字列に対する必要バイト数が正しく設定されていないのが原因だった。
Unicode化に正しく対応できていない関数はまだまだありそうな感じですね。

コメント (0件)


くろねこ研究所
https://www.blackcat.xyz/article.php/ProgramingFAQ_del0080