[pgsql-jp: 38213] Re: ロケールCでインストールしないとLIKEで invalid memory alloc request

ITAGAKI Takahiro itagaki.takahiro @ oss.ntt.co.jp
2007年 3月 22日 (木) 18:53:49 JST


板垣です。

"Reinin Oyama" <lenin @ hasiru.net> wrote:

> 私は、純粋に、不具合が潜在していないか心配なだけで、調べているのです。
> -1 で、メモリーを、確保しようとしている異常な、挙動は、
> メモリー破壊に起因する可能性が、高いと思っています。

はい。まさにおっしゃるとおり、バグだと思います。
エラーチェックをサボっている場所があるのでしょう。

……と、ざっと眺めていましたが、まずそうな箇所を見つけました。
ここも、strxfrm() の使い方が間違っています。

[src/backend/utils/adt/selfuncs.c]
convert_string_datum(Datum value, Oid typid)
{
    if (!lc_collate_is_c())
    {
        xfrmlen = strxfrm(NULL, val, 0);
★      xfrmstr = (char *) palloc(xfrmlen + 1);


| strxfrm()
| 変換された文字列の長さを返します。終端の NULL 文字は数えません。
| エラーが発生すると、各関数は errno を設定し、INT_MAX を返します。

INT_MAX = 0x7FFFFFFF なので、
   palloc(xfrmlen + 1) → palloc(0x80000000) → palloc(2147483648)
となっているのではないでしょうか。

ここは UTF-8 専用処理もないので、EUC_jp, UTF-8 いずれの場合もアウトです。
OS とサーバ・エンコーディングを一致させれば動作するかもしれませんが、
Windows では SJIS を選べないので、ロケール C 以外で動作する可能性はゼロです。
というわけで、特に Windows では --no-locale は必須です。


ロケールを使えない理由は、OS のロケールが壊れているからでは★ありません★。
PostgreSQL が、ロケール関数の使い方を間違っているからです。

CRT のロケール関数を使う限り、OSとサーバのエンコーディングの一致は必須です。
例えば Windows であれば、バグを修正するにしても、以下の2択になります。
  ・サーバで SJIS をサポートする
  ・いったん UTF-16 に変換した後に Unicode 関数を使う
後者のほうが一般性はありますが、ワイド文字列サポートの弱いOSもありそうなので、
そのあたりの調整は面倒でしょう。何とかしたいところではありますが。




pgsql-jp メーリングリストの案内