Zeichenkette
Eine Zeichenkette, Zeichenfolge, Zeichenreihe oder ein String (aus dem Englischen) ist in der Informatik eine endliche Folge von Zeichen (z.B. Buchstaben, Ziffern, Sonderzeichen und Steuerzeichen) aus einem definierten Zeichensatz. Zeichen können sich in einer Zeichenkette wiederholen, die Reihenfolge der Zeichen ist definiert. Eine Zeichenkette kann auch leer sein, also kein Zeichen enthalten und die Länge 0 haben. Zeichenketten sind somit Sequenzen aus Symbolen mit endlicher Länge.
In der Programmierung ist eine Zeichenkette ein Datentyp, der eine Kette von Zeichen mit fester oder variabler Länge enthält. Damit werden hauptsächlich Wörter, Sätze und ganze Texte gespeichert. Fast jede Programmiersprache besitzt einen derartigen Datentyp und manche Programmiersprachen arbeiten ausschließlich mit diesem Datentyp. Beispiele dafür sind sed, awk und bash. Im Quelltext eines Computerprogramms stellen Zeichenketten Text dar, der nicht als Programmierbefehl aufgefasst wird, sondern Information enthält. So können zum Beispiel Fehlermeldungen oder andere Ausgaben an den Benutzer als Zeichenkette im Quelltext festgehalten werden oder Benutzereingaben als Zeichenketten in Variablen abgespeichert werden.
Die Grundlagen von Programmiersprachen werden in der Theoretischen Informatik untersucht. Dort wird der gegebene Zeichensatz als Alphabet bezeichnet und die Zeichenketten werden „Wörter“ genannt. Die Theorie solcher Wörter sind ein Thema der formalen Sprachen. Im Zusammenhang mit Programmiersprachen stellen sich dagegen Fragen der Darstellung, der Speicherung und des Umgangs mit Zeichenketten.
Repräsentation
Zeichenketten können auf verschiedenen Ebenen repräsentiert werden. Eine davon ist der Quelltext eines Programms, der vom Übersetzer gelesen und interpretiert wird. Eine andere ist, wie eine Zeichenkette zur Laufzeit eines Programms im Speicher abgelegt wird.
Syntax für Literale
Im Allgemeinen wird eine literale Zeichenkette in den Programmiersprachen durch das einfache Aneinanderfügen von Zeichen repräsentiert. Sie wird durch einfache oder doppelte Anführungsstriche eingeschlossen:
"Wikipedia"
'Dieser Satz ist eine Zeichenkette.'
"123"
""
(eine leere Zeichenkette, Leerstring)"Erste Lösung, um das Anführungszeichen \" als Teil der Zeichenkette aufzunehmen."
(z.B. in C; C-Strings werden stets durch Anführungszeichen begrenzt, ein Anführungszeichen als Element der Zeichenkette kann trotzdem in Form einer Escape-Sequenz eingebaut werden)'Zweite Lösung, um ein '' aufzunehmen'
(Verdoppelung des Begrenzers, z.B. in Pascal oder Rexx; Pascal-Strings werden stets durch Hochkommata begrenzt)"Dritte Lösung, um ein ' aufzunehmen"
:
(Verwendung eines bzw. des anderen Begrenzers, z.B. in Rexx oder Python)L"Wide String"
s. u. bei Multibyte-String in C
Solche Strings müssen normalerweise in einer einzigen Zeile notiert werden. In manchen Programmiersprachen wie etwa Python können jedoch Strings, die durch verdreifachte Anführungszeichen begrenzt werden, auch mehrere Zeilen umfassen.
Intern
Es gibt mehrere Verfahren, um Zeichenketten effizient abzuspeichern. Zum Beispiel kann ein Zeichen aus dem verwendeten Zeichensatz als Abschlusszeichen definiert werden. Eine Zeichenkette hört dann vor dem ersten Vorkommen dieses Zeichens auf. Eine andere Möglichkeit ist, die Länge der Zeichenkette separat zu speichern.
Repräsentation mit Abschlusszeichen
In Programmiersprachen wie C werden die Zeichenketten fortlaufend im Speicher abgelegt und mit dem Nullzeichen (NUL in ASCII) abgeschlossen. Das Nullzeichen ist das Zeichen, dessen binäre Repräsentation nur aus Nullen besteht. Das folgende Beispiel zeigt, wie eine Zeichenkette mit 5 Zeichen in einem Puffer von 10 Byte Länge abgelegt werden könnte:
F | R | A | N | K | NUL | k | e | f | w |
46 | 52 | 41 | 4E | 4B | 00 | 6B | 65 | 66 | 77 |
Die Länge der obigen Zeichenkette ist 5; sie benötigt aber 6 Bytes
im Speicher. Buchstaben nach dem NUL-Zeichen zählen nicht mehr zur Zeichenkette;
sie können zu einer neuen Zeichenkette gehören oder einfach ungenutzt sein. Eine
Zeichenkette in C
ist ein Array
vom Typ char,
wobei die Zeichenkette als Ende-Kennung ein Nullzeichen enthält. Deswegen heißen
solche Zeichenketten auch nullterminiert, ein älterer Begriff ist
ASCIIZ-String. Da das Nullzeichen selbst auch noch Speicherplatz
benötigt, den die Zeichenkette belegt, ist der Speicherbedarf einer Zeichenkette
immer mindestens 1 Zeichen größer als die nutzbare Länge der Zeichenkette.
Als „Länge der Zeichenkette“ wird die Anzahl der Zeichen vor der Endekennung
bezeichnet. Sie wird von der C-Funktion strlen()
ermittelt.
Der Vorteil dieser Methode ist, dass die Länge eines Strings nur durch den verfügbaren Speicher begrenzt ist und nicht zusätzlich von der Kapazität des Längenfeldes; ein Nachteil ist, dass er keine Null-Zeichen enthalten kann, und dass der Umgang vergleichsweise schwierig und ineffizient ist; beispielsweise kann die Länge eines solchen Strings nur durch das Abzählen der Zeichen ermittelt werden.
Repräsentation mit separater Längenangabe
Eine andere Art, Zeichenketten abzulegen, wird in den Programmiersprachen Pascal, BASIC, PL/I und anderen verwendet:
length | F | R | A | N | K | k | e | f | w |
05 | 46 | 52 | 41 | 4E | 4B | 6B | 65 | 66 | 77 |
Zeichenketten, die so gespeichert werden, können eine bestimmte Länge nicht überschreiten. In Turbo Pascal wird die Länge zum Beispiel im „nullten“ Zeichen gespeichert. Da ein Zeichen 8 Bit groß ist, ist die Länge damit auf 255 Zeichen begrenzt. Die Nachfolgesprache Object Pascal hat das Längenfeld auf 31 Bit erweitert und unterstützt Zeichenketten von bis zu 2 Gigabyte Länge. Auch in REXX wird die Länge in vier Bytes gespeichert, sodass die Begrenzung durch das Längenfeld nicht stärker ist als durch den Speicher.
Speicherung im Pool
Die Speicherung von Zeichenketten benötigt viel Speicherplatz und ist eine sehr häufige Aufgabe. Deshalb verwenden viele höhere Programmiersprachen eine besondere Verwaltung, um das möglichst effizient gestalten zu können. Dies ist aber dem Zugriff der Programmierer einer Anwendung entzogen; es gibt in aller Regel keine Möglichkeit, auf diese Verwaltung direkt zuzugreifen oder auch nur festzustellen, ob eine solche aktiv ist.
Es werden alle Zeichenketten in einem zentralen „Pool“ abgelegt. Das Ziel ist, dass jede benötigte Zeichenkette nur genau ein einziges Mal gespeichert wird. Die Variable im Anwendungsprogramm erfährt nur eine Kennnummer, um bei Bedarf auf die Zeichenkette zugreifen zu können.
Die Verwaltung bedient sich für die Organisation schneller und effizienter Methoden (meist einer Hashtabelle). Jedes Mal, wenn eine Zeichenkette gespeichert werden soll, wird nachgesehen, ob eine inhaltsgleiche bereits bekannt ist. Ist das der Fall, wird die Kennnummer der bereits existierenden Zeichenkette zurückgegeben; ansonsten muss sie neu angelegt werden.
Jedes Mal, wenn eine Zeichenkette gespeichert wird, wird ihr Referenzzähler um eins erhöht. Wird eine Zeichenkette an einer Stelle des Programms nicht mehr benötigt (weil ein Unterprogramm beendet ist und die darin enthaltenen Literale sinnlos werden, oder weil eine Variable einen anderen Wert erhält), wird dies der Verwaltung gemeldet und der Referenzzähler um eins vermindert. Damit lässt sich feststellen, welche der gespeicherten Zeichenketten im Moment verwendet werden – hat der Referenzzähler den Wert Null, wird sie zurzeit nicht gebraucht. Dadurch wäre es möglich, bei Engpässen an Speicherplatz die Verwaltung zu reorganisieren und unbenötigte Zeichenketten zu löschen (Garbage Collection). Dies wird allerdings möglichst vermieden, weil es dazu kommen kann, dass bei jedem Aufruf eines Unterprogramms immer wieder gleichlautende Zeichenketten erneut zugewiesen werden; fortgeschrittene Verwaltung registriert auch die Häufigkeit des Abspeicherns und löscht nur besonders selten benutzte und lange Zeichenketten.
Handelt es sich um eine Programmiersprache, in der ein Quelltext kompiliert und das Ergebnis in einer Objektdatei abgelegt wird, dann erhalten in ihrer Datensektion nach Auflösung aller Präprozessor-Operationen die resultierenden statischen Zeichenketten meist eine ähnliche tabellarische Verwaltung. Allerdings gibt es hier weder ein Löschen noch Referenzzähler. Diese Literale stehen auch der zentralen Zeichenkettenverwaltung nicht zur Verfügung, da bei dynamischer Einbindung nicht gesichert ist, dass diese Datensektion immer geladen ist.
Multibyte-Zeichen
Traditionell wurden zur Repräsentation eines einzelnen Zeichens 8 bit entsprechend einem Byte verwendet, was bis zu 256 verschiedene Zeichen ermöglicht. Um gleichzeitig Zeichen vieler Fremdsprachen und vor allem auch nichtlateinischer Schriften wie etwa Griechisch verarbeiten zu können, reicht das nicht aus.
Mittlerweile sehen die Programmiersprachen für die Speicherung eines einzelnen Zeichens 2 Byte oder 4 Byte vor; konsequenterweise vermeidet man heute in diesem Zusammenhang das Wort byte und spricht allgemein von char.
Unter Microsoft
Windows sind alle Systemfunktionen, die Zeichenketten verwenden, in einer
Version mit nachgestelltem A
(für ANSI,
meint 1 Byte nach ISO 8859)
verfügbar sowie mit nachgestelltem W
(für wide, Multibyte).
Einfacher ist es aber, dies gar nicht explizit anzugeben: Kompiliert man ein
Programm mit der entsprechenden Option, so werden automatisch alle neutralen
Funktionsaufrufe auf 1 Byte/Zeichen oder auf Multibyte umgestellt. Genauso
gibt es für die Programmiersprachen C++ und C Präprozessor-Makros,
mit deren Hilfe sämtliche Standardfunktionen und Literale
in einer unbestimmten Version im Quelltext notiert werden können; bei der
Kompilierung wird dann die gerade angemessene Funktion eingesetzt. Per
Definition verarbeiten die historischen Standardfunktionen in C immer genau
1 Byte/Zeichen.
Intern ist es inzwischen in praktisch allen aktuellen Programmiersprachen üblich, mehrere Bytes für ein Zeichen zu verwenden und darin die größeren Zahlen nach UCS („Unicode“) abzulegen.
In der Kommunikation nach außen und beim Abspeichern in Dateien ist hingegen
eine Mischform gebräuchlich. Um in Dateien und bei der Datenfernübertragung
Platz und Übertragungszeit zu sparen, werden vorwiegend aus lateinischen
(englischen) Buchstaben bestehende Texte mit 1 Byte/Zeichen notiert. Ist
die Kodierung kleiner als 128 (ein „ASCII-Zeichen“),
wird das Zeichen verwendet wie es ist. Hat das Byte dagegen einen Wert ab 128,
so wird dies als Beginn einer aus mehreren Bytes bestehenden Sequenz
interpretiert, die ein einzelnes Zeichen repräsentiert. Das standardisierte
Format hierfür ist UTF-8 (dazu auch UTF-16). Werden solche Zeichen
angetroffen und sind für die interne Repräsentation mehrere Bytes verfügbar,
sollte so früh wie möglich (während des Einlesevorgangs) die Dekodierung
erfolgen, da später nicht mehr zu unterscheiden ist, wie diese Sequenz gemeint
war. Dieselbe Technik wird auch angewendet, um URL zu
kodieren; das Wikilink DF%C3%9C
führt auf „DFÜ
“.
Eine proprietäre Zwischenform war in den 1990er Jahren auf Systemen von Microsoft unter dem Namen „Multibyte Character Set“ gebräuchlich. Hier wurden verschiedene Formate und Kodierungen/Dekodierungen eingesetzt, um der Problematik abzuhelfen, mit 1 Byte/Zeichen auch asiatische Schriften abdecken zu müssen. Mittlerweile wird dies zwar noch nach außen unterstützt; interne Darstellungen und Entwicklungen verwenden es allerdings nicht mehr, sondern benutzen Unicode.
Basisoperationen mit Zeichenketten
Die Basisoperationen mit Zeichenketten, die in fast allen Programmiersprachen vorkommen, sind Länge, Kopieren, Vergleichen, Verketten, Bilden von Teilketten, Mustererkennung, Suchen von Teilketten oder einzelnen Zeichen.
Zum Kopieren von Zeichenketten wird in vielen
höheren Programmiersprachen der Zuweisungsoperator (meist =
oder
:=
) benutzt. In C wird das Kopieren mit der Standardfunktion
strcpy()
oder memcpy()
durchgeführt. Wie zeitaufwendig
das Kopieren ist, hängt stark von der Repräsentation der Zeichenketten ab. Bei
einem Verfahren mit Referenzzählern
besteht das Kopieren nur aus dem Erhöhen des Referenzzählers. In anderen
Verfahren muss eventuell die Zeichenkette alloziert und
komplett kopiert werden.
Das Vergleichen von Zeichenketten auf gleich und
ungleich wird von vielen höheren Programmiersprachen mit den Operatoren
=
oder <>
bzw. !=
unterstützt. In
einigen Sprachen wie Pascal lässt sich zudem ein lexikographischer
Vergleich mit <
und >
durchführen. Sind
diese Operatoren nicht vorhanden, werden Funktionen genutzt. Bei der
Standardfunktion strcmp()
in C gibt es drei Ergebnisse: gleich,
größer oder kleiner. Dabei hat das erste Zeichen die höchste Wertigkeit.[1][2]
Es gibt aber auch kompliziertere Vergleichsfunktionen, die
Groß-/Kleinbuchstaben, Einordnung von Umlauten usw. berücksichtigen. Beim Suchen
in Wörter- und Telefonbüchern spielt dies eine Rolle.
Zum Verketten gibt es in vielen Programmiersprachen
Operatoren wie +
(BASIC,
Pascal,
Python,
Java,
C++),
&
(Ada,
BASIC), .
(Perl,
PHP),
..
(Lua) oder ||
(REXX). In C gibt es
dafür die Funktion strcat()
.
Um an eine bereits bestehende Zeichenkette eine andere anzufügen, stellen
einige Sprachen einen eigenen Operator zur Verfügung (+=
in Java
und Python, ..
in Perl und PHP). Dabei wird üblicherweise der
Operand nicht einfach hinten angefügt, sondern der Ausdruck
alt+neu ausgewertet und der Variablen alt zugewiesen, da
Strings in der Regel als unveränderlich betrachtet werden; es handelt sich also
nur um eine abkürzende Schreibweise. Es gibt jedoch in vielen modernen
Programmiersprachen, wie Java,
C-Sharp oder
Visual
Basic .NET sogenannte String-Builder-Klassen, die veränderbare
Strings darstellen. Allerdings lassen sich String und String-Builder in der
Regel nicht gegenseitig austauschen, sondern müssen ineinander umgewandelt
werden.
Direkt (mit oder ohne Whitespace) hintereinander notierte Strings werden in manchen Sprachen implizit verkettet (C, C++, Python, REXX).
Um eine Teilkette zu erhalten, gibt es verschiedene Möglichkeiten. Durch die
Angabe von (Zeichenkette, Startindex, Endindex) bzw.
(Zeichenkette, Startindex, Länge) kann eine Teilkette
eindeutig definiert werden. Diese Operation heißt häufig substr()
.
Einige Programmiersprachen, zum Beispiel Python, bieten syntaktischen
Zucker für diese Operation an (siehe Beispiele).
PL/SQL
In Oracle sind in gespeicherten Prozeduren, Funktionen und PL/SQL-Blöcken folgende Basisoperationen möglich:
DECLARE
Text1 varchar2(30);
Text2 varchar2(30);
Text3 varchar2(61);
BEGIN
Text1 := 'Frank';
Text2 := 'Meier';
Text3 := Text1 || ' ' || Text2
END;
/
BASIC
text$ = "FRANK"
text2$ = text$
Das nachgestellte Dollarzeichen gibt an, dass es sich um eine
Zeichenkettenvariable handelt. Da ein String durch Anführungszeichen begrenzt
wird, können sie selbst nur über die Chr(34)
- bzw.
CHR$(34)
-Funktion in den String eingebaut werden, die 34 ist der ASCII-Code
des Anführungszeichens.
Mehrere Zeichenketten können (je nach BASIC-Dialekt) mit dem Pluszeichen oder mit dem Kaufmanns-Und „&“ zu einer verbunden („konkateniert“) werden:
text2$ = "***" + text$ + "***"
text2$ = "***" & text$ & "***"
C
Dieses C-Programm definiert zwei Zeichenketten-Variablen, die jeweils 5 Zeichen „Nutzlast“ aufnehmen können. Da Zeichenketten mit einem Nullzeichen abgeschlossen werden, muss das Array 6 Zeichen haben. Anschließend wird in beide Variablen der Text „FRANK“ kopiert.
#include <string.h>
int main(void)
{
char text1[6];
char text2[6];
strcpy(text1, "FRANK");
strcpy(text2, text1);
return 0;
}
Um zwei Strings aneinanderzuhängen, existiert die Standardfunktion
strcat()
. Diese allozziert jedoch nicht den für den
Zielstring notwendigen Speicherplatz. Dies muss vorher separat erfolgen.
#include <string.h>
int main(void)
{
char puffer[128]; // Zielpuffer, der groß genug ist.
strcpy(puffer, "FRANK");
strcat(puffer, "ENSTEIN");
return 0;
}
Java
String text1 = "FRANK";
String text2 = text1;
Zeichenketten in Java sind Objekte der Klasse String. Sie sind nach dem Erzeugen nicht mehr änderbar. Im obigen Beispiel repräsentieren text1 und text2 dasselbe Objekt.
Die Konkatenation von Zeichenketten wird durch den (für diesen Fall überladenen) Plus-Operator durchgeführt:
String text1 = "FRANK";
String text2 = "ENSTEIN";
String ganzerName = text1 + text2;
Pascal
(Streng genommen funktioniert das folgende erst seit Turbo Pascal, da die ursprüngliche von Niklaus Wirth geschaffene Pascal-Sprache nur packed arrays of char kannte, die etwas umständlicher zu handhaben waren)
var vorname, nachname, name: string;
{… …}
vorname := 'FRANK';
nachname := 'MEIER';
name := vorname + ' ' +nachname;
PHP
Bei PHP verhält es sich ähnlich wie bei Perl.
$text = "FRANK";
$text2 = $text; // $text2 ergibt "FRANK"
$text3 = <<<HEREDOC
Ich bin ein längerer Text mit Anführungszeichen wie " oder '
HEREDOC;
Texte werden mit einem Punkt konkateniert.
$text = "FRANK";
$text = "FRANK" . "ENSTEIN"; // $text ergibt "FRANKENSTEIN"
$text = "FRANK";
$text .= "ENSTEIN"; // $text ergibt "FRANKENSTEIN"
Rexx
In Rexx wird
alles – einschließlich Zahlen – als String repräsentiert. So wird
einer Variablen ein String-Wert zugewiesen: a
= "Ottos Mops"
Die folgenden Ausdrücke ergeben jeweils den Wert
"Ottos Mops"
:
"Ottos" "Mops"
(implizit verkettet; genau ein Leerzeichen wird automatisch eingefügt)"Ottos" || ' Mops'
(explizit verkettet, kein Einfügen eines Leerzeichens)"Ottos"' Mops'
(implizit verkettet durch unmittelbares Anfügen eines weiteren Strings, der durch das andere Begrenzungszeichen begrenzt wird)
Weitere Operationen
Substrings ermitteln
Angenommen, die Variable s
enthalte die Zeichenkette Ottos
Mops hopst fort
. Dann lassen sich das erste Zeichen (O
), die
ersten fünf Zeichen (Ottos
), das siebte bis zehnte
(Mops
) sowie die letzten vier (fort
) wie folgt
ermitteln:
Python
s[0]
→ Os[:5]
oders[0:5]
oders.split()[0]
→ Ottoss[6:10]
oders.split()[1]
→ Mopss[-4:]
oders.split()[-1]
→ fort
Dieses Verfahren wird Slicing genannt (von engl. „to slice“ mit der Bedeutung „in Scheiben schneiden“ bzw. „aufteilen“). Das erste Zeichen hat den Index 0.
Rexx
SubStr(s, 1, 1)
oderLeft(s, 1)
→ OLeft(s, 4)
oderWord(s, 1)
→ OttosSubStr(s, 7, 4)
oderWord(s, 2)
→ MopsRight(s, 4)
oderWord(s, 4)
→ fort
Rexx kann Strings auch wortweise verarbeiten, wobei Wörter durch (beliebig viele) Leerzeichen getrennt werden. Das erste Zeichen hat, wie bei Pascal-Strings, den Index 1.
PARSE VAR s A 2 1 O M F
⇒ Variablen A,O,M,F beinhalten 'O', 'Ottos', 'Mops', 'fort'
Dieses Verfahren wird Tokenizing genannt (von engl. „token“ mit der Bedeutung „Kürzel“ oder „Spielstein“ und meint hier etwa „Stück“ oder „Bröckchen“) und ist auch in anderen Sprachen eine Standardfunktion.
PHP
substr($s, 0, 5)
→ Ottossubstr($s, 6, 4)
→ Mopssubstr($s, -4)
→ fort
BlitzBasic
Left(s, 5)
→ OttosMid(s, 7, 4)
→ MopsRight(s, 4)
→ fort
Object Pascal
s[1]
→ OCopy(s, 1, 5)
→ OttosCopy(s, 7, 4)
→ Mops
Mittels der Unit StrUtils:
LeftStr(s, 5)
→ OttosMidStr(s, 7, 4)
→ MopsRightStr(s, 4)
→ fort
Algorithmen
Verschiedene Algorithmen arbeiten vorwiegend mit Zeichenketten:
- String-Matching-Algorithmen überprüfen ob eine Zeichenkette Teil einer größeren Zeichenkette ist.
- Bestimmen von Teilzeichenketten, die mit einem regulären Ausdruck beschrieben sind.
- Sortieralgorithmen, im Kontext von Strings hauptsächlich zum Sortieren der Suffixe eines Textes (Suffixbaum, Suffixarray)
- Parser
- Codeumwandlungen (Unicode usw.)
Heute schreibt ein Programmierer diese Art Algorithmen meist nicht mehr selbst, sondern benutzt Konstrukte einer Sprache oder Bibliotheksfunktionen.
Pufferüberlauf – Zeichenketten und Computersicherheit
Immer dann, wenn Zeichenketten aus der Außenwelt in die innere Repräsentation übernommen werden, sollten besondere Vorkehrungen getroffen werden. Neben unerwünschten Steuerzeichen und der Formatierung ist vor allem die maximale Länge der Zeichenkette zu überprüfen.
Beispiel: Eine internationale Telefonnummer soll aus einer Datei eingelesen werden. Sie soll ausschließlich Ziffern enthalten und durch ein Tabulatorzeichen (ASCII 9) von der Anschrift abgetrennt werden. Für die Aufnahme ist eine Zeichenkette fester Länge mit 16 Zeichen vorgesehen; dies reicht für alle gültigen Telefonnummern aus. – In den Eingabedaten könnten Leerzeichen oder Bindestriche enthalten sein und die Telefonnummer verlängern. Auch wenn versehentlich statt TAB ein genauso aussehendes Leerzeichen folgt, ergeben sich mehr als 16 Zeichen.
Wird dies nicht durch geeignete Prüfungen kontrolliert und darauf angemessen reagiert, kommt es zum Pufferüberlauf und möglicherweise zum Absturz des Programms oder zu mysteriösen Folgefehlern.
Zu den häufigsten Angriffsmethoden auf Webserver zählen Pufferüberläufe. Dabei wird versucht, einer Zeichenkettenvariablen einen Inhalt zuzuweisen, dessen Länge die vom Compiler im Speicher reservierte Länge der Variablen übersteigt. Hierdurch werden andere, benachbarte Variablen im Speicher überschrieben. Bei geschickter Ausnutzung dieses Effekts kann ein auf einem Server laufendes Programm manipuliert und für Angriffe auf den Server missbraucht werden. Es reicht aber schon, die Server-Software so zum Absturz zu bringen; da sie die Netzverbindung bewachen soll („Gateway“), reißt ihr Ausfall eine Lücke, die einen schwach gesicherten Server nun schutzlos jeder Manipulation überlässt.
Soweit nicht in überschaubarer Umgebung bereits die Gültigkeit überwacht
wurde, sollten Zeichenketten-Operationen nur mit Funktionen durchgeführt werden,
bei denen die maximale Länge der Zeichenkette überprüft wird. In C wären
das Funktionen wie z.B. strncpy()
,
snprintf()
, … (anstelle von strcpy()
,
sprintf()
, …).
Siehe auch
Anmerkungen
- ↑ Jedem einzelnen Zeichen kommt in jedem Computersystem ein Zahlenwert (meist Binärwert) zu, entsprechend dem es mit einem anderen Zeichen auf gleich, größer oder kleiner verglichen werden kann. Für die Feststellung von Duplikaten in einer Menge von Strings kommt es zwar nur auf die Gleichheit an; bietet die Vergleichsfunktion aber auch die Ergebnisse größer und kleiner nach den Regeln einer Totalordnung an, kann Duplikaterkennung mit binärem Suchen wesentlich effizienter geschehen.
- ↑
Wegen der absteigenden Wertigkeit der Zeichen mit
wachsender Adresse, vergleichen die Vergleichsoperatoren der verschiedenen
Programmiersprachen, aber auch die C-Funktionen
strcmp()
,strncmp()
,memcmp()
auf jeder Maschine im Stil Big-Endian.
© biancahoegel.de
Datum der letzten Änderung: Jena, den: 21.09. 2022