HTTPAppユニットにあるHTMLEncodeが正常なHTML文字列を出力してくれない。
文字列の中に & < > " があればそれぞれ& < > " に変換してくれるはずなのだがどうもうまく変換してくれない。
仕方がないのでソースを見てみることに。
該当の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件)