【发布时间】:2016-04-04 18:30:38
【问题描述】:
我有一个简单的函数来处理 C websocket 程序中 Sec-WebSocket-Key 值的解析和散列。我让整个程序正常工作,但发现我有一堆 char* 没有指向的静态位置。正如您可能已经猜到的那样,这会导致一些内存问题并且需要修复。为了解决这个问题,我制作了大小为 100 的 char 并将 char* 指向它们。现在我从函数中返回的值不正确。有人可以告诉我我做错了什么。据我了解,这应该有效。仅供参考,我是自学成才的,但我对 C 的理解仍然存在巨大差距。
char* sock_handle_hash(struct sock_data *sockdat, int dataCount) {
char EncodeHashbuff[100];
char key1buff[100];
char key2buff[100];
char key3buff[100];
char *EncodeHash = EncodeHashbuff;
char *key1 = key1buff;
char *key2 = key2buff;
char *key3 = key3buff;
unsigned char hash[SHA_DIGEST_LENGTH]; // this sets the length to the predefigned length in the SHA standard
char *testKey = "Sec-WebSocket-Key"; // this is the key for the key value pair of the hash
char *additionalHashData = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // the magic string used in websockets
sockdat->buffer[dataCount] = '\0'; // null terminate the buffer
key1 = strtok(sockdat->buffer, "\n"); // brake up the data by new lines
key1 = strtok(NULL, "\n"); // skip the first line
while (key2 != NULL) { //find the key to hash
key2 = strtok(NULL, ":"); //brake data into the key value pairs
key3 = strtok(NULL, "\n"); // go to next line
if(strcmp(key2, testKey) == 0) { // if the correct key
if( key3[(strlen(key3)-1)] =='\r'){
key3[(strlen(key3)-1)]='\0';
}
key3++;
char key4[200];
strcpy(key4, key3); // copy the string to the final key
strcat(key4, additionalHashData); // concat the magic websocket hash string
SHA1(key4, strlen(key4), hash); //Hash SHA1 to the correct reply value
EncodeHash = apssock_base64(hash, sizeof hash); // base 64 encode the value
break; //Stop looping
}
}
return EncodeHash; //success retrun the hashed value for the handshake
}
【问题讨论】:
-
什么是“大小为 100 的字符”?你的意思是
char [100],即。char的数组?并查看How to Ask。 -
return EncodeHash;也可以是return EncodeHashbuff;,它返回函数范围内即将到期的自动变量的地址。因此,当调用者使用返回的地址时,未定义的行为。 Read this answer仔细。 -
仅供参考,除非
EncodeHash = apssock_base64(hash, sizeof hash);动态分配生成的 base64 编码,我们从发布的代码中不知道,否则该代码路径同样会遭受类似的命运。如果它执行 dyna-alloc,它可能工作(至少它不会调用上面提到的 UB)。 -
谢谢 WhozCraig。这是一个非常有用的链接。仍然在解决这个问题。