[英]C - Buffer overflow with strcpy() and strncpy()
我正在edx上參加CS50課程,應該使用C語言編寫代碼,該代碼使用Vigenere Cipher加密消息。 而我做到了。 但是問題是我一直在緩沖區溢出。
如果我使用短字符串,例如“ Meet”,它可以正常工作。 但是,如果我使用更長的字符串,例如“上午11點在公園見我”,則會出現緩沖區溢出。
如果我使用strcpy()
將傳入argv[1]
的密鑰復制到另一個變量(比如說k
),並且將原始消息( msg
) encMsg
到加密消息的變量( encMsg
),那么它將擦除我擁有的內容。 k
。 如果再次使用strcpy()
將argv[1]
的值復制到k
一次,則在encMsg
連接兩個字符串時會出現緩沖區溢出。
如果我使用strccpy()
,它將不會刪除k的內容,但是它將溢出並連接encMsg
上的兩個字符串。
當我使用GetSting()
(來自cs50.h)時,所有這些都會發生;
如果我使用fgets()
,那么我將在msg的末尾得到'\\ n',然后必須添加if,以在'\\ n'所在的位置放置'\\ 0',這解決了我的問題,但是我想要知道是否有人可以解釋我為什么會發生所有這一切。
這是我的代碼:
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#include <string.h>
int main(int argc, char *argv[])
{
if (argc != 2) //Checks if number of command-line arguments is valid
{
printf ("usage: ./caesar + key \n");
return 1;
}
char k[strlen(argv[1])];
//strcpy(k, argv[1]); //Saves argument into a string
strncpy(k, argv[1], strlen(argv[1]));
for (int x = 0; x < strlen(k); x++)
{
if (k[x] < 65 || (k[x] > 90 && k[x] < 97) || k[x] > 122) //Checks if there is any non-alphabetical character in key
{
printf ("key must contain only alphabetical characters \n");
return 1;
}
}
//printf("Inform the message you want to encrypt: \n");
string msg = GetString();
//char msg[255];
//fgets(msg, 255, stdin);
char encMsg[strlen(msg)];
//strcpy(encMsg, msg);
strncpy(encMsg, msg, strlen(msg));
//strcpy(k, argv[1]);
int y = 0;
for (int x = 0; x < strlen(msg); x++)
{
//if(msg[x] == '\n') msg[x] = '\0';
if (msg[x] < 65 || (msg[x] > 90 && msg[x] < 97) || msg[x] > 122) encMsg[x] = msg[x];
else if ((msg[x] + (k[y] - 97 ) > 90 && msg[x] + (k[y] - 97 ) < 97) || msg[x] + (k[y] - 97 ) > 122)
{
encMsg[x] = msg[x] + (k[y] - 97) - 26;
y++;
}
else
{
encMsg[x] = msg[x] + (k[y] - 97);
y++;
}
if (y >= strlen(k)) y = 0;
}
printf("key = %s\n", k);
printf("msg = %s\n", msg);
printf("encMsg = %s\n", encMsg);
return 0;
}
這種代碼風格:
char k[strlen(argv[1])];
不留空格來終止'\\0
'字符。 它應該是
char k[strlen(argv[1]) + 1 ];
正如注釋中指出的那樣,
strncpy(k, argv[1], strlen(argv[1]));
將無法正確終止目標字符串。 按照strncpy()
的標准 :
如果
s2
指向的數組是短於n
個字節的字符串,則NUL字符應附加到s1
指向的數組的副本中,直到總共寫入n
個字節。
由於目標串不小於短n
,只有非NUL
作為有源串中的字節被復制n
它們。
正確的代碼可能是
strncpy(k, argv[1], 1 + strlen(argv[1]));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.