[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
BLOGTIMES
» ArchiveList (Tag for "c" )
«Prev || 1 · 2 · 3 · 4 · 5 ·... | | Next»
2023/03/05
2023/03/05
2023/03/05
2023/03/03

TeraTerm の背景色をお手軽に変更できる TTXCommandLineOptKai を TeraTerm5 対応に

teraterm  c 
TTXCommandLineOptKai v2.0 - TeraTerm の背景色をお手軽に変更できる TTXCommandLineOptKai を TeraTerm5 対応に

以前、作成した TeraTerm の背景色をお手軽に変更できる TTXCommandLineOptKai プラグインTeraTerm 5.x 系の API 変更で動かなくなってしまっていたのでバージョンアップしてみました。

前回と同様、ビルド済みの .dll は GitHub にアップロードしてあります。

例えば、このプラグインを入れた状態で user@host.example.com /BG=M のようなホスト名に対して接続すると、背景は画像のような感じになります。


    at 18:31 |
    2022/11/12
    2022/10/06

    gcc で配列の境界外アクセスをチェックする

    c  programming 

    gcc で練習用のプログラムをコンパイルしていろいろ試していたら、配列の境界外アクセスでも意外と SIGSEGV しないパターンが多いことに気づきました。

    test.c

    #include <stdio.h> int main(void){ int a[10] = {1,2,3}; int b[2] = {4,5}; printf("a[0] %p\n", &a[0]); printf("b[2] %p\n", &b[2]); b[2] = 9; // a[0] アドレスと同じなので、a[0]への代入になる for(int i = 0; i < 3; i++){ printf("a[%d] = %d\n",i,a[i]); } }

    例えば、上記のプログラムを実行すると a[0]9 になってしまいます。

    $ gcc test.c $ ./a.out a[0] 0x7fffd1363e80 b[2] 0x7fffd1363e80 a[0] = 9 a[1] = 2 a[2] = 3

    初学者だとこういう間違いが非常に多いので、コンパイラの設定でチェックできる方法がないか調べてみたところ、最近の gcc には AddressSanitizer*1 という仕組みが入っているようです。

    仕組みについては USENIX ATC'12 で発表された論文と GitHub のリポジトリがあります。

    上記と同じプログラムをサニタイザありでコンパイルして実行すると、こんな感じで runtime error が出るようになります。

    $ gcc -g -fsanitize=bounds test.c $ ./a.out a[0] 0x7ffdff286da0 b[2] 0x7ffdff286da0 test.c:9:3: runtime error: index 2 out of bounds for type 'int [2]' a[0] = 9 a[1] = 2 a[2] = 3

    at 07:57 |
    2022/05/21
    2021/12/19

    scanf() で整数を 1 バイト分だけ読み取る

    c 

    最近の gcc はチェックが厳しくなっているので scanf() を使って int の値を char に書込むと *** stack smashing detected *** というエラーが出るようです。

    例えば 10 進の値を char に代入するようなプログラムは C 言語の入門などでよく出てきます。

    test.c

    #include <stdio.h> int main(void){ char c; printf("文字コード: "); scanf("%d", &c); printf("文字コード%dの文字は'%c'です\n",c,c); return 0; }

    コンパイルすると警告が出る

    これを単純にコンパイルすると、以下のように警告が出ます
    これを見て驚くのは、最近の gcc はエラーや警告メッセージがかなり丁寧になっているということ。

    これをきちんと読めば、scanf() に含まれる書式指定 %d は可変長引数部分の int * に対応していなければならないのに対して、実際の可変長引数部分の型は char * になっているので、型があっていないというのがきちんと分かります。

    これを修正するための候補として %hhd も挙げられていますね。

    $ gcc --version gcc (Ubuntu 9.3.0-10ubuntu2) 9.3.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ gcc test.c test.c: In function ‘main’: test.c:6:10: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘char *’ [-Wformat=] 6 | scanf("%d", &c); | ~^ ~~ | | | | | char * | int * | %hhd

    とりあえず無理やり実行してみる

    とりあえずコンパイル自身はされているので、警告を無視して実行してみます。
    結果は表示されますが、実行時エラーが出て正常終了しません

    $ ./a.out 文字コード: 100 文字コード100の文字は'd'です *** stack smashing detected ***: terminated Aborted

    実行時のエラーの原因は char (1B) の領域に無理やり int (4B) 分のデータを書込んでしまうからですね。
    要はバッファーオーバーフローです。

    このバッファオーバーフローが gcc の stack protector*1 によって検知されていることになります。
    実行結果が表示されてしまっているのは、stack protector が関数の実行後(今回の場合は main()の実行終了時 )にバッファオーバーフローを検出しているためです。

    書式を修正してみる

    gcc の警告のアドバイスに従って書式を %hhdにしてみるとコンパイルの警告、実行時エラー共に解消しました。

    サイズ的には %d→4B、%hd→2B、%hhd→1B となるようなので、h は half の h でしょうか(llongl だと分かるのですが)。

    test.c

    #include <stdio.h> int main(void){ char c; printf("文字コード: "); scanf("%hhd", &c); printf("文字コード%dの文字は'%c'です\n",c,c); return 0; }
    $ gcc test.c $ ./a.out 文字コード: 100 文字コード100の文字は'd'です

    ちなみに調べてみたら h 接頭辞は C99 から使えるようになっていたようです。


    at 15:22 |
    2021/01/17

    C 言語で cwd を取得する

    c 

    C で cwd を表示するプログラムが書きたくなって調べてみたのでメモ。
    やり方はいろいろあるようなのですが、Linux / Windows 両対応させたいので POSIX に含まれている getcwd()*1 を使ってみました。
    C はアプリを書くために普段あまり使っていないので、やっぱりちょっと面倒な感じがしますね。

    #include <stdio.h> #ifdef _WIN32 #include <stdlib.h> #include <direct.h> #define PATH_MAX _MAX_PATH #elif defined __linux__ #include <linux/limits.h> #endif int main() { char path[PATH_MAX]; getcwd(path, PATH_MAX); puts(path); return 0; }

    at 13:54 |
    2020/11/07

    TIOBE Index で Python が初の 2 位に

    python  java  c 

    プログラミング言語の人気ランキングとしてよく使われている TIOBE Index Python が始めて 2 位になっていました

    C と Java が 1, 2 位を明け渡すのは TIOBE Index 至上初とのこと。
    Java は Oracle の JRE/JDK ライセンス変更以降、退潮傾向が続いているので中長期的にはしょうがないかなという感じもします。

    JavaとCの2大人気に異変、Pythonが2位にーーTIOBE Index | OSDN Magazine

    オランダTIOBE Softwareが発表した最新のプログラミング言語ランキング「TIOBE Index for November 2020」で、Pythonが過去最高位の2位となった。約20年前にTIOBE Indexの作成を開始以来初めてJavaとCが揃って上位2位に入らないという結果となった。


      at 17:05 |
      «Prev || 1 · 2 · 3 · 4 · 5 ·... | | Next»
      » ArchiveList (Tag for "c" )