■1.次のプログラムは何と表示されますか?
#include <stdio.h>
#include <string.h>
//strlen("全角")は4とは限らない
void f1(void){
printf("4を期待してはいけない:strlen = %zu\n",strlen("全角"));
printf("5を期待してはいけない:sizeof = %zu\n",sizeof("全角"));
}
//全角を2byteと決めつけるのは危険
void f2(void){
for(size_t i = 0;i < sizeof("全");i++){
printf("%02x[%zu]\n",(unsigned char)"全"[i],i);
}
}
//昔は問題がなかったがUTF-8では事故になる例
void f3(void){
char src[3] = "全";//右辺が3byteの場合終端文字が入らない
char dst[3];
strcpy(dst,src); //終端文字がないので暴走の可能性
printf("%s\n",dst); //終端文字がないので暴走の可能性
}
int main(void){
f1();
f2();
fflush(stdout);
f3();
}
■2.ソースコードがEUCの場合
4を期待してはいけない:strlen = 4
5を期待してはいけない:sizeof = 5
c1[0]
b4[1]
00[2]
全
プログラマの期待した結果になります。
■3.ソースコードがShift_JISの場合
4を期待してはいけない:strlen = 4
5を期待してはいけない:sizeof = 5
91[0]
53[1]
00[2]
全
プログラマの期待した結果にこの例ではなりましたが、
gcc/clangでShift_JISのソースコードをコンパイルすると
5C問題(いわゆる化け字問題)を起こすので
基本的に
gcc/clangでShift_JISのソースコードをコンパイル
してはいけません。
■4.ソースコードがUTF-8の場合
4を期待してはいけない:strlen = 6
5を期待してはいけない:sizeof = 7
e5[0]
85[1]
a8[2]
00[3]
====中略
==755==ERROR: AddressSanitizer: stack-buffer-overflow on address
プログラマの期待した結果になりません。
実験した環境下ではプログラムは異常終了しました。
■5.実験用スクリプト
rm -f ./a.out
nkf -we -Lu f0.c > EUC.c
nkf -g EUC.c
gcc EUC.c -Wall -Wextra -fsanitize=address
./a.out | nkf
rm -f ./a.out
iconv -f utf8 -t sjis f0.c > Shift_JIS.c
nkf -g Shift_JIS.c
gcc Shift_JIS.c -Wall -Wextra -fsanitize=address
./a.out |nkf
rm -f ./a.out
cp f0.c UTF-8.c
nkf -g UTF-8.c
gcc UTF-8.c -Wall -Wextra -fsanitize=address
./a.out