sprintf kapselung



  • itman schrieb:

    kein Standard ist

    kein ANSI 89 Standard aber ist C99 standard.

    Wenn du mich zitierst, dann tu es gefälligst ordentlich! 😡



  • Sovok schrieb:

    ich hab die funktion jedenfalls ned

    Dann hast du nen alten Compiler.

    Jetzt wirds problematisch. Du könntest zB die einzelnen größen händisch berechnen 😉 aber das ist wohl nicht so ganz das wahre...

    Ich würde es einfach lassen... die Funktion Format (oder wie auch immer) soll die benötigte größe als Param übergeben bekommen - das ist sicher genug. denn dann liegt es am Programmierer das Ding sicher zu machen (und es ist nicht so arsch lahm wie eine for-schleife mit dauerndem realloc)



  • Shade Of Mine schrieb:

    @itman:
    ich kapier deinen Code zwar nicht, aber er leaked speicher. Insofern würde ich das funktionierend lieber in Hochkommas setzen 😉

    Das folgender ist besser, keine "memory leaks". Der Code ist einfach.
    vsnprintf gibt die char-Anzahl zuerueck. wenn diese Anzahl = Speicher kapazitet denn
    ist es moeglich dass kapazitet ist zu wenig ist. Denn brauchen wir mehr Speicher zu reservieren.

    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <stdarg.h>
    
    using namespace std;
    
    string
    Format (const char * fmtspec, ...)
    {
        va_list     ap;
        string      s;
    
        va_start (ap, fmtspec);
        char * buf = NULL;
        for (unsigned int initLen = strlen (fmtspec) + 1;;initLen = initLen * 2 + 1) {
            delete [] buf;
            buf = new char [initLen + 1];
            buf [initLen] = 0;
            unsigned int res = vsnprintf (buf, initLen, fmtspec, ap);
             if (res < initLen) {
                s = buf;
                delete [] buf;
                va_end (ap);
                return s;
            }
        }
    }
    


  • Shade Of Mine schrieb:

    Sovok schrieb:

    ich hab die funktion jedenfalls ned

    Ich würde es einfach lassen... die Funktion Format (oder wie auch immer) soll die benötigte größe als Param übergeben bekommen - das ist sicher genug. denn dann liegt es am Programmierer das Ding sicher zu machen (und es ist nicht so ***** lahm wie eine for-schleife mit dauerndem realloc)

    Die benoetigte grosse kann Man im vorauss nicht immer weissen 🙂



  • itman schrieb:

    Das folgender ist besser, keine "memory leaks".

    dafür immer noch mies...

    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <stdarg.h>
    
    using namespace std;
    
    string
    Format (const char * fmtspec, ...)
    {
        va_list     ap;
        string      s; //warum hier definieren??
    
        va_start (ap, fmtspec);
        va_end (ap);
        char * buf = NULL;
        //das strlen() ist mies. warum nicht gleich strlen()+50% oder uU 100% ?
        for (unsigned int initLen = strlen (fmtspec) + 1;;initLen = initLen * 2 + 1) {   //warum überall diese +1 ? das verwirrt mich...
            delete [] buf;
            buf = new char [initLen + 1];
            //warum nicht realloc?
            buf [initLen] = 0; //warum?
            unsigned int res = vsnprintf (buf, initLen, fmtspec, ap);
            if (res < initLen) { //was ist wenn res==initLen ?
                s = buf;
                delete [] buf;
                return s;
            }
        }
    }
    

    Die benoetigte grosse kann Man im vorauss nicht immer weissen

    Ich weiss sie schon.
    Ausnahme: Input von extern.
    hier tut mir ein strlen() aber nicht weh... Und schon kenn ich die größe wieder...

    ah, das ist auch so schön effizient



  • Shade Of Mine schrieb:

    itman schrieb:

    Das folgender ist besser, keine "memory leaks".

    dafür immer noch mies...

    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <stdarg.h>
    
    using namespace std;
    
    string
    Format (const char * fmtspec, ...)
    {
        va_list     ap;
        string      s; //warum hier definieren??    
        // warum nicht ?
    
        va_start (ap, fmtspec);
        va_end (ap);
        char * buf = NULL;
        //das strlen() ist mies. warum nicht gleich strlen()+50% oder uU 100% ?
       // ist nur die "erste" Grosse, Bewertung
        for (unsigned int initLen = strlen (fmtspec) + 1;;initLen = initLen * 2 + 1) {   //warum überall diese +1 ? das verwirrt mich...
      // kann initLen * 2 sein
            delete [] buf;
            buf = new char [initLen + 1];
            //warum nicht realloc?
           // wir sprechen ueber C++ oder ?
            buf [initLen] = 0; //warum?
            // das ist mein Fehler kann Man dass weg lassen :)
            unsigned int res = vsnprintf (buf, initLen, fmtspec, ap);
            if (res < initLen) { //was ist wenn res==initLen ? 
            // res ist die Anzhal ohne '\0 denn muss mann 
            // unsigned int res = vsnprintf (buf, initLen + 1, fmtspec, ap);
           // schreiben
                s = buf;
                delete [] buf;
                return s;
            }
        }
    }
    

    Die benoetigte grosse kann Man im vorauss nicht immer weissen

    Ich weiss sie schon.
    Ausnahme: Input von extern.
    hier tut mir ein strlen() aber nicht weh... Und schon kenn ich die größe wieder...

    ah, das ist auch so schön effizient

    Und dass ist nur ein 5-sec Beispiel, es ist gar nicht ideal



  • Shade Of Mine schrieb:

    itman schrieb:

    Das folgender ist besser, keine "memory

    Die benoetigte grosse kann Man im vorauss nicht immer weissen

    Ich weiss sie schon.
    Ausnahme: Input von extern.
    hier tut mir ein strlen() aber nicht weh... Und schon kenn ich die größe wieder...

    ah, das ist auch so schön effizient

    Und gar keine einzige Ausnahme!!!
    z.B

    sprintf(buf, "%f", val)
    

    wass ist buf groesse? du kannst die maximale groesse berechnen, aber wenn du damit ein Feheler machst ist der Code kaput - buffer overflow.



  • itman schrieb:

    wass ist buf groesse? du kannst die maximale groesse berechnen, aber wenn du damit ein Feheler machst ist der Code kaput - buffer overflow.

    Ich bin ja nicht dumm. Mich interessiert ein float doch nicht auf 100 Stellen (wo er sowieso nicht genau ist) mich interessieren nur bestimmte, signifikante Stellen. Und die gebe ich aus. Da kann ich sehr wohl genau wissen wie groß das maximal wird.

    Und wenn ich zu dumm zum addieren bin dann kann ich nix anderes machen als meinen Beruf an den Nagel hängen.

    die n-Funktionen haben durchaus ihren Sinn, aber eben nur dann wenn ich mit Werten arbeite über die ich nix weiss (also sie von extern erhalten habe).

    Wenn es zu einem Bufferoverflow kommt, auch wenn es durch snprintf, strncpy, etc. 'gesichert' ist - so ist es IMHO ein Fehler. Denn dann versuche ich mehr in den Buffer reinzuschreiben als geht. Und das sollte eigentlich nicht passieren...



  • Shade Of Mine schrieb:

    itman schrieb:

    wass ist buf groesse? du kannst die maximale groesse berechnen, aber wenn du damit ein Feheler machst ist der Code kaput - buffer overflow.

    Ich bin ja nicht dumm. Mich interessiert ein float doch nicht auf 100 Stellen (wo er sowieso nicht genau ist) mich interessieren nur bestimmte, signifikante Stellen. Und die gebe ich aus. Da kann ich sehr wohl genau wissen wie groß das maximal wird.

    Und wenn ich zu dumm zum addieren bin dann kann ich nix anderes machen als meinen Beruf an den Nagel hängen.

    Es gibt viele Security-Meldungen ueber den Programmen die mit solchen Gedanken geschrieben werden. Und sie jetzt unsicher. Dabei, ich sah kein Programmierer, wer mit dem Addieren keine Fehelr macht. Du bist sehr wahrscheinlich keine Ausnahme. Dabei, kann dein Kode beim anderen Programmierer benutzt und/oder umgeschrieben werden. Und dieser Programmierer (oder sogar du) kann double durch long double ersetzen und dann kann dein Kode manchmal Kaput sein.

    Wenn es zu einem Bufferoverflow kommt, auch wenn es durch snprintf, strncpy, etc. 'gesichert' ist - so ist es IMHO ein Fehler. Denn dann versuche ich mehr in den Buffer reinzuschreiben als geht. Und das sollte eigentlich nicht passieren...

    Und gibt es die Programmen ohne Feheler? Und ein Feheler, IMHO ist fast immer besser als SEG FAULT.



  • itman schrieb:

    Dabei, kann dein Kode beim anderen Programmierer benutzt und/oder umgeschrieben werden. Und dieser Programmierer (oder sogar du) kann double durch long double ersetzen und dann kann dein Kode manchmal Kaput sein.

    In der Tat, denn dann muss ich %f in %lf ändern, und wenn ich das vergesse ist es ein Fehler.

    Aber es ändert doch nix daran, dass ich die Nachkommastellen beschränke.

    Und gibt es die Programmen ohne Feheler? Und ein Feheler, IMHO ist fast immer besser als SEG FAULT.

    Naja... Ob ich jetzt Blödsinn ausgebe - das Programm also 'kaputt' ist und der User sich darauf verlässt, dass es funktioniert - ist das schon ein großes Problem.

    Dagegen ist ein SEG FAULT total leicht zu finden, da ich sofort weiss, dass es einen Fehler gibt.

    Ich sage ja nicht, dass die n-Funktionen sinnlos sind, aber sie sind noch lange kein garant für Fehlerfreiheit. Und oft sind sie unnötig. Weil ich eben oft bzw. meistens selber weiss wie groß die Variablen sind - da kann man selbst beim addieren nix falsch machen.

    Um dich noch mehr zu schocken: ich verwende zB sogar fast nie strcpy - da ich meistens memcpy vorziehe. Und strcat verwende ich nie.

    Und selbst wenn ich strncpy verwende, kann ich nicht sichersein, dass der code fehlerfrei ist:

    void copy(char* buffer, size_t len)
    {
      strncpy(buffer, "Hallo wie geht es dir!", len);
      buffer[len-1]=0;
    }
    
    char* buf=new char[2];
    copy(buf, sizeof(buf));
    

    und schon machts PENG.
    Nur weil ich strncpy verwendet habe, bin ich noch lange nicht auf der sicheren seite.


Anmelden zum Antworten