• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

strncpy-Bug

In welches Forum schreib ich die Frage jetzt?


Habe einen Bug in der strncpy-Funktion vom gcc entdeckt.

Wo kann man den den melden?
 
mampfi schrieb:
In welches Forum schreib ich die Frage jetzt?
In gar kein Forum. In Foren wird das nämlich garantiert nicht diejenigen erreichen, die das Problem beheben könnten.
mampfi schrieb:
Habe einen Bug in der strncpy-Funktion vom gcc entdeckt.
Wow, nicht übel.
mampfi schrieb:
Wo kann man den den melden?
http://gcc.gnu.org/bugzilla/

Aber bitte erst nach Lektüre der Richtlinien:

http://gcc.gnu.org/bugs.html
 
Mit welches Forum hab ich die Kategorie vom Forum hier gemeint, Programmierung scheint zu passen.

Im Zusammenhang mit der Funktion macht Turbo-C++ auch kuriose Sachen, aber das betrifft die Gnu-Schöpfer ja weniger. ;-)
 
Noch was: Ich glaube, dass das, wenn es denn überhaupt ein Bug ist, kein GCC-Bug, sondern ein glibc-Bug wäre. => http://sources.redhat.com/bugzilla/
 
traffic schrieb:
mampfi schrieb:
Habe einen Bug in der strncpy-Funktion vom gcc entdeckt.
Wow, nicht übel.

wobei ich bei diesen "gefundenen GCC-Bugs" in Basis-Dingen jetzt ja fast schon einwerfen möchte, dass der Bug vor dem Monitor sitzt... denn *diese* Basissachen sind wahrscheinlich schon von Millionen anderen Codern zur vollsten Zufriedenheit genutzt worden...
 
Liegt wahrscheinlich dran, dass der Bug einfach zu umgehen ist.

Wenn jemand den Befehl sofort im Programm einsetzt, dann kann es ihn einige Zeit kosten.

Der strncpy-Befehl vergisst, das die abschließende '\0' im Zielstring.

Mein altes Kernighan/Ritchie sagt, das ghört dazu.

Hat jemand ein ANSI-Buch?
 
mampfi schrieb:
Der strncpy-Befehl vergisst, das die abschließende '\0' im Zielstring.
Was? Dazugehört, mitgezählt, hinzugefügt, sollte, könnte, hätte?

Jetzt machs doch nicht so spannend ;)

Nebenbei: man strcpy:
The strncpy() function is similar, except that not more than n bytes of src are copied. Thus, if there is no null byte among the first n bytes of src, the result will not be null-terminated.
 
mampfi schrieb:
Der strncpy-Befehl vergisst, das die abschließende '\0' im Zielstring.
Mein altes Kernighan/Ritchie sagt, das ghört dazu.
Hat jemand ein ANSI-Buch?
man strncmp
The strncmp() function is similar, except it only compares the first
(at most) n characters of s1 and s2.
K&R, 2.Ausgabe sagt dasgleiche
strncpy(s,t,n) copy at most n characters of t to s
QED. WWWWW. PEBKAC.
 
Laut diesem Zitat ist es kein Bug.
Auf meinem Kernighan/Ritchie-Buch (Zweite Ausgabe: ANSI C) ist es keiner.

Fest steht: In den meisten Fällen ist es auch kein Feature ;-)



Hier der Quälcode:

#include "stdio.h"
#include "string.h"


void test_strncpy()

{
char s[100];
char ct[100];

int laenge=3;
int startposition=2;

strcpy(s, "01234567890");

strncpy(ct, s+startposition, laenge);

printf("s=%s<\n", s);
printf("ct=%s<\n", ct);

puts("Und jetzt richtig");

ct[laenge]='\0';

printf("s=%s<\n", s);
printf("ct=%s<\n", ct);
}
 
Code:
jo@codered:~/src> ./strncpy
s=01234567890<
ct=234<
Und jetzt richtig
s=01234567890<
ct=234<

Und wo soll jetzt der Fehler sein?
 
