04. september 2000 - 09:57Der er
6 kommentarer og 1 løsning
CGI - QueryString dekodning 2
Så er jeg her igen!
Jeg har nu fået noget kode til dekodning af GueryString, fra Thue, og har forsøgt, at tilføje en funktion til dekodning af specialtegn fra denne. Den virker bare ikke!
Her er koden : (funktionen er imellem \"|-----Indsat af Emil|-----\" og \"|-----Indsat af Emil slut|-----\")
TPairList(); void NewPair(char*, char*); //startes fra TParser og modtager char* GetValue(char*); //Name og Value fra TParser, til //initaialisering af nyt TPair. };
//TPairlist methods
TPairList::TPairList(){ First = NULL; //kommer til at pege på par 1. }
char* TPairList::GetValue(char* aName){ int Flag = 1; //sat til sandt TPair* hjelpepeger = First;
while(Flag){ if(First == NULL){ return NULL; }else{ if(strcmp(First -> Name, aName) == 0){ return First -> Value; }else{ if(hjelpepeger -> Next != NULL){ if(strcmp(hjelpepeger -> Next -> Name, aName) == 0){ return hjelpepeger -> Next -> Value; }else{ hjelpepeger = hjelpepeger -> Next; //ryk en frem }
}else{ char* error=\"Navnet kunne ikke findes ... \"; printf(\"\\nSøgt navneværdi: %s\\n\",aName); return error; }
}
} //slut yderste else } //slut while - løkke }
void TPairList::NewPair(char* aName, char* aValue){ int True = 1; int False = 0; if(First == NULL)First = new TPair(aName, aValue); else{ TPair* hjelpepeger = First; while(True){ if(hjelpepeger -> Next == NULL){ hjelpepeger -> Next = new TPair(aName, aValue); True = False; //stop løkke }else hjelpepeger = hjelpepeger -> Next; //ryk én frem } } }
class TParser{ private: char* Query; //Peger på starten af QUERYSTRING char* Method; int Length; //længden af Query char* Source; //Source rykker frem gennem Query char* Name; //Name og Value sendes til Liste char* Value;
public: TPairList* PairList; TParser(); //Konstruktøren indlæser \"QUERY_STRING\" char* GetValue(char*); //sender forespørgsel til Pairlist void InsertSpaces(); TPairList* Parse(); //Parser og returnerer liste };
TPairList* TParser::Parse(){ InsertSpaces(); char aName[MAXARRAY]; char aValue[MAXARRAY]; int Kontakt = 1; //0 for \'=\', 1 for \'&\' int Count_Name = 0; int Count_Value = 0;
for(int a=0;a <= Length;a++){ if(Query == NULL){ printf(\"CGI - HTML fejl : Forespørgselen er tom\\n\"); break; }else{ switch(Query[a]){ case \'\\0\': //opret sidste par her ! aValue[Count_Value] = \'\\0\'; //case: kun et par ialt ! Name = aName; //adressen på array Value = aValue; PairList -> NewPair(Name, Value); a = a + Length; //kør over MAX i for - løkke break; //ikke flere par
case \'=\': aName[Count_Name] = \'\\0\'; Count_Name = 0; //initialiser igen Count_Value = 0; Kontakt = 0; break;
case \'&\':; Kontakt = 1; aValue[Count_Value] = \'\\0\';
Name = aName; Value = aValue;
PairList -> NewPair(Name, Value);
Count_Name = 0; //initialiser igen Count_Value = 0;
Bortset fra nogle manglende initialiseringer af et par af variablerne, en formodet stavefejl af strcpy og *S* manglende kommentarer kan jeg ikke lige se hvad der er galt. Men det ville hjælpe hvis du skrev hvilke fejl du fik. Jeg er med på du løber strengen igennem og kopierer efterhånden til Resultat. Hvis du møder et \'%\' så vil du dekode. Men hvorfor køre 2 whileløkker ? hvad er det du gør i den første andet end at tælle x lidt ekstra op hvis du finder \'%\'. Meget muligt jeg har overset noget, men skriv et par kommentarer og fejlmeddelelser så hjlæper det nok. :-)
Glad for at du kunne bruge koden. M.V.H Thue Tuxen
Den run-time fejl jeg får, er en fejl fra windows, som lydder:
____________________________________________________________ |CGI.exe - Programfejl x| |------------------------------------------------------------| | | | X Instruktionen ved \"0x00402814\" refererede hukommelse | | ved \"0x00000032\". Hukommelsen kunne ikke \"read\". | | | | Klik på Ok for at afslutte programmet | | Klik på Annuler for at udføre fejlfinding i | | programmet | | ________ __________ | | | OK | | Annuller | | | -------- ---------- | |____________________________________________________________|
Her er den forbandede funktion igen - denne gang bedre kommenteret. Jeg kikkede på \'strcpy()\' funktionen, og den kopierer jo hele strengen, hvorimod \'strncpy()\' kun kopierer det antal tegn, som er angivet i tredie parameter til denne.
//Variabelforklaring // //Kilde : Strengen, der skal dekodes //Resultat : Funktionens returverdi (den dekodede streng) //Hex : En streng, der bruges til at holde specialtegnenes hex koder //Len : Længden af \'Kilde\' //x : Tæller, der bruges til at løbe \'Kilde\' igennem //y : Tæller, der bruges til at løbe \'Resultat\' igennem
char *DekodCGITegn(char *Kilde){ char *Resultat, *Hex; int Len=strlen(Kilde), x=0,y=0; while(x<=Len){ //Start while løkke til optælling switch(Kilde[x]){ //af antallet af tegn i \'Resultat\' case \'%\': //(\'y\') x = x + 3; //Spring % tegnet og Hex koden y++; //over. break; default: y++; x++; } } Resultat=(char*)calloc(y,sizeof(char)); //Brug \'y\' til at afsætte den plads y=0; //der skal bruges i \'Resultat\', x=0; //samp nulstilling af \'x\' og \'y\'. while(x<=Len){ //Start while løkke til dekodning switch(Kilde[x]){ //og kopiering over i \'Resultat\'. case \'%\': Hex=strncpy( Hex, ((char *)Kilde[x + 1]), 2); //Kopier Hex koden Resultat[y] = (char)strtol( Hex, NULL, 16); //Dekod hex koden x = x + 3; //Spring % tegnet og Hex koden y++; //over. break; default: Resultat[y]=Kilde[x]; //Kopier alt andet. y++; x++; } } return Resultat; //Finito }
jeg ved sgu ikke umiddelbart hvad der går galt, men den fejl du får tyder på at du prøver at pege et sted i et adresseområde du ikke må pege i. D.v.s At fejlen rimeligt sikkert er et overflow et eller andet sted. Er du helt sikker på at du får talt alting korrekt ? Bedre svar har jeg desværre ikke lige nu og jeg har ikke tid til at afprøve din funktion, ved selvsyn. Hilsen Thue
Jeg fandt fejlen! Variablen \'char* Hex;\' skule initialisseres, før den kunne bruges i funktionen \'strncpy();\'. Tak for den tid du brugte på at kikke på mit spørgsmål!
TPairList(); void NewPair(char*, char*); //startes fra TParser og modtager char* GetValue(char*); //Name og Value fra TParser, til //initaialisering af nyt TPair. };
//TPairlist methods
TPairList::TPairList(){ First = NULL; //kommer til at pege på par 1. }
char* TPairList::GetValue(char* aName){ int Flag = 1; //sat til sandt TPair* hjelpepeger = First;
while(Flag){ if(First == NULL){ return NULL; }else{ if(strcmp(First -> Name, aName) == 0){ return First -> Value; }else{ if(hjelpepeger -> Next != NULL){ if(strcmp(hjelpepeger -> Next -> Name, aName) == 0){ return hjelpepeger -> Next -> Value; }else{ hjelpepeger = hjelpepeger -> Next; //ryk en frem }
}else{ char* error=\"Navnet kunne ikke findes ... \"; printf(\"\\nSøgt navneværdi: %s\\n\",aName); return error; }
}
} //slut yderste else } //slut while - løkke }
void TPairList::NewPair(char* aName, char* aValue){ int True = 1; int False = 0; if(First == NULL)First = new TPair(aName, aValue); else{ TPair* hjelpepeger = First; while(True){ if(hjelpepeger -> Next == NULL){ hjelpepeger -> Next = new TPair(aName, aValue); True = False; //stop løkke }else hjelpepeger = hjelpepeger -> Next; //ryk én frem } } }
class TParser{ private: char* Query; //Peger på starten af QUERYSTRING char* Method; int Length; //længden af Query char* Source; //Source rykker frem gennem Query char* Name; //Name og Value sendes til Liste char* Value;
public: TPairList* PairList; TParser(); //Konstruktøren indlæser \"QUERY_STRING\" char* GetValue(char*); //sender forespørgsel til Pairlist void InsertSpaces(); TPairList* Parse(); //Parser og returnerer liste };
TPairList* TParser::Parse(){ InsertSpaces(); char aName[MAXARRAY]; char aValue[MAXARRAY]; int Kontakt = 1; //0 for \'=\', 1 for \'&\' int Count_Name = 0; int Count_Value = 0;
for(int a=0;a <= Length;a++){ if(Query == NULL){ printf(\"CGI - HTML fejl : Forespørgselen er tom\\n\"); break; }else{ switch(Query[a]){ case \'\\0\': //opret sidste par her ! aValue[Count_Value] = \'\\0\'; //case: kun et par ialt ! Name = aName; //adressen på array Value = aValue; PairList -> NewPair(Name, Value); a = a + Length; //kør over MAX i for - løkke break; //ikke flere par
case \'=\': aName[Count_Name] = \'\\0\'; Count_Name = 0; //initialiser igen Count_Value = 0; Kontakt = 0; break;
case \'&\':; Kontakt = 1; aValue[Count_Value] = \'\\0\';
Name = aName; Value = aValue;
PairList -> NewPair(Name, Value);
Count_Name = 0; //initialiser igen Count_Value = 0;
return PairList; //send listen med pair´s til main
} //end Funktion
//--------------------------|Indsat af Emil|-----------------------------------
//Variabelforklaring // //Kilde : Strengen, der skal dekodes //Resultat : Funktionens returverdi (den dekodede streng) //Hex : En streng, der bruges til at holde specialtegnenes hex koder //Len : Længden af \'Kilde\' //x : Tæller, der bruges til at løbe \'Kilde\' igennem //y : Tæller, der bruges til at løbe \'Resultat\' igennem
char *DekodCGITegn(char *Kilde){ char *Resultat, *Hex; int Len=strlen(Kilde), KildeCount=0,ResCount=0; while(KildeCount<=Len){ //Start while løkke til optælling switch(Kilde[KildeCount]){ //af antallet af tegn i \'Resultat\' case \'%\': //(\'y\') KildeCount+=3; //Spring % tegnet og Hex koden ResCount++; //over. break; default: ResCount++; KildeCount++; } } Resultat=(char*)calloc(ResCount,sizeof(char)); //Brug \'y\' til at afsætte den plads ResCount=0; //der skal bruges i \'Resultat\', KildeCount=0; //samp nulstilling af \'x\' og \'y\'. while(KildeCount<=Len){ //Start while løkke til dekodning switch(Kilde[KildeCount]){ //og kopiering over i \'Resultat\'. case \'%\': Hex=(char*)calloc(2,sizeof(char)); //Initialisser \'Hex\' //VIGTIGT! strncpy( Hex, &Kilde[KildeCount + 1], 2); //Kopier Hex koden Resultat[ResCount] = (char)strtol( Hex, NULL, 16); //Dekod hex koden KildeCount += 3; //Spring % tegnet og ResCount++; //Hex koden over. break; default: Resultat[ResCount]=Kilde[KildeCount]; //Kopier alt andet. ResCount++; KildeCount++; } } return Resultat; //Finito }
//-----------------------|Indsat af Emil - slut|-----------------------------------
//END
void main(){ TPairList* List; //oprettelse af instanser TParser* Parser = new TParser(); List = Parser -> Parse(); //parse og returnér liste
printf(\"content-type: text/html\\n\\n\"); //START output til Browseren printf(\"<html><head></head><body>\"); printf(\"<font size=5 face=\\\"Verdana\\\"><strong>Opgaven lyder :</strong></font><hr>%s<hr>\",List->GetValue(\"opgave\")); printf(\"<font size=5 face=\\\"Verdana\\\"><strong>Den skal udføres med dataerne :</strong></font><hr>%s<hr>\",List->GetValue(\"data\")); printf(\"<font size=5>Dataerne kan også dekodes :</font><hr>%s<hr>\",DekodCGITegn(List->GetValue(\"data\"))); printf(\"</body></html>\"); //END output }
Glad for at kunne hjælpe held og lykke med opgaven. Thue
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.