2010-10-12 629 views
2

C文件:GETENV(QUERY_STRING)用C CGI

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char* argv[]) 
{ 
    FILE *ptr; 
    char m[200]; 
    char *data = malloc(200); 
    data=getenv("QUERY_STRING"); 
    sscanf(data,"%s", m); 
    printf("%s", m); 
    ptr=fopen("c:/test.txt", "w"); 
    fprintf(ptr, "%s", m); 
    fclose(ptr); 
    return 0; 
} 

// GCC -g print.c -o print.exe

HTML文件:

<html> 
    <body> 
    <h2>CGI Server</h2> 
    <p> 
     <form action="http://localhost/cgi-bin/print.exe"> 
    <div><label>value: <input name="m" size="10"></label></div> 
    <div><input type="submit" value="Run"></div> 
     </form> 
    </p> 
    </body> 
</html> 

如果輸入進入網頁形式是c:/data.txt然後結果是:c%3A%2Fdata.txt

發生了什麼事?爲什麼輸出中的/和:損壞?看起來問題在於QUERY_STRING,因爲getenv(「PATH」)不存在這個問題。

+2

我不是C期望,但我確定有已有的CGI和表單數據解析庫。這是一個比看起來更復雜的領域,所以請不要重新發明輪子! – Quentin 2010-10-12 23:21:27

回答

4

「問題」是由URL-encoding造成的。您需要對從QUERY_STRING獲取的值進行URL解碼。

+0

就像@nategoose說的那樣,「破壞」是在你的服務器收到它之前由瀏覽器完成的。 (檢查訪問日誌,你會看到。) – LarsH 2010-10-12 22:42:45

1

%3A類型的東西是可能是特殊的字符的HTTP十六進制編碼。它就像在C字符串中轉義引號字符一樣。 "\""

PATH環境變量與HTTP無關,所以不受影響。您的Web服務器程序將QUERY_STRING設置爲Web瀏覽器發送的內容,其中包含%十六進制編碼。

6
char *data = malloc(200); 
    data=getenv("QUERY_STRING"); 

此處存在內存泄漏。你正在分配200個字節,你永遠不會使用或能夠free()。 (或不爲malloc()可能失敗並返回NULL。)

char m[200]; 
    sscanf(data,"%s", m); 

這是strcpy()/strncpy()粗更換。如果查詢字符串長度超過200個字符,則會導致緩衝區溢出。當它找到一個空白時也會終止,但這不是問題,因爲在URL編碼期間,它們被轉換爲+%20

ptr=fopen("c:/test.txt", "w"); 
    fprintf(ptr, "%s", m); 

fopen()可能失敗,導​​致NULL返回值。

我建議你檢查指針和內存分配,查找除printf/scanf以外的一些字符串操作函數,並養成檢查錯誤的習慣,即防禦性編碼。即使在小的,示例質量的代碼中。