String in C kürzen



  • Frank Erdorf schrieb:

    @-_-

    Hier geht es darum,
    daß die von Wutz aufgeführte Funktion theoretisch nicht sicher ist.
    In der Praxis ist diese Funktion normalerweise schon sicher,
    weil sie die meisten checks schon macht.

    Wie auch immer,
    je nach Nutzdaten kann es hier zu einem Stackoverflow oder Heapoverflow kommen.
    Das kann zu undefiniertem Verhalten und zum Absturz des Programms führen.
    Schlimmer noch es kann ausgenutzt werden um Angriffe zu starten und Fremdcode auszuführen.

    Insbesondere ein Stackoverflow lässt sich vergleichsweise einfach für Angriffe
    ausnutzen, weil die Rücksprungadressen auf dem Stack liegen.
    Man braucht 'nur' diese Adressen geschickt zu überschreiben und
    kann Fremdcode in den Daten ausführen.

    Wie schon gesagt,
    genau das ist hier nicht Thema.

    noch etwas:
    wenn du was nicht verstehst, kannst du auch gerne freundlicher fragen.

    Gruß Frank

    wo steht das eine datei eine endung hat... nirgends daher sollte man erstmal die datei+endung aus dem gesamten sting rauslösen und dann die endung entfernen. da dies das thema dieses threads ist habe ich das geschrieben... da ging es noch nicht mal buffer overflows o.ä.

    noch etwas:
    wenn ichs dir genauer erklären soll sag bescheid 😋



  • hum0r -> nein schrieb:

    da ging es noch nicht mal um buffer overflows o.ä.



  • @noobKing?
    Sorry,
    dann habe ich das kurze Posting wohl missinterpretiert,
    war aber nicht wirklich schwer.

    wo steht das eine datei eine endung hat... nirgends

    korrekt,
    wenn die Datei keine Endung hat,
    dann macht die Funktion von Wutz nichts und signalisiert das auch:

    if( !(p=strrchr(dateiname,'.')) )
        return 0;
    

    Gruß Frank



  • ich bin eher der quertreiber 😉 aber laß doch mal die function von wutz auf folgenden string los

    /hello.world/file
    


  • Jetzt wird es aber deutlich schwieriger als in der Aufgabenstellung ...

    na dann schreib du doch mal was,
    du hast dir ja auch diesen Testcase ausgedacht 😉
    und wenn dann schon bitte auch winlike \ berücksichtigen .. 😉

    Gruß Frank



  • Da schaut man mal ein paar Stunden nicht nach und schon tummeln sich die Querulanten, aber wenigstens einer bemüht sich um Pragmatismus.

    Der Fragesteller hat sich noch nicht geäußert, vielleicht genügt ihm der Vorschlag ja, zumal er einfachstes C bevorzugt.
    Die Vorschlagsfunktion erhebt keinen Anspruch auf Robustheit sämtlichen Randbedingungen gegenüber, das schreibe ich nicht jedes Mal explizit dazu, sie genügt genau dem genannten Anwendungsfall.



  • char *replace(char *path,char *ext){
    	char *ret = strrchr(path,'/');
    	if(!ret)
    		ret = path;
    	ret = strrchr(ret,'.');
    	if(ret){
    		if(strlen(ret) >= strlen(ext))
    			strcpy(ret,ext);
    		else
    			return 0;
    	}
    	return path;
    }
    


  • wutz schrieb:

    zumal er einfachstes C bevorzugt

    bei solchen sätzen bekomm ich nen kropf einfachstes c heißt nicht das es falsch sein darf ⚠



  • Frank Erdorf schrieb:

    Wie auch immer,
    je nach Nutzdaten kann es hier zu einem Stackoverflow oder Heapoverflow kommen.
    Das kann zu undefiniertem Verhalten und zum Absturz des Programms führen.
    Schlimmer noch es kann ausgenutzt werden um Angriffe zu starten und Fremdcode auszuführen.

    Insbesondere ein Stackoverflow lässt sich vergleichsweise einfach für Angriffe
    ausnutzen, weil die Rücksprungadressen auf dem Stack liegen.
    Man braucht 'nur' diese Adressen geschickt zu überschreiben und
    kann Fremdcode in den Daten ausführen.

    Warum kann es da zu einem Stackoverflow kommen? Den Heapoverflow hab ich verstanden, aber beim anderen hapert es noch.

    -_o schrieb:

    strcpy(ret + 1,ext);
    

    sonst wird der Punkt mit überschrieben.



  • Antoras schrieb:

    strcpy(ret + 1,ext);
    

    sonst wird der Punkt mit überschrieben.

    merci 👍



  • dann muß man doch sicher auch noch das strlen() anpassen 😕



  • blindesSmiley schrieb:

    dann muß man doch sicher auch noch das strlen() anpassen 😕

    stimmt.

    Ich hab die Funktion gerade noch so geändert, dass man auch Endungen anhängen kann, die länger sind als die ursprüngliche Endung:

    char *replace(char *path, char *ext)
    {
        char *ret = strrchr(path, '/');
        if (!ret) {
            ret = path;
        }
        ret = strrchr(ret, '.');
        if (ret) {
            int len_ret = strlen(ret);
            int len_ext = strlen(ext);
            if (len_ret - 1 < len_ext) {
                int new = len_ext - len_ret;
                if ((path = realloc(path, strlen(path) + new)) == '\0') {
                    return 0;
                }
            }
            strcpy(ret + 1, ext);
        }
        return path;
    }
    


  • wieso les ich das new als variable nur so gerne 🤡
    evtl. könnte man noch das int in size_t tauschen
    👍



  • #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char *replace(char *path, char *ext)
    {
        char *ret = strrchr(path, '/');
        if (!ret) {
            ret = path;
        }
        ret = strrchr(ret, '.');
        if (ret++) {
            int diff = strlen(ext) - strlen(ret);//buggy?
            if (diff++ > 0) {
                if ((path = realloc(path, strlen(path) + diff)) == '\0') {
                    return 0;
                }
            }
            strcpy(ret,ext);
        }
        return path;
    }
    
    int main(void) {
    	char *s = malloc(sizeof("/asd.asd/file.xx"));
    	strcat(s,"/asd.asd/file.xx");
    	printf(replace(s,".nn"));
    	return EXIT_SUCCESS;
    }
    

    @edit size_t ist unsigned das wird ja nie negativ ⚠



  • buggy? könnt schon sein...

    int main(void) {
    	size_t a = ~0;
    	int b = 0 - a;
    	printf("%d",b);
    	return 0;
    }
    


  • Hallo Leute,

    ist ja wahnsinn wie viel auf meine Frage geantwortet wurde. Mit eurer Hilfe habe ich es nun auch problemlos hinbekommen!

    Vielen Dank!

    Übrigens: auch die allererste Lösung die gepostet wurde funktioniert bei mir.


Anmelden zum Antworten