我需要编写一个函数,该函数将从HTTP 1.0中的Authorization Header中获取base64字符串。因此,我写了这个函数:
char* getAuthenticate(char* buffer) {
const char* AuthorizationLine = calloc(1, sizeof(char));
char* BasePtr;
char* CodePtr = calloc(1, sizeof(char));
//Get Authoriztaion Header
if(strstr(buffer, "Authorization: ") != NULL) {
AuthorizationLine = strstr(buffer, "Authorization: ");
char Copy[strlen(AuthorizationLine)];
strcpy(Copy, AuthorizationLine);
AuthorizationLine = strtok(Copy, "\r\n");
}
else {
printf("Error - no valid Authorization Header");
return NULL;
}
//Set CodePtr to the base64 String
CodePtr = strrchr(AuthorizationLine, " ");
CodePtr = CodePtr +1;
return CodePtr;
}
通过在调试器中运行此功能,我发现一切正常,直到进入CodePtr部分。一旦执行
CodePtr = strstr(AuthorizationLine, " ")
,我的授权行将被废话填充,例如“ \020Õÿÿÿ\ 177”。而且CodePtr
甚至没有受到影响:直到我执行0x0
之前,它的地址一直保持+1
,但是只有0x1
,并且Eclipse无法访问该地址的内存。那我做错了什么?我也尝试了
strstr()
,但是也没有用。 最佳答案
您的函数会泄漏内存。它为一个char
分配空间,并为变量AuthorizationLine
分配一个指向该空间的指针,但随后在不释放分配的内存的情况下为AuthorizationLine
分配了一个新值。您似乎不需要在这里分配任何内存。
您没有声明数组Copy
足够大。您还需要空间来容纳字符串终止符。因此,当您复制到该数组时,您将获得不确定的行为。
您将AuthorizationLine
设置为指向数组Copy
的一部分的指针,但是Copy
之后会立即超出范围,而使AuthorizationLine
无效的指针。strrchr()
(或strstr()
)很有可能随后用其局部变量的值覆盖AuthorizationLine
指向的任何内存(在堆栈中的某个位置)。 strrchr()
返回NULL指针,因为这是在找不到指定字符时执行的操作。
此外,您将指针(输入)返回到局部变量。当Copy
超出范围时,这会出现相同的问题。
更新:
这个版本可以解决问题。请注意,它返回指向已分配内存的指针,当不再需要调用者时,调用者必须将其释放。
char* getAuthenticate(char* buffer) {
/* Get Authoriztaion Header */
const char* AuthorizationLine = strstr(buffer, "Authorization: ");
if (AuthorizationLine) {
/* extract the authorization token */
char* EndPtr = strstr(AuthorizationLine, "\r\n");
char* CodePtr;
if (!EndPtr) {
/* the header is the last thing in the buffer */
EndPtr = AuthorizationLine + strlen(AuthorizationLine) - 1;
}
/* ignore trailing whitespace */
while (isspace(*EndPtr)) {
EndPtr -= 1;
}
/* find the start of the authorization token */
for (CodePtr = EndPtr; !isspace(*CodePtr); CodePtr -= 1 ) {
if (CodePtr == AuthorizationLine) {
printf("Error - invalid authorization header\n");
return NULL;
}
}
/* allocate space and copy the token into it */
ptrdiff_t value_length = ++EndPtr - CodePtr++;
char *Copy = malloc(value_length + 1);
if (Copy) {
strncpy(Copy, CodePtr, value_length);
Copy[value_length] = '\0';
} else {
printf("Error - memory allocation failure\n");
}
return Copy;
} else {
printf("Error - no Authorization Header\n");
return NULL;
}
}