2010-10-12 11 views
2

fichier C:getenv (QUERY_STRING) en 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

fichier 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> 

Si l'entrée dans le formulaire de la page Web est c: /data.txt puis le résultat est: c% 3A% 2Fdata.txt

Que s'est-il passé? Pourquoi le/et le: endommagé dans la sortie? il semble que le problème est avec QUERY_STRING car getenv ("PATH") ne présente pas ce problème.

+2

Je ne suis pas un C s'attendre, mais je suis sûr qu'il existe des bibliothèques préexistantes pour CGI et l'analyse des données de formulaire. C'est un domaine qui est plus compliqué qu'il n'y paraît, alors ne réinventez pas la roue! – Quentin

Répondre

4

Le "problème" est dû à URL-encoding. Vous devrez décoder l'URL de la valeur obtenue dans QUERY_STRING.

+0

Comme @nategoose dit, le "dommage" a été fait par le navigateur avant que votre serveur ne le reçoive. (Vérifiez les journaux d'accès et vous verrez.) – LarsH

1

Le type %3A est le codage hexadécimal HTTP des caractères qui peuvent être spéciaux. C'est comme échapper le caractère de citation dans une chaîne de caractères. La variable d'environnement PATH n'a rien à voir avec HTTP, elle n'est donc pas affectée. Votre programme de serveur Web définit QUERY_STRING sur ce que le navigateur Web a envoyé, avec l'encodage% hexadécimal.

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

Une fuite de mémoire se produit ici. Vous allouez 200 octets que vous n'utiliserez jamais ou que vous pourrez utiliser free(). (Ou pas, pour malloc() peut échouer et retourner NULL.)

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

Ceci est un remplacement brut pour strcpy()/strncpy(). Résultats dans un débordement de tampon si la chaîne de requête a plus de 200 caractères. Se termine également dès qu'il trouve un espace, mais ce n'est pas un problème car ils ont été tournés vers + ou %20 pendant le codage de l'URL.

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

fopen() peut échouer, entraînant une valeur de retour de NULL. Je suggère que vous passiez en revue les pointeurs et l'allocation de mémoire, que vous consultiez certaines fonctions de manipulation de chaînes autres que printf/scanf et que vous preniez l'habitude de vérifier les erreurs, c'est-à-dire de coder de manière défensive. Même dans un petit code de qualité d'exemple.