• 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

mampfi

Hacker
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
 
OP
M

mampfi

Hacker
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/
 

TeXpert

Guru
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...
 
OP
M

mampfi

Hacker
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?
 

panamajo

Guru
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.
 
OP
M

mampfi

Hacker
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);
}
 

panamajo

Guru
Code:
jo@codered:~/src> ./strncpy
s=01234567890<
ct=234<
Und jetzt richtig
s=01234567890<
ct=234<

Und wo soll jetzt der Fehler sein?
 

ralf13

Newbie
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".
 
OP
M

mampfi

Hacker
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.
 
OP
M

mampfi

Hacker
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').
 
OP
M

mampfi

Hacker
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?
 

ralf13

Newbie
'\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.
 
OP
M

mampfi

Hacker
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