Null-Character

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Hallo,


    mir ist eben aufgefallen, dass man in pawn garkeinen Null-Character am Ende braucht.


    new teststring[6];
    for(new i=0;i<6;i++)
    {
    teststring[i]='.';
    }
    print(teststring);
    printf("%i",strlen(teststring));
    printf("'%c'",teststring[5]);


    Serverlog:

    Code
    [21:42:38] ......
    [21:42:38] 6
    [21:42:38] '.'




    Stimmt das jetzt oder was habe ich übersehen?

  • Strings die du in Funktionen verwendest haben einen EOS.
    Welcher halt nur nicht gezählt wird.


    Du kannst aber, wenn du einen vollen Array als string verwenden willst einen Bufferoverflow auslösen

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski

  • Wo soll ich strings sonst verwenden, wenn nicht in "Funktionen"?


    Du meinst, es ist sicherer immer einen Array mehr zu definieren um in ihr den Null-Character bzw. EOS einzuspeichern,
    damit der zugesicherte Speicher für die Variable nicht überschritten werden und so Fehler auftreten, auch wenn
    es in diesem Beispiel einwandfrei funktioniert?

  • Wo soll ich strings sonst verwenden, wenn nicht in "Funktionen"?


    Ich meinte spezielle stringfunktionen aus der Stringlibrary


    Du meinst, es ist sicherer immer einen Array mehr zu definieren um in ihr den Null-Character bzw. EOS einzuspeichern,
    damit der zugesicherte Speicher für die Variable nicht überschritten werden und so Fehler auftreten, auch wenn
    es in diesem Beispiel einwandfrei funktioniert?


    print und printf sind abgesicherte Funktionen, die können keinen direkten Bufferoverflow auslösen,
    dafür ist die VM zu "intelligent".


    Bei anderen Funktionen kann es halt im schlimmsten Fall zum Absturz des Servers kommen

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski

  • mir ist eben aufgefallen, dass man in pawn garkeinen Null-Character am Ende braucht.
    ...
    Stimmt das jetzt oder was habe ich übersehen?

    Man braucht eine Null Endung. In Deinem Fall wurde der Code in der main() Methode ausgefuehrt?
    Das einfachste Test-Szenario, dass belegt, dass eine Null Endung notwendig ist sieht wie folgt aus:
    new eins[3];
    for(new i=0; i < 3; i++)eins[i] = '#';
    new teststring_zwei[6];
    for(new i=0; i < 6; i++)teststring_zwei[i] = '.';
    new drei[3];
    for(new i=0; i < 3; i++)drei[i] = '!';
    print(teststring_zwei);Das Ergebnis ist "......###", wenn es in main() ausgefuehrt wird.


    Alternativ kann man auch das von Dir gezeigte Beispiel nehmen und den Quelltext einfach in eine Funktion 'test' schieben, welche von main() aus aufgerufen wird. Da der Code nun nicht mehr in main() ausgefuehrt wird erhaelt man einen verfaelschten String.


    Hier eine etwas umfangreichere Version (des im ersten Post gezeigten Quelltextes), welcher die letzten ein, oder zwei, 'Buchstaben'/Werte ausgibt (die, die nicht angezeigt werden duerften, wenn tatsaechlich ein 'unsichtbarer Null-Character', oder sonstiger Schutzmechanismus vorhanden sein wuerde) :
    #include <a_samp>
    stock test(){
    new teststring[6];
    printf("'%c' (0x%x) '%c' (0x%x)",0x2020,0x2020,0x2020,0x2020);//Der 0te String. Ignoriert ihn.
    print("\n\tTest beginnt hier:");
    for(new i=0;i<6;i++)
    {
    teststring[i]='.';
    }
    printf("strlen: %i, teststring: %s",strlen(teststring),teststring);


    // Compiler weigert sich:
    //printf("'%c' (0x%x) '%c' (0x%x)",teststring[6],teststring[6],teststring[7],teststring[7]);
    // Deswegen das selbe in anders:
    #emit addr.pri 0xFFFFFFE8// teststring[7]
    #emit add.c 0x1C
    #emit push.pri
    #emit push.pri
    #emit addr.pri 0xFFFFFFE8// teststring[6]
    #emit add.c 0x18
    #emit push.pri
    #emit push.pri
    #emit push.c 0x0 // 0ter String
    #emit push.c 0x14
    #emit sysreq.c printf
    #emit stack 0x18
    }
    main(){test();}Beachte, dass in der Konsole ASCII Zeichen ausgegeben werden. Aus 0x2020 wird 0x20, welches dem Leerzeichen entspricht. Deswegen habe ich dort auch die Hexadezimale Ausgabe eingefuegt, um die korrekten Werte (ueber 255) anzuzeigen.
    Waehrend meiner Tests war die maximale Laenge 2 Zeichen laenger, als erwuenscht. Der Erste Wert war konstant (bei mehreren Aufrufen von test(), nach veraendern des Quelltextes und neuladen des Scripts kann sich die Variable aendern) und ist vermutlich die Instanz-Variable/Struktur der Pawn-Maschine. Der zweite Wert aendert sich bei jedem Aufruf der test() Funktion innerhalb von main(). Der dritte Wert war stetig entweder groesser als 255, oder exakt 0.

    Einmal editiert, zuletzt von SBIKA ()