CPP悪用
xxxxxxxxxx
••%:define H(x) <st%:%:x##.h>
••#include H(dio)
••#include H(dlib)
••#include H(ring)
••#define x ) == 0 ?__LINE__:0){O =__LINE__;break;} }
••#define X(x) __LINE__ x __LINE__
••#define t(a)\
for (c = 0; c <n##a; ++c) { \
if (strchr (a[c], 0[__FILE__])) { if (*a[c] == 0[__FILE__]) { \
if (strcmp (a[c]+__LINE__, I + strlen (I) + __LINE__ - strlen (a[c]) x else { \
if (strncmp (a[c], I, strlen (a[c])-__LINE__ x \
} else { if (strcmp (a[c], I x }
#line 4 "info\0r"
int
main (int C, char **V)
{
FILE *H;
int c, ne, nn, S = C < 2 ? 060 : *V[1];
char f[__LINE__][X(*)], K[X(*)], L[X(<<)],
e[X(<<)][3*__LINE__], n[X(<<)][3*__LINE__], F[__LINE__];
if (freopen (__FILE__, 5+__FILE__, stdin) == 0) return __LINE__-13;
for (c = 0;;) {
#line 1 "#\n"
if (!fgets (f[c], (int)sizeof *f, stdin)) return __LINE__; if (*f[c] == 0[__FILE__]) continue; if (*f[c] != __LINE__[__FILE__]) { f[c][strlen (f[c]) - __LINE__] = 2[__FILE__];
++c;
} else
break;
}
for (ne = 0;;) {
do {
#line 1 "#%s%s"
if (!fgets (L, (int)sizeof L, stdin)) return __LINE__; } while (*L == 0[__FILE__]); switch (sscanf (L, __LINE__+__FILE__, F, e[ne])) { default: goto O;
case __LINE__: switch (strchr (F, S)!=0) case 1: ++ne;
}
}
O:
nn = 0;
while ((fgets (L, (int) sizeof L, stdin)) != 0) {
char A[__LINE__], f3; if (*L == 0[__FILE__]) continue;
#line 1 "%s%s %c"
switch (sscanf (L, __FILE__, A, n[nn], &f3)) {
case __LINE__: if (strchr (A, S)) ++nn; break;
case __LINE__:
if (strchr (A, S)) {
#line 8 "<%s>:\n"
char *I = L + __LINE__;
int O = printf (__FILE__, n[nn]) +
#line 2 "0gcc -ansi -E -dM -undef %s /usr/include/%s>r\0 ("
sprintf (K, 1+__FILE__, f[S-*__FILE__] + __LINE__, n[nn]);
O += system (K);
if ((H = fopen (__FILE__+44, 44+__FILE__)) == 0) return 1;
while ((fgets (L, (int)sizeof L, H)) != 0) {
I[strcspn (I, 46+__FILE__)] = O = 0;
#line 1 "*r"
t (n) t (e)
if (0 == O) O = puts (L);
}
nn = fclose (H);
}
}
}
return remove (1+__FILE__);
}
引用元:https://www.ioccc.org/1998/schweikh1.c
審査員・作者による説明:https://github.com/ioccc-src/winner/blob/main/1998/schweikh1.hint
Cコンパイラのconformance testとして書かれたプログラム。 よくわからない出力が出てくるだけ。 終了コードが0なら成功なのだと思う。
$ cp data info
$ gcc -o schweikh1 schweikh1.c
$ ./schweikh1
<errno.h>:
#define e
<stddef.h>:
<assert.h>:
#define asse
<locale.h>:
#define NULL ((void
<math.h>:
#define M_SQRT1_2 0.70710678118654752440
...
#include
の引数をマクロの結合で生成したり、#line
のファイル名にNUL文字を挿入したり、digraphを利用したりして、当時のCコンパイラのバグ挙動をつきまくったプログラムとのこと。
ただ、当時から審査員コメントに「元のコードはgccでは動くがISO C89違反」のような記述があり、どこまで信用していいのかわからない。
とりあえずstdio.h
をマクロの結合で生成するのは現代のgccでも禁止されていた。
また#line
にinfo\0r
を置くのは可能だが、\0
より先は__FILE__
では参照できなかった。
これらを修正して終了コードが0になるようになったが、これで想定通りに動いているのかどうかはわからない。
xxxxxxxxxx
--- schweikh1.c
+++ schweikh1.c
-••%:define H(x) <st%:%:x##.h>
-••#include H(dio)
-••#include H(dlib)
-••#include H(ring)
+••
+••#include <stdio.h>
+••#include <stdlib.h>
+••#include <string.h>
••#define x ) == 0 ?__LINE__:0){O =__LINE__;break;} }
••#define X(x) __LINE__ x __LINE__
char f[__LINE__][X(*)], K[X(*)], L[X(<<)],
e[X(<<)][3*__LINE__], n[X(<<)][3*__LINE__], F[__LINE__];
- if (freopen (__FILE__, 5+__FILE__, stdin) == 0) return __LINE__-13;
+ if (freopen (__FILE__, "r", stdin) == 0) return __LINE__-13;
for (c = 0;;) {
#line 1 "#\n"
if (!fgets (f[c], (int)sizeof *f, stdin)) return __LINE__; if (*f[c] == 0[__FILE__]) continue; if (*f[c] != __LINE__[__FILE__]) { f[c][strlen (f[c]) - __LINE__] = 2[__FILE__];