Not only is the Internet dead, it's starting to smell really bad.:2021年05月22日分

2021/05/22(Sat)

[オレオレN6] bm(3)にオーバーラン系のバグがあったもよう

やっぱbm(3)のバグじゃねーか、おのれKeith!

つーかN本家はとっくの7年前に直ってたことに問題個所特定した後で気づいたよクソァ!当時まだサポート中のN6 STABLEへのpullupサボってたもよう、仮にもlibc関数のオーバーランだし使ってるアプリ無くてもそこはちゃんとしようや。

diff --git a/lib/libc/string/bm.c b/lib/libc/string/bm.c
index e38fe7db6c5..5dc211f8c64 100644
--- a/lib/libc/string/bm.c
+++ b/lib/libc/string/bm.c
@@ -201,7 +201,7 @@ bm_exec(pat, base, n)
 	e = base + n - 3 * pat->patlen;
 	while (s < e) {
 		k = d0[*s];		/* ufast skip loop */
-		while (k) {
+		while (k && s < e) {
 			k = d0[*(s += k)];
 			k = d0[*(s += k)];
 		}

つーかこの実装ってただのBM法ではないのはすぐわかったけど改良版のSunday法ってやつか、ペーパーは こちら。 ここのサンプルコードほぼそのままでバグもここ由来、KeithすまんかったおのれSunday!

というかKeithは気づいてたのか修正試みて失敗してる感じやな、オリジナルだと

	s = base+pat.patlen-1;
	e = base+n;

と検索対象文字列の最後までufast skip loopを試みるけど

        s = base + (pat->patlen - 1);

        /* fast loop up to n - 3 * patlen */
        e = base + n - 3 * pat->patlen;

と検索文字列の長さ3倍減じることでガードしたつもりだったのかなと、d0の各要素はpat->patlen-1超えない前提で。 なんとKeith Bostic級のグルでもわからない俺は雰囲気で実装してるなんてあるんだなぁ。

性能については素のBM法に比べてたった1文字移動量が多くなることで速くなるそうで、チリも積もれば何とやら。

これで動くようになったのでとりあえず 前の差分をcommitしておいたが、国際化絡み考えると性能落ちても素のBM法の方がいい気がするし悩ましいね。

まぁnviのワイド文字版regexのcharacter classバグの方が優先度高いのでそっちやるか…

[プログラミング] カレンダーの国際化

kbkさんとこ、Nのcal(1)だと-R(Reform)オプションでイギリス以外でも表示できますな。

そもそもcal(1)の国際化にはPOSIX localeは完全に役立たずなのよね、まず第一にグレゴリオ暦以外扱えないという話は 以前書いたとおり。

ということでその辺のデータにはcal(1)が自前で持ってる、以下はNのcal(1)のソース。

static struct reform {
	const char *country;
	int ambiguity, year, month, date;
	long first_missing_day;
	int missing_days;
	/*
	 * That's 2 for standard/julian display, 4 for months possibly
	 * affected by the Gregorian shift, and MAXDAYS + 1 for the
	 * days that get displayed, plus a crib slot.
	 */
} *reform, reforms[] = {
	{ "DEFAULT",		0, 1752,  9,  3, 0, 0 },
	{ "Italy",		1, 1582, 10,  5, 0, 0 },
	{ "Spain",		1, 1582, 10,  5, 0, 0 },
	{ "Portugal",		1, 1582, 10,  5, 0, 0 },
	{ "Poland",		1, 1582, 10,  5, 0, 0 },
	{ "France",		2, 1582, 12, 10, 0, 0 },
	{ "Luxembourg",		2, 1582, 12, 22, 0, 0 },
	{ "Netherlands",	2, 1582, 12, 22, 0, 0 },
	{ "Bavaria",		0, 1583, 10,  6, 0, 0 },
	{ "Austria",		2, 1584,  1,  7, 0, 0 },
	{ "Switzerland",	2, 1584,  1, 12, 0, 0 },
	{ "Hungary",		0, 1587, 10, 22, 0, 0 },
	{ "Germany",		0, 1700,  2, 19, 0, 0 },
	{ "Norway",		0, 1700,  2, 19, 0, 0 },
	{ "Denmark",		0, 1700,  2, 19, 0, 0 },
	{ "Great Britain",	0, 1752,  9,  3, 0, 0 },
	{ "England",		0, 1752,  9,  3, 0, 0 },
	{ "America",		0, 1752,  9,  3, 0, 0 },
	{ "Sweden",		0, 1753,  2, 18, 0, 0 },
	{ "Finland",		0, 1753,  2, 18, 0, 0 },
	{ "Japan",		0, 1872, 12, 20, 0, 0 },
	{ "China",		0, 1911, 11,  7, 0, 0 },
	{ "Bulgaria",		0, 1916,  4,  1, 0, 0 },
	{ "U.S.S.R.",		0, 1918,  2,  1, 0, 0 },
	{ "Serbia",		0, 1919,  1, 19, 0, 0 },
	{ "Romania",		0, 1919,  1, 19, 0, 0 },
	{ "Greece",		0, 1924,  3, 10, 0, 0 },
	{ "Turkey",		0, 1925, 12, 19, 0, 0 },
	{ "Egypt",		0, 1928,  9, 18, 0, 0 },
	{ NULL,			0,    0,  0,  0, 0, 0 },
};

ここで注目すべきは"Japan"の項が1872/12/20になってることやね。

$ cal -R Japan 12 1872
   December 1872
 S  M Tu  W Th  F  S
                1  2
 3  4  5  6  7  8  9
10 11 12 13 14 15 16
17 18 19


ハイクソー、日本人の感覚では明治5年12月3~19日なんて存在しないんですがこれはNのcal(1)の仕様やね。 そもそも日本はユリウス暦を採用してた事は無くグレゴリオ暦の前は寛政暦だったのだけど、cal(1)はユリウス暦と決めつけてるわけ、どこの異世界カレンダーかよ。

とはいえ日本だと150年前ものカレンダーを表示する必要性ほぼ無いのでイラっとくることも少ないのだけど、つい2016年までヒジュラ歴を採用してたサウジアラビアなんかでは混乱するんじゃねぇかな。 つーかすでに存在するエントリでもトルコとエジプトは明らかに問題なはずよね、それこそイスラム的にユリウス暦すなわち十字軍野郎の暦を使ってたことにされるとか怒られない?

という余計な心配してしまうのだが、そもそもイスラムのヒジュラ暦って太陰暦だからどんどん季節とズレてくので、ルーミー暦(キュロス紀元の春分の日を起点としたユリウス暦)も併用してたのでまぁいいか…

他にもツッコミどころ多くて独立宣言の1776年以前から存在するAmericaとか、この2021年にU.S.S.Rがまだ存在してたりな(ソ連関連のネタはもうひとつあるがまた後で)、よろしいシベリア送りだ。

話を戻して、他にも国際化が必要なものに言語地域によって週の開始が日曜だったり月曜だったりがあるのだけどこの情報もLC_TIMEは持ってない。 いちおう TR14652では拡張してこのへんの情報も持とうという方向性だったのだけど、廃案になってしまったのでな。

こいつらはglibc2には実装されてるので(というかこっちが元だし)locale(1)の-kオプションか、C言語からならnl_langinfo(3)に

を渡すと取得できる、もちろん移植性は皆無なので使わない方がいいけど。

そんでさっきのソ連の話につながるのだが、そもそもPOSIX localeだと非週7日制の暦たとえば

が扱えないのよね、神は納期7日で世界作って最後の1日でやるべきテストをサボったから世の中争いが絶えないのでどんどん変えていこう。

いくら週7日制というものが月の満ち欠けの周期を4で割った近似値で人類のDNAに刷り込まれたものとはいえ、プラゴミの収集日が7日に一回って少ねえよ横浜市!よって週5日制が妥当だと思います、よし革命だ。

これについてもglibc2の開発者の連中はパラノイア極めてるのか

なんてパラメーターが増えてたりする(こちらはlocaleコマンドからは不可視)、莫迦じゃねえの(褒め)。 これきっとオー〇ン〇〇エ〇ィ財団からの資金援助で実装され、〇ラー革命が全世界で成功した後は労働者を奴隷とすべく週365~6日制(週休2日、ホワイトだなあぁ)を施行するための準備と思われる、おのれ〇ョージ・ソ〇ス!(陰謀論) *1

しかしこの_NL_TIME_WEEK_NDAYSだけじゃDAY_7/ABDAY_7より大きい曜日扱えないわけで、まったく意味ないのだ、やっぱりglibc2莫迦じゃねえの(dissり)。

*1:まったくどうでもいいけど陰謀論者ができあがるまでを知りたければP.K.ディックの「戦争が終り、世界の終りが始まった」を読むとよい、ちょうどハヤカワで「ジャック・イジドアの告白」に改題して再刊されたし。 ディック本人がなぜ敵国人差別とオカルトに傾倒したのかその世情と自身の育った環境を自虐的に書き残している、いまの世に読み返すとおもしろいよ。 それとソヴィエト革命暦の採用に他国でもっとも熱心だったのはアメリカだったって話、昨今の騒動で隠れ共産主義者が多いのが可視化された後だと興味深いよね…