Es gibt doch 3 mögliche Definitionen für strncpy-Funktionalität:
1. Nach den n Zeichen wird einfach abgebrochen. Nachteil: abschließendes \0 muss ggf. von Hand gesetzt werden.
2. Nach den n Zeichen wird zusätzlich ein '\0' angehängt.
Code:
char str1[3];
strncpy(str1, "ABC", 3) => Leicht zu übersehenden Stack-Überschreiber
3. Es werden nur max. n-1 Zeichen kopiert, dann kommt ein '\0'.
Code:
strncpy(str1, "ABCDEF", 3);
printf("%d", strlen(str1)); => Ausgabe 2, auch nicht gerade auf Anhieb einsichtlich

Es gibt also keine perfekte Lösung. Laut Dokumentation wird Definition 1 verwendet und genauso verhält sich der strncpy() auch (zumindest auf meinem System). Was soll daran jetzt falsch sein?

@panamajo: Das Ergebnis hat ich am Anfang auch, da ist ct[4] zufälligerweise schon '\0' gewesen. Wenn du vor dem strncpy() noch ein strcpy(ct, "aaaaaaaaaaaaaaaaaa") einfügst, siehst du den "Fehler".
 
Meine gcc-version, gcc von der DVD SuSE 10.0:

manfred@athlon:/daten/prog/c/dbase> gcc --version
gcc (GCC) 4.0.2 20050901 (prerelease) (SUSE Linux)
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
Ich bin keiner, der sich als C-Guro bezeichnen würde und deshalb hab ich auch (aufgrund einer paranoiden Eingebung) vorher mit dem strncpy rumprobiert und nicht sofort im eigentlichen Quelltext eingesetzt.

Offenbar ist beim "strncpy-Standard" die abschließende 0 weggefallen.

Das könnte einem angestellten C-Quellcode-Ersteller den Vormittag versauen.
8) 8)

Im Buch steht:

char *strncpy(s, ct, n)

höchstens n Zeichen aus ct in s kopieren, liefert s. Mit '\0' auffüllen, wenn ct weniger als n Zeichen hat.
 
Fakt ist, dass strncpy N Zeichen kopiert. Wenn innerhalb der ersten N Zeichen '\0' vorkommt, brauchst du's nicht selber machen. Da man aber strncpy nur verwendet, wenn man sich dessen nicht sicher ist, setzt man statistisch immer hinten einen drauf (also str[sizeof(str)-1]='\0').
 
Das Ergebnis des Threads ist offenbar: Es ist kein Bug.
(Am Rande bemerkt: Nun weiß ich auch, warum Turbo-C im Editor was anderes macht, wie auf der DOS-Zeile).

Bin wie erwähnt nur durch Zufall auf die Thematik gestoßen.

Wobei: Wenn mit '\0' aufgefüllt wird, dann wäre der Delimiter bereits gesetzt, oder versteh ich was falsch?
 
'\0' wird nur aufgefüllt, wenn die Quellstring-Laenge < n ist.
Code:
strncpy(a, "A", 1000);
kopiert ein 'A' und schreibt dann noch 999 '\0' dahinter.

Bei deinem Problem war aber n < Quellstring-Laenge, und da wird auch nichts aufgefüllt.
 
Also dann ungefähr so:

#include "stdio.h"
#include "string.h"


void test_strncpy(char quell[], char ziel[], int laenge, int startposition)

{
if ( strlen(quell)+1 > laenge ) puts("so gehts ja nicht, laenge ist zu klein für den delimiter");

if (startposition > strlen(ziel) )
{
puts("funzt nicht startposition > strlen(ziel)");
}


printf("strlen(quell)=%d\n",strlen(quell));

strncpy(ziel+startposition, quell, laenge);
}

int main(void)

{
char quell[100];
char ziel[100];

strcpy(quell, "rein");
strcpy(ziel, "01234567890");



test_strncpy(quell, ziel, 5, 10);

printf("s=%s<\n", quell);
printf("ziel=%s<\n", ziel);
}
 
Oben