-
Notifications
You must be signed in to change notification settings - Fork 7
Description
現在の upTeX の実装では is_char_kanji
が「0 以上の整数かどうか」になっており,そのため文字コードとして TeX が許す最大整数 ("7FFFFFFF) まで可能となっています(Bad character code エラーを発しないし,\char や \chardef に指定できる)。一方で,文字トークンや文字ノードとして可能なのは 24bit 整数値 ("FFFFFF) までの仕様と理解しています。
さて,文字ノード生成時には charcode + kcatcode * max_cjk_val という計算が行われます。この時,文字コード (charcode) が 24bit を超える場合に kcatcode の位まではみ出してしまっています。極端な場合で,足し算が 2^32 を超えることもあり,それは例えば \lastnodechar で不可解な返り値となります。なお,文字トークン生成にはこの問題がなさそうです(0x1000000 以上の文字トークン生成が起こりうるのは \Uchar / \Ucharcat だけで,これは print_kanji
に投げられ,そちらで mod max_cjk_val
されています)。
これを回避する方法として,2 通り考えられます。
- 有効な文字コードの範囲を「0 以上」から「0 以上 2^24 未満」に制限する。
- 有効な文字コードの範囲はそのまま,ノード生成時に
mod max_cjk_val
する。
前者は,文字コードの有効範囲が減るので「大きな整数値を定義する」時に \chardef を使う技(ptex-guide-en に記載)が封じられますが,仕様としてはシンプルです。後者の場合は「大きな整数値を定義する」技は従来通り使えます。
前者は,kanji.c の is_char_kanji
を修正し,和文文字トークン判定 check_kanji
を調整すればよさそうだと @h-kitagawa さんが Gist にコメントくださっています。
boolean check_kanji (integer c)
{
if (c >= CS_TOKEN_FLAG) return false;
else if (!(XXHi(c)>=KCAT_KANJI && XXHi(c)<=KCAT_HANGUL)) return false;
- else return is_char_kanji(c);
+ else return is_char_kanji(c & CJK_TOKEN_FLAG);
}
...
boolean is_char_kanji(integer c)
{
if (is_internalUPTEX())
- return (c >= 0);
+ return ((c >= 0)&&(c<CJK_CHAR_LIMIT));
後者は uptex-m.ch で mod max_cjk_val
を仕込めば実現できます。
→ 'uptex-code1' ブランチで #159 の修正への追加という形にしています。
@t-tk さん,ご意見をいただきたいです。
なお,0x110000 以上 0x1000000 未満の文字コード(OTF パッケージで利用)は影響を受けません。OTF パッケージについては 別の場所 で不具合報告をしております。