Avatar billede emileej Nybegynder
04. september 2000 - 09:57 Der 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|-----\")




CGI.cpp------------------------------------

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

                                                //Deklaration af globale variable,
                                                //konstanter og andre strukturer.

const int MAXARRAY = 80;                        //Bruges i CGI delen.


                                                //
                                                //END
                                                //

class TPair{
    private:

    public:
    char Name[MAXARRAY];
    char Value[MAXARRAY];

    TPair* Next;

    TPair(char*, char*);
};

                                                //TPair methods

TPair::TPair(char* aName, char* aValue){
    strcpy(Name, aName);
    strcpy(Value, aValue);
    Next = NULL;
}


class TPairList{
    private:

    public:

    TPair* First;

    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
};

                                                //TParser methods

TParser::TParser(){
    PairList = new TPairList();

    Query  = getenv(\"QUERY_STRING\");
    Method = getenv(\"REQUEST_METHOD\");

    Length  = strlen(Query);                    //bruges i for - løkke
    Name    = NULL;
    Value  = NULL;
}


void TParser::InsertSpaces(){
    char* IndexPeger = Query;

    for(int a=0;a < Length;a++){
        if(IndexPeger[a] == \'+\')Query[a] = \' \';
    }
}


char* TParser::GetValue(char* aName){
    return PairList -> GetValue(aName);
}


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&oslash;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;

                break;

                default :
                    if(Kontakt == 1){
                        aName[Count_Name] = Query[a];
                        Count_Name++;
                    }else{
                        aValue[Count_Value] = Query[a];
                        Count_Value++;
                    }

                }

            }                                    //end else
    }                                            //end For

    return PairList;                            //send listen med pair´s til main

}                                                //end Funktion


//--------------------------|Indsat af Emil|-----------------------------------

char *DekodCGITegn(char *Kilde){
    char *Resultat, *Hex=\"\";
    int Len=strlen(Kilde), x=0,y=0;
    while(x<=Len){
        switch(Kilde[x]){
            case \'%\':
                x = x + 3;
                y++;
            break;
            default:
                y++;
                x++;
        }
    }
    Resultat=(char*)calloc(y,sizeof(char));
    y=0;
    x=0;
    while(x<=Len){
        switch(Kilde[x]){
            case \'%\':
                Hex=strncpy( Hex, ((char *)Kilde[x + 1]), 2);
                Resultat[y] = (char)strtol( Hex, NULL, 16);
                x = x + 3;
                y++;
            break;
            default:
                Resultat[y]=Kilde[x];
                y++;
                x++;
        }
    }
    return Resultat;
}

//-----------------------|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&oslash;res med dataerne :</strong></font><hr>%s<hr>\",List->GetValue(\"data\"));
    printf(\"<font size=5>Den skal dataerne kan ogs&aring; dekodes :</font><hr>%s<hr>\",DekodCGITegn(List->GetValue(\"data\")));
    printf(\"</body></html>\");                    //END output
}
Avatar billede tuxen Nybegynder
05. september 2000 - 10:02 #1
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
Avatar billede emileej Nybegynder
05. september 2000 - 12:48 #2
Hej Thue!

Tak for at du ville spilde din tid på at svare mig!

Jeg sidder i øjeblikket på mit gymnasium, og kan derfor ikke tjecke precis, hvad fejlmeddelelsen går ud på. Det er i hvert fald en run-time fejl.

mht. strncpy og strcpy, så er det ingen stavefejl. Jeg har bare aldrig brug strcpy funktionen - Det skal prøves!

mht. de to while løkker:
Den første bruges til, at finde ud af, hvor lang Resultat skal være, og x fra denne bruges i calloc funktionen.



Vender snarest tilbage
Emil
Avatar billede tuxen Nybegynder
05. september 2000 - 13:23 #3
Nå sådan :-)
Avatar billede emileej Nybegynder
06. september 2000 - 09:47 #4
Hej Thue!


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
}



Håber, at du ka\' finde ud af det for mig igen

Emil
Avatar billede tuxen Nybegynder
06. september 2000 - 11:10 #5
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
Avatar billede emileej Nybegynder
07. september 2000 - 08:59 #6
Hej 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!

Emil



Kildekoden:


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

                                                //Deklaration af globale variable,
                                                //konstanter og andre strukturer.

const int MAXARRAY = 80;                        //Bruges i CGI delen.
                                                //

class TPair{
    private:

    public:
    char Name[MAXARRAY];
    char Value[MAXARRAY];

    TPair* Next;

    TPair(char*, char*);
};

                                                //TPair methods

TPair::TPair(char* aName, char* aValue){
    strcpy(Name, aName);
    strcpy(Value, aValue);
    Next = NULL;
}


class TPairList{
    private:

    public:

    TPair* First;

    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
};

                                                //TParser methods

TParser::TParser(){
    PairList = new TPairList();

    Query  = getenv(\"QUERY_STRING\");
    Method = getenv(\"REQUEST_METHOD\");

    Length  = strlen(Query);                    //bruges i for - løkke
    Name    = NULL;
    Value  = NULL;
}


void TParser::InsertSpaces(){
    char* IndexPeger = Query;

    for(int a=0;a < Length;a++){
        if(IndexPeger[a] == \'+\')Query[a] = \' \';
    }
}


char* TParser::GetValue(char* aName){
    return PairList -> GetValue(aName);
}


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&oslash;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;

                break;

                default :
                    if(Kontakt == 1){
                        aName[Count_Name] = Query[a];
                        Count_Name++;
                    }else{
                        aValue[Count_Value] = Query[a];
                        Count_Value++;
                    }

                }

            }                                    //end else
    }                                            //end For

    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&oslash;res med dataerne :</strong></font><hr>%s<hr>\",List->GetValue(\"data\"));
    printf(\"<font size=5>Dataerne kan ogs&aring; dekodes :</font><hr>%s<hr>\",DekodCGITegn(List->GetValue(\"data\")));
    printf(\"</body></html>\");                    //END output
}
Avatar billede tuxen Nybegynder
07. september 2000 - 09:26 #7
Glad for at kunne hjælpe held og lykke med opgaven.
Thue
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester