sprintf kapselung
-
@itman is kein ansi
-
*****
-
itman schrieb:
vsprint und printf sind unsicher!
es ist immer besser snprintf und vsnprint zu benutzen!Blödsinn:
void something(char const* str) { size_t len=strlen(str); char* buffer=new char[4+len+1]; for(int i=0; i<10; ++i) { sprintf(buffer, "%d. %s", i+1, str); someotherthing(str); } }
Wo brauche ich da bitte snprintf? sprintf tut es genauso, nur besser.
-
@itman is kein ansi
aber Posix oder Unix98 compatible. Und WinXXX compatibel dabei.
-
[quote]
Wo brauche ich da bitte snprintf? sprintf tut es genauso, nur besser.
[quote]
"buffer overflow" zu vermeiden.
-
itman schrieb:
und hier ist ein arbeitender Beispiel:
#include <iostream> #include <string> #include <stdio.h> #include <stdarg.h> using namespace std; string Format (const char * fmtspec, ...) { va_list ap; va_start (ap, fmtspec); va_end (ap); 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) { return string (buf); } } } int main (void) { string s = Format ("Big test %d %4.2f", 23, 44.533); cout << s<<endl; }
-
-
itman schrieb:
Wo brauche ich da bitte snprintf? sprintf tut es genauso, nur besser.
"buffer overflow" zu vermeiden.
wo ist da ein potentieller Bufferoverflow?
Ich muss nur auf Usereingaben acht geben - beim rest kenne ich die größen meiner Strings...
-
kein Standard ist
kein ANSI 89 Standard aber ist C99 standard.
-
@itman:
ich kapier deinen Code zwar nicht, aber er leaked speicher. Insofern würde ich das funktionierend lieber in Hochkommas setzen
-
ich hab die funktion jedenfalls ned
-
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 setzenDas 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.Bsprintf(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.