0

私は現在Cで書かれたFTPクライアントに取り組んでおり、それはかなりうまく機能しています。FTPサーバーに接続し、ユーザー名とパスワードでログインする関数を作成することに成功しましたが、エラーを返すのに問題があります。私はstruct FTPError {};3つのフィールドでを設定しました:

  1. intエラーコード
  2. intFTPエラードメイン(私の機能に固有)
  3. char[256]ユーザーが読める説明

関数の呼び出し元は、関数を参照して構造体を渡し、データを入力します。しかし、私はユーザーが読み取り可能な文字列(char[256])を入力するのに苦労しています。文字列を。で埋めますがstrcpy、それを呼び出すと、プログラムがSIGABRTに信号を送ります。私はあなたに私のコードの簡略化された部分を提示します:

struct FTPError {
    int status;
    int domain;
    char message[FTP_ERROR_MAX];
};

typedef int FTPConnection;

FTPConnection FTPConnect(const char *hostname, const char *username, const char *password, struct FTPError *errn) {

    int socket = /* socket file descriptor */

    // Success
    if(success == 1) {
        if(errn) {
            // when I comment out the line below, no signal is sent
            strcpy(errn->message, "User successfully loged in");
            errn->status = 230;
            errn->domain = kServerReplyDomain;
        }
    }

    // return the file descriptor
    return sockfd;
}

PS:これはXcodeがエラーコンソールで私に与えるものです:

Program loaded.
run
[Switching to process 2566]
Running…
SOCK: 3
Program received signal:  “SIGABRT”.
sharedlibrary apply-load-rules all
kill
quit

0x00007fff824c03cc  <+0000>  mov    $0x2000025,%eax
0x00007fff824c03d1  <+0005>  mov    %rcx,%r10
0x00007fff824c03d4  <+0008>  syscall 
0x00007fff824c03d6  <+0010>  jae    0x7fff824c03dd <__kill+17> --> (points this line) 
0x00007fff824c03d8  <+0012>  jmpq   0x7fff82560a8c <cerror>
0x00007fff824c03dd  <+0017>  retq 

3 __kill
2 __abort
1 __stack_chk_fail
0 main

PPS:関数を呼び出すコードを表示するように求められました:

int main (int argc, const char * argv[]) {
    struct FTPError reply;
    FTPConnection socket;

    socket = FTPConnect("ftp.belnet.be", "anonymous", "pwd", &reply);

    printf("SOCK: %d\n", socket);

    return 0;
}
4

4 に答える 4

2

ほとんどerrnの場合、関数に指定されたポインターが正しく初期化されていないか、そうでなければ無効です。それ以外の場合もFTP_ERROR_MAX、数が少なすぎる可能性があるため、strcpy()はバッファオーバーフローを生成します。

于 2010-09-01T16:00:27.867 に答える
0

割り当てられていないポインタではなく、メモリが割り当てられた構造体を渡してもよろしいですか?呼び出しは次のようになります。

FTPError myError;
FTPConnect(host, user, password, &myError);

それ以外の場合、ポインタを使用したい場合:

FTPError* myError = (FTPError*) malloc(sizeof(FTPError));
FTPConnect(host, user, password, myError);
于 2010-09-01T16:02:48.377 に答える
0

それが言っていることから、あなたは他のコードのいくつかであなたのスタックを破壊し、それはちょうどその場所にここに現れると思います。

とにかく、必ず次のerrnようなもので構造を初期化する必要があります

 struct FTPError reply = { .status = 0 };
于 2010-09-01T16:13:41.220 に答える
0

代わりに、strcpyのバリエーションを保存してみてください。

strncpy(errn->message, "any string with unknown length", FTP_ERROR_MAX-1 );
errn->message[ FTP_ERROR_MAX-1 ] = 0;
于 2010-09-01T16:20:52.830 に答える