HighDots Forums  

Strings formatieren

Javascript (German) Programmiersprache JavaScript. (de.comp.lang.javascript)


Discuss Strings formatieren in the Javascript (German) forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Michael Schuerig
 
Posts: n/a

Default Strings formatieren - 05-28-2005 , 03:54 PM







Vielleicht bin ich nicht der einzige, der Strings formatieren, genauer,
Platzhalter in Strings durch Variablen ersetzen möchte. Hier mein
Vorschlag, wie man das anstellen kann:

String.prototype.format = function() {
var args = arguments;
return this.replace(
/{{.*?}}|{(\d+)(,\s*([\w.]+))?}/g,
function(m, a1, a2, a3) {
if (m[1] == '{') return m;
var rpl = args[a1];
if (a3) {
var f = eval(a3);
rpl = f(rpl);
}
return rpl ? rpl : '';
});
}

Im einfachsten Fall wird die Funktion einfach so benutzt:

alert('Die Temperatur hat heute {0}°C erreicht'.format(35));

Für unsere Freunde, die es nicht so mit SI-Einheiten haben, ginge es
auch so:

function CtoF(t) {
return (t * 9)/5 + 32;
}
alert('Today the temperature reached {0,CtoF}°F'.format(35));


Michael

--
Michael Schuerig Face reality and stare it down
mailto:michael (AT) schuerig (DOT) de --Jethro Tull, Silver River Turning
http://www.schuerig.de/michael/


Reply With Quote
  #2  
Old   
Thomas 'PointedEars' Lahn
 
Posts: n/a

Default Re: Strings formatieren - 05-28-2005 , 06:21 PM






Michael Schuerig wrote:

Quote:
Vielleicht bin ich nicht der einzige, der Strings formatieren, genauer,
Platzhalter in Strings durch Variablen ersetzen möchte.
Du meinst Variablen_werte_. Nein, da haben sich zuvor schon ein paar Leute
Gedanken gemacht und z.B. in C geeignete Funktionen geschrieben (*printf*).
Eine bislang anscheinend fe lende, allerdings noch nicht 100%ig
featuregleiche, ECMAScript-konforme Implementation von printf(3) findest Du
seit einiger Zeit hier:

<http://PointedEars.de/scripts/string.js>, format()

Quote:
Hier mein Vorschlag, wie man das anstellen kann:

String.prototype.format = function() {
var args = arguments;
return this.replace(
/{{.*?}}|{(\d+)(,\s*([\w.]+))?}/g,
^^^^^^^ ^^ ^
Das ist syntaktisch inkorrekt und compiliert daher nicht. `{'...`}'
definiert das n-fache Vorkommen des vorhergehenden Ausdrucks (n >= 0).

Es funktioniert aber auch mit korrekter Syntax nicht wie gewünscht, denn
(wie hier schonmal erwähnt wurde) kontextfreie Sprachen (Chomsky-L2), wie
die Sprache korrekter Klammerausdrücke, lassen sich nur mit Einschränkungen
mit Regulären Ausdrücken (beschreiben L3, die Klasse Regulärer Sprachen)
parsen (sonst hiessen sie ja kontextfreie Ausdrücke ); um es 100%ig
richtig zu machen, braucht man hier einen PDA (Push-Down Automaton) statt
einen DFA (Deterministic Finite Automaton) und/oder NFA (Non-deterministic
Finite Automaton) wie er für REs benutzt wird.

Konkret matcht die erste Alternative bei korrekter Syntax (d.h. escaped)
auch auf

{{{x}}

und zwar mit folgenden Produktionen:

\{\{ --> {{
.*? --> {x
\}\} --> }}

Besser ist

\{\{[^{}]*?\}\}

Das matcht allerdings immer noch auf

{{}}

Daher ist ein guter Ansatz fürs Parsing:

\{\{[^{}]+?\}\}

Und das hat immer noch zwei Fehler:

1. Es macht noch immer auf das "{{x}}" in "{{{x}}".

2. Nicht-gierige Quantifizierer wie `+?' funktionieren nicht in nicht
ganz neuen Browsern, d.h. solchen, die ECMAScript 3 nicht (vollständig)
implementieren. Per default funktioniert es IIRC nicht in IE 5.5, weil
die per default installierte JScript-Version das nicht hergibt.

Quote:
function(m, a1, a2, a3) {
if (m[1] == '{') return m;
In Deinen Format-Strings darf man also keine geschweiften Klammern
benutzen. [Und dabei fällt mir auf, dass man bei meiner derzeitigen
printf(3)-Implementation keine `%' mit Buchstabe dahinter benutzen
darf. Mist (der sich aber beheben lässt).]

Quote:
var rpl = args[a1];
if (a3) {
var f = eval(a3);
^^^^
Lover not, wie der Engländer nie sagen würd'. Überleg mal, was
passieren kann, wenn man Deine Methode mit einer Benutzereingabe
füttert, beispielsweise

"{0,function spamMe() {...}; while (true) {spamMe();};}"

Quote:
[...]
Im einfachsten Fall wird die Funktion einfach so benutzt:

alert('Die Temperatur hat heute {0}°C erreicht'.format(35));
Bei meiner Lösung geht's so:

alert(format('Die Temperatur hat heute %d°C erreicht', 35));

Quote:
Für unsere Freunde, die es nicht so mit SI-Einheiten haben, ginge es
auch so:

function CtoF(t) {
return (t * 9)/5 + 32;
}
alert('Today the temperature reached {0,CtoF}°F'.format(35));
Entsprechend:

alert(format('Today the temperature reached %d°F', CtoF(35)));


HTH

PointedEars
--
I hear, and I forget; I see, and I remember; I do, and I understand.
-- Chinese proverb


Reply With Quote
  #3  
Old   
Michael Schuerig
 
Posts: n/a

Default Re: Strings formatieren - 05-28-2005 , 07:19 PM



Thomas 'PointedEars' Lahn wrote:

Quote:
Michael Schuerig wrote:

Vielleicht bin ich nicht der einzige, der Strings formatieren,
genauer, Platzhalter in Strings durch Variablen ersetzen möchte.

Du meinst Variablen_werte_. Nein, da haben sich zuvor schon ein paar
Leute Gedanken gemacht und z.B. in C geeignete Funktionen geschrieben
(*printf*). Eine bislang anscheinend fe lende, allerdings noch nicht
100%ig featuregleiche, ECMAScript-konforme Implementation von
printf(3) findest Du seit einiger Zeit hier:

http://PointedEars.de/scripts/string.js>, format()
Printf ist aber nicht das, was ich haben will. Ich brauche die Funktion
zum lokalisieren von Strings mit interpolierten (interpositionierten?)
Variablenwerten. Dabei ist es wichtig, dass die Werte in einer anderen
Reihenfolge in den Formatstring eingefügt werden können als in ihrer
Argumentreihenfolge.

Quote:
Hier mein Vorschlag, wie man das anstellen kann:

String.prototype.format = function() {
var args = arguments;
return this.replace(
/{{.*?}}|{(\d+)(,\s*([\w.]+))?}/g,
^^^^^^^ ^^ ^
Das ist syntaktisch inkorrekt und compiliert daher nicht. `{'...`}'
definiert das n-fache Vorkommen des vorhergehenden Ausdrucks (n >= 0).
Danke. Korrigiert. Dummerweise hat es mit einem Browser doch kompiliert.

Quote:
Es funktioniert aber auch mit korrekter Syntax nicht wie gewünscht,
Doch tut es allem Anschein nach. Was aber daran liegt, dass ich wohl
etwas anderes wünsche als Du vermutest. Die Funktion muss nicht gegen
jeglichen Missbrauch gefeit sein, soll es jemand, der sie verwendet,
aber ermöglichen, jeden String zu erzeugen.

Quote:
Konkret matcht die erste Alternative bei korrekter Syntax (d.h.
escaped) auch auf

{{{x}}
Das stimmt wohl, ist für meinen(!) Anwendungszweck aber nicht ernsthaft
relevant. Nach weiterem Überlegen will ich die umschliessenden Klammern
ja gar nicht haben. Also

return this.replace(
/\{\{[^{}]*\}\}|\{(\d+)(,\s*([\w.]+))?\}/g,
function(m, a1, a2, a3) {
if (m[1] == '{') {
return m.slice(1, -1);
}

Quote:
function(m, a1, a2, a3) {
if (m[1] == '{') return m;

In Deinen Format-Strings darf man also keine geschweiften Klammern
benutzen.
Probier's mal...
Der Test prüft ganz einfach, welche der beiden Alternativen gematcht
hat.

Quote:
var rpl = args[a1];
if (a3) {
var f = eval(a3);
^^^^
Lover not, wie der Engländer nie sagen würd'. Überleg mal, was
passieren kann, wenn man Deine Methode mit einer Benutzereingabe
füttert, beispielsweise

"{0,function spamMe() {...}; while (true) {spamMe();};}"
Dann war der Benutzer dumm. Wenn ich schon einen flexible, dynamische
Sprache habe, dann nutze ich das auch. Der Formatstring ist bei meiner
Anwendung immer fest vorgegeben, keine Benutzereingabe. Das ist ein
ganz typisches Szenario bei der Lokalisierung von Programmtexten.


Quote:
Im einfachsten Fall wird die Funktion einfach so benutzt:

alert('Die Temperatur hat heute {0}°C erreicht'.format(35));

Bei meiner Lösung geht's so:

alert(format('Die Temperatur hat heute %d°C erreicht', 35));

Für unsere Freunde, die es nicht so mit SI-Einheiten haben, ginge es
auch so:

function CtoF(t) {
return (t * 9)/5 + 32;
}
alert('Today the temperature reached {0,CtoF}°F'.format(35));

Entsprechend:

alert(format('Today the temperature reached %d°F', CtoF(35)));
Das würde mir aber überhaupt nicht helfen. Ich möchte beide Situationen
einheitlich behandeln und dazu muss ich an irgendeiner Stelle
abstrahieren.

Konkret brauche ich das, um bei der client-seitigen Validierung von
Benutzereingaben (mehr dazu bei einer späteren Gelegenheit)
lokalisierte Meldungen zu erzeugen. Dabei stehen die Locale-abhängigen
Teile in eigenen Dateien, die nach Bedarf eingebunden werden. Etwa so

Validators.Localized = {

fieldsMustBeDifferent: 'Felder müssen sich unterscheiden: {0,
Validators.Localized.join}',

temperatureTooHigh: 'Mehr als {0, Validators.Localized.degrees}°C? Das
glaubt doch keiner!',

join: function(arg) {
return arg.join(', ');
},

degrees: function(dgc) {
return dgc;
}
}


Michael

--
Michael Schuerig This is not a false alarm
mailto:michael (AT) schuerig (DOT) de This is not a test
http://www.schuerig.de/michael/ --Rush, Red Tide



Reply With Quote
  #4  
Old   
Thomas 'PointedEars' Lahn
 
Posts: n/a

Default Re: Strings formatieren - 05-28-2005 , 09:28 PM



Michael Schuerig wrote:

Quote:
Thomas 'PointedEars' Lahn wrote:
Michael Schuerig wrote:
Vielleicht bin ich nicht der einzige, der Strings formatieren,
genauer, Platzhalter in Strings durch Variablen ersetzen möchte.

Du meinst Variablen_werte_. Nein, da haben sich zuvor schon ein paar
Leute Gedanken gemacht und z.B. in C geeignete Funktionen geschrieben
(*printf*). Eine bislang anscheinend fe lende, allerdings noch nicht
100%ig featuregleiche, ECMAScript-konforme Implementation von
printf(3) findest Du seit einiger Zeit hier:

http://PointedEars.de/scripts/string.js>, format()

Printf ist aber nicht das, was ich haben will. Ich brauche die Funktion
zum lokalisieren von Strings mit interpolierten (interpositionierten?)
`Interpoliert' sicher nicht. MUSEN schon eher das andere.

Quote:
Variablenwerten. Dabei ist es wichtig, dass die Werte in einer anderen
Reihenfolge in den Formatstring eingefügt werden können als in ihrer
Argumentreihenfolge.
Sowohl printf(3) als auch meine Implementation davon ermöglichen dies.
Lies die Manpage bzw. die JSdoc-Kommentare nochmal genau.

Quote:
/{{.*?}}|{(\d+)(,\s*([\w.]+))?}/g,
^^^^^^^ ^^ ^
Das ist syntaktisch inkorrekt und compiliert daher nicht. `{'...`}'
definiert das n-fache Vorkommen des vorhergehenden Ausdrucks (n >= 0).

Danke. Korrigiert. Dummerweise hat es mit einem Browser doch kompiliert.
Schlimm. Mit welchem?

Quote:
Es funktioniert aber auch mit korrekter Syntax nicht wie gewünscht,

Doch tut es allem Anschein nach. Was aber daran liegt, dass ich wohl
etwas anderes wünsche als Du vermutest. Die Funktion muss nicht gegen
jeglichen Missbrauch gefeit sein, soll es jemand, der sie verwendet,
aber ermöglichen, jeden String zu erzeugen.
Die Methode muss klar definiert sein, sonst ist sie mindestens für die
Produktion unbrauchbar.

Quote:
Konkret matcht die erste Alternative bei korrekter Syntax (d.h.
escaped) auch auf

{{{x}}

Das stimmt wohl, ist für meinen(!) Anwendungszweck aber nicht ernsthaft
relevant. Nach weiterem Überlegen will ich die umschliessenden Klammern
ja gar nicht haben. Also

return this.replace(
/\{\{[^{}]*\}\}|\{(\d+)(,\s*([\w.]+))?\}/g,
^^^^ ^^^^ ^^ ^^
Also??ß

Quote:
function(m, a1, a2, a3) {
if (m[1] == '{') {
^^^^
return m.slice(1, -1);
Da `m' vom Typ string ist, funktioniert das nur in JavaScript.
Du solltest stattdessen

if (m.charAt(1) == '{')
{
// ...
}

verwenden.

Quote:
function(m, a1, a2, a3) {
if (m[1] == '{') return m;

In Deinen Format-Strings darf man also keine geschweiften Klammern
benutzen.

Probier's mal...
Stimmt, man kann sie benutzen, solange sie nicht doppelt vorkommen.

Quote:
Der Test prüft ganz einfach, welche der beiden Alternativen gematcht
hat.
Ja. Und bei einem einzelnen `{' wird keine davon gematcht. So weit,
so gut.

Quote:
var rpl = args[a1];
if (a3) {
var f = eval(a3);
^^^^
Lover not, wie der Engländer nie sagen würd'. Überleg mal, was
passieren kann, wenn man Deine Methode mit einer Benutzereingabe
füttert, beispielsweise

"{0,function spamMe() {...}; while (true) {spamMe();};}"

Dann war der Benutzer dumm.
Eher schlau. Bedenke, dass *Du* die _Sicherheitslücke_ öffnest. Der
Cracker muss sie nur ausnutzen. Deshalb wird das Script mit diesem
Ansatz wenig bis keine Verbreitung finden, und einen Programmierer,
der es (insbesondere, aber nicht nur, für ein kommerzielles Projekt)
unverändert einsetzt, muss man als inkompetent einstufen.

Quote:
Wenn ich schon einen flexible, dynamische Sprache habe, dann nutze
ich das auch.
Das kannst Du trotzdem und sogar noch flexibler haben, ohne die
Sicherheit zu kompromittieren, wie Du an meinem vorherigen Beispiel
siehst.

Quote:
Der Formatstring ist bei meiner Anwendung immer fest
vorgegeben, keine Benutzereingabe.
Du kennst anscheinend z.B. das Phänomen Buffer Overflow nicht.

Und Du schreibst Scripts offenbar nur für Dich selbst. Wenn
das Dein einziger Antrieb ist ...

Quote:
Das ist ein ganz typisches Szenario bei der Lokalisierung von
Programmtexten.
Ja, aber der fhcsale Ansatz.

Quote:
function CtoF(t) {
return (t * 9)/5 + 32;
}
alert('Today the temperature reached {0,CtoF}°F'.format(35));

Entsprechend:

alert(format('Today the temperature reached %d°F', CtoF(35)));

Das würde mir aber überhaupt nicht helfen.
Es macht nichts anderes als das, was Du tust, nur an anderer, sichererer
Stelle.

Quote:
Ich möchte beide Situationen einheitlich behandeln und dazu muss ich an
irgendeiner Stelle abstrahieren.
Die richtige Stelle dafür ist aber nicht der Format-String (jedenfalls
nicht in der jetzigen Form), sondern die Konvertierungsfunktion des
Wertes, CtoF(). Z.B. so:

var temp = 35;
alert(format(
'Today the temperature reached %d°' + (bUseFahrenheit ? 'F' : 'C'),
bUseFahrenheit ? CtoF(temp) : temp));

Alternativ könnte man einen Konvertierungsbezeichner für printf(3)
definieren, etwa `%T' (wäre noch nicht verplant) für °F oder °C je
nach Locale:

alert(format('Today the temperature reached %T', 35));

format() ruft dann nach Bedarf CtoF() mit dem übergebenen Argument
auf und fügt auch die passende Einheit hinzu.


PointedEars
--
Wer aufhört zu lernen, hört auf zu existieren.
-- altes jap. Sprichwort


Reply With Quote
  #5  
Old   
Michael Schuerig
 
Posts: n/a

Default Re: Strings formatieren - 05-29-2005 , 05:06 AM



Thomas 'PointedEars' Lahn wrote:

Quote:
Michael Schuerig wrote:

Printf ist aber nicht das, was ich haben will. Ich brauche die
Funktion zum lokalisieren von Strings mit interpolierten
(interpositionierten?)

`Interpoliert' sicher nicht. MUSEN schon eher das andere.
Anscheinend bezeichnet das aber praktisch jeder und sein Hund trotzdem
als Interpolation. Warum auch immer.

[Nicht maskierte '{' und '}']
Quote:
Danke. Korrigiert. Dummerweise hat es mit einem Browser doch
kompiliert.

Schlimm. Mit welchem?
Konqueror/kjs

Quote:
return this.replace(
/\{\{[^{}]*\}\}|\{(\d+)(,\s*([\w.]+))?\}/g,
^^^^ ^^^^ ^^ ^^
Also??ß
Also was?

Quote:
"{0,function spamMe() {...}; while (true) {spamMe();};}"

Dann war der Benutzer dumm.

Eher schlau. Bedenke, dass *Du* die _Sicherheitslücke_ öffnest. Der
Cracker muss sie nur ausnutzen. Deshalb wird das Script mit diesem
Ansatz wenig bis keine Verbreitung finden, und einen Programmierer,
der es (insbesondere, aber nicht nur, für ein kommerzielles Projekt)
unverändert einsetzt, muss man als inkompetent einstufen.
[schnipp]

Quote:
Der Formatstring ist bei meiner Anwendung immer fest
vorgegeben, keine Benutzereingabe.

Du kennst anscheinend z.B. das Phänomen Buffer Overflow nicht.
Oh, natürlich, ein Cracker könnte es sich noch viel einfacher machen und
einfach durch einen Proxy den Formatstring so ändern, dass sein
"spamMe" drin steht. Wenn er schon dabei ist, könnte er auch gleich
meine ganzen Skripte ignorieren und einfach seine bösen Sachen
einbauen.

Quote:
Und Du schreibst Scripts offenbar nur für Dich selbst. Wenn
das Dein einziger Antrieb ist ...
Thomas, ich schätze deine sachlichen Kommentare. Solche Bemerkungen
könntest du dir sparen. Sie sind unsachlich, reine Spekulation, in
ihrer Tendenz darauf angelegt, den Rezipienten als dumm darzustellen.

Zurück zur Sache. Du hältst meinem Ansatz vor, dass er eine
Sicherheitslücke öffnet. Ein sorgfältiger(er) Umgang mit diesem Vorwurf
ist geboten.

Ich halte deine bisherige Begründung für irrelevant. Ja, es kann bei
einer fehlerhaften Implementierung sein, dass eval es ermöglicht, per
Buffer-Overflow unerwünschten Code auszuführen. Bedeutsam wäre das,
wenn das einem Cracker _neue_ Angriffsmöglichkeiten gäbe. Das tut es
nicht. Der Formatstring, in dem auch der eval'te Text enthalten ist,
ist fest, keine Benutzereingabe. Zeige mir ein Szenario, in dem es ein
Angreifer gelingt, diesen Formatstring zu ändern -- wo er aber keine
andere, einfachere Möglichkeit hat, sein böses Werk zu tun. Die
Bedingung hinter dem Gedankenstrich ist wesentlich.


Quote:
Es macht nichts anderes als das, was Du tust, nur an anderer,
sichererer Stelle.
Die Stelle ist aber wichtig...


Quote:
Ich möchte beide Situationen einheitlich behandeln und dazu muss ich
an irgendeiner Stelle abstrahieren.

Die richtige Stelle dafür ist aber nicht der Format-String (jedenfalls
nicht in der jetzigen Form), sondern die Konvertierungsfunktion des
Wertes, CtoF(). Z.B. so:

var temp = 35;
alert(format(
'Today the temperature reached %d°' + (bUseFahrenheit ? 'F' :
'C'), bUseFahrenheit ? CtoF(temp) : temp));

Alternativ könnte man einen Konvertierungsbezeichner für printf(3)
definieren, etwa `%T' (wäre noch nicht verplant) für °F oder °C je
nach Locale:

alert(format('Today the temperature reached %T', 35));

format() ruft dann nach Bedarf CtoF() mit dem übergebenen Argument
auf und fügt auch die passende Einheit hinzu.
Nein. Im ersten Fall wird der Programmcode mit Präsentationslogik (frag
mich jetzt nicht, warum das gemeinhin als "Logik" bezeichnet wird)
überfrachtet. Stell dir vor, es würden Locale-abhängig ausserdem
Ausgaben in Kelvin benötigt. Bei Temperaturen war's das dann
hoffentlich, aber für andere Angaben kann es beliebig viele
Darstellungsformen geben, die potenziell gebraucht werden.
Der zweite Fall ist nicht erweiterbar, er erfüllt das
Open-Closed-Principle nicht. Werden weitere Formate benötigt, muss der
Code von format/printf geändert werden, was nicht wünschenswert ist.
Stattdessen sollen Erweiterungen _ohne_ Änderungen an bestehendem Code
möglich sein.

Michael

--
Michael Schuerig This is not a false alarm
mailto:michael (AT) schuerig (DOT) de This is not a test
http://www.schuerig.de/michael/ --Rush, Red Tide



Reply With Quote
  #6  
Old   
Thomas 'PointedEars' Lahn
 
Posts: n/a

Default Re: Strings formatieren - 05-29-2005 , 01:48 PM



Michael Schuerig wrote:

Quote:
Thomas 'PointedEars' Lahn wrote:
Michael Schuerig wrote:
Printf ist aber nicht das, was ich haben will. Ich brauche die
Funktion zum lokalisieren von Strings mit interpolierten
(interpositionierten?)
`Interpoliert' sicher nicht. MUSEN schon eher das andere.

Anscheinend bezeichnet das aber praktisch jeder und sein Hund
Die sind mir nicht bekannt.

Quote:
trotzdem als Interpolation. Warum auch immer.
Das kommt darauf an, was Du damit meinst. MUSEN ist Interpolation ein
mathematisches Verfahren (<http://de.wikipedia.org/wiki/Interpolation>).
Interposition (Dazwischenanordnung) ist MUSEN das, was Du mit den
Variablenwerten im String vorhast.

Quote:
[Nicht maskierte '{' und '}']
Danke. Korrigiert. Dummerweise hat es mit einem Browser doch
kompiliert.

Schlimm. Mit welchem?

Konqueror/kjs
Ich habe hier auch Konqueror. Mit welcher Version hast Du genau getestet?

Quote:
return this.replace(
/\{\{[^{}]*\}\}|\{(\d+)(,\s*([\w.]+))?\}/g,
^^^^ ^^^^ ^^ ^^
Also??ß

Also was?
Du schriebst, dass Du die geschweiften Klammern nicht ersetzen möchtest.
Ich übersah, dass das nur für einfache geschweifte Klammern gelten soll.
Der Quelltext erfüllt die genannte Anforderung.

Quote:
"{0,function spamMe() {...}; while (true) {spamMe();};}"
Dann war der Benutzer dumm.
Eher schlau. Bedenke, dass *Du* die _Sicherheitslücke_ öffnest. Der
Cracker muss sie nur ausnutzen. Deshalb wird das Script mit diesem
Ansatz wenig bis keine Verbreitung finden, und einen Programmierer,
der es (insbesondere, aber nicht nur, für ein kommerzielles Projekt)
unverändert einsetzt, muss man als inkompetent einstufen.

[schnipp]

Der Formatstring ist bei meiner Anwendung immer fest
vorgegeben, keine Benutzereingabe.
Du kennst anscheinend z.B. das Phänomen Buffer Overflow nicht.

Oh, natürlich, ein Cracker könnte es sich noch viel einfacher machen
und einfach durch einen Proxy den Formatstring so ändern, dass sein
"spamMe" drin steht. Wenn er schon dabei ist, könnte er auch gleich
meine ganzen Skripte ignorieren und einfach seine bösen Sachen
einbauen.
Ja. Aber *das* kannst Du nicht beeinflussen, mithin trägst Du dafür auch
keine Mitverantwortung. Für bekannte und nicht behobene Sicherheitslücken
schon.

Quote:
Und Du schreibst Scripts offenbar nur für Dich selbst. Wenn
das Dein einziger Antrieb ist ...

Thomas, ich schätze deine sachlichen Kommentare. Solche Bemerkungen
könntest du dir sparen. Sie sind unsachlich, reine Spekulation, in
ihrer Tendenz darauf angelegt, den Rezipienten als dumm darzustellen.
Nein, waren dazu ausgelegt, zu weitergehenden Überlegungen anzuregen.
Schade, hat (noch?) nicht geklappt.

Quote:
Zurück zur Sache. Du hältst meinem Ansatz vor, dass er eine
Sicherheitslücke öffnet. Ein sorgfältiger(er) Umgang mit diesem
Vorwurf ist geboten.
Noch sorgfältiger?

Quote:
Ich halte deine bisherige Begründung für irrelevant. Ja, es kann bei
einer fehlerhaften Implementierung sein, dass eval es ermöglicht, per
Buffer-Overflow unerwünschten Code auszuführen. Bedeutsam wäre das,
wenn das einem Cracker _neue_ Angriffsmöglichkeiten gäbe. Das tut es
nicht. Der Formatstring, in dem auch der eval'te Text enthalten ist,
ist fest, keine Benutzereingabe.
Das ist in *Deiner* Anwendung Deiner Methode so. Wenn aber jemand Deine
Methode wiederverwenden möchte, kann er damit nicht guten Gewissens
Benutzereingaben formatieren, weil die von Dir geschaffene Sicherheitslücke
existiert. Damit ist Dein Code nicht allgemein brauchbar und daher von
geringerem Wert als universell einsetzbarer Code.

Quote:
Zeige mir ein Szenario, in dem es ein Angreifer gelingt, diesen
Formatstring zu ändern -- wo er aber keine andere, einfachere
Möglichkeit hat, sein böses Werk zu tun. [...]
Nein. Es geht hierbei ums (Programmier-)Prinzip: Bei gutem Design
werden solche Fallen erkannt und durch eine geeignete Implementation
von vornherein vermieden.

Quote:
Es macht nichts anderes als das, was Du tust, nur an anderer,
sichererer Stelle.

Die Stelle ist aber wichtig...
Ja, es ist wichtig, dass die andere Stelle sicherer
ist, denn das beeinflusst wesentlich die Codequalität.

Quote:
[...]
var temp = 35;
alert(format(
'Today the temperature reached %d°' + (bUseFahrenheit ? 'F' :
'C'), bUseFahrenheit ? CtoF(temp) : temp));
[...]
alert(format('Today the temperature reached %T', 35));

format() ruft dann nach Bedarf CtoF() mit dem übergebenen Argument
auf und fügt auch die passende Einheit hinzu.

Nein. Im ersten Fall wird der Programmcode mit Präsentationslogik (frag
mich jetzt nicht, warum das gemeinhin als "Logik" bezeichnet wird)
überfrachtet. [...]
Der zweite Fall ist nicht erweiterbar, er erfüllt das
Open-Closed-Principle nicht. Werden weitere Formate benötigt, muss der
Code von format/printf geändert werden, was nicht wünschenswert ist.
Stattdessen sollen Erweiterungen _ohne_ Änderungen an bestehendem Code
möglich sein.
Man kann eben nicht alles haben. [psf 3.2]


PointedEars


Reply With Quote
  #7  
Old   
Thomas 'PointedEars' Lahn
 
Posts: n/a

Default Re: Strings formatieren - 05-29-2005 , 01:52 PM



Michael Schuerig wrote:

Quote:
Thomas 'PointedEars' Lahn wrote:
Michael Schuerig wrote:
Printf ist aber nicht das, was ich haben will. Ich brauche die
Funktion zum lokalisieren von Strings mit interpolierten
(interpositionierten?)
`Interpoliert' sicher nicht. MUSEN schon eher das andere.

Anscheinend bezeichnet das aber praktisch jeder und sein Hund
Die sind mir nicht bekannt.

Quote:
trotzdem als Interpolation. Warum auch immer.
Das kommt darauf an, was Du damit meinst. MUSEN ist Interpolation ein
mathematisches Verfahren (<http://de.wikipedia.org/wiki/Interpolation>).
Interposition (Dazwischenanordnung) ist MUSEN das, was Du mit den
Variablenwerten im String vorhast.

Quote:
[Nicht maskierte '{' und '}']
Danke. Korrigiert. Dummerweise hat es mit einem Browser doch
kompiliert.

Schlimm. Mit welchem?

Konqueror/kjs
Ich habe hier auch Konqueror. Mit welcher Version hast Du genau getestet?

Quote:
return this.replace(
/\{\{[^{}]*\}\}|\{(\d+)(,\s*([\w.]+))?\}/g,
^^^^ ^^^^ ^^ ^^
Also??ß

Also was?
Du schriebst, dass Du die geschweiften Klammern nicht ersetzen möchtest.
Ich übersah, dass das nur für einfache geschweifte Klammern gelten soll.
Der Quelltext erfüllt die genannte Anforderung.

Quote:
"{0,function spamMe() {...}; while (true) {spamMe();};}"
Dann war der Benutzer dumm.
Eher schlau. Bedenke, dass *Du* die _Sicherheitslücke_ öffnest. Der
Cracker muss sie nur ausnutzen. Deshalb wird das Script mit diesem
Ansatz wenig bis keine Verbreitung finden, und einen Programmierer,
der es (insbesondere, aber nicht nur, für ein kommerzielles Projekt)
unverändert einsetzt, muss man als inkompetent einstufen.

[schnipp]

Der Formatstring ist bei meiner Anwendung immer fest
vorgegeben, keine Benutzereingabe.
Du kennst anscheinend z.B. das Phänomen Buffer Overflow nicht.

Oh, natürlich, ein Cracker könnte es sich noch viel einfacher machen
und einfach durch einen Proxy den Formatstring so ändern, dass sein
"spamMe" drin steht. Wenn er schon dabei ist, könnte er auch gleich
meine ganzen Skripte ignorieren und einfach seine bösen Sachen
einbauen.
Ja. Aber *das* kannst Du nicht beeinflussen, mithin trägst Du dafür auch
keine Mitverantwortung. Für bekannte und nicht behobene Sicherheitslücken
schon.

Quote:
Und Du schreibst Scripts offenbar nur für Dich selbst. Wenn
das Dein einziger Antrieb ist ...

Thomas, ich schätze deine sachlichen Kommentare. Solche Bemerkungen
könntest du dir sparen. Sie sind unsachlich, reine Spekulation, in
ihrer Tendenz darauf angelegt, den Rezipienten als dumm darzustellen.
Nein, waren dazu ausgelegt, zu weitergehenden Überlegungen anzuregen.
Schade, hat (noch?) nicht geklappt.

Quote:
Zurück zur Sache. Du hältst meinem Ansatz vor, dass er eine
Sicherheitslücke öffnet. Ein sorgfältiger(er) Umgang mit diesem
Vorwurf ist geboten.
Noch sorgfältiger?

Quote:
Ich halte deine bisherige Begründung für irrelevant. Ja, es kann bei
einer fehlerhaften Implementierung sein, dass eval es ermöglicht, per
Buffer-Overflow unerwünschten Code auszuführen. Bedeutsam wäre das,
wenn das einem Cracker _neue_ Angriffsmöglichkeiten gäbe. Das tut es
nicht. Der Formatstring, in dem auch der eval'te Text enthalten ist,
ist fest, keine Benutzereingabe.
Das ist in *Deiner* Anwendung Deiner Methode so. Wenn aber jemand Deine
Methode wiederverwenden möchte, kann er damit nicht guten Gewissens
Benutzereingaben formatieren, weil die von Dir geschaffene Sicherheitslücke
existiert. Damit ist Dein Code nicht allgemein brauchbar und daher von
geringerem Wert als universell einsetzbarer Code.

Quote:
Zeige mir ein Szenario, in dem es ein Angreifer gelingt, diesen
Formatstring zu ändern -- wo er aber keine andere, einfachere
Möglichkeit hat, sein böses Werk zu tun. [...]
Nein. Es geht hierbei ums (Programmier-)Prinzip: Bei gutem Design
werden solche Fallen erkannt und durch eine geeignete Implementation
von vornherein vermieden. Nicht umsonst heisst es: eval is evil,
und zwar nicht nur in JS. Google ist Dein Freund. [psf 6.1]

Quote:
Es macht nichts anderes als das, was Du tust, nur an anderer,
sichererer Stelle.

Die Stelle ist aber wichtig...
Ja, es ist wichtig, dass die andere Stelle sicherer
ist, denn das beeinflusst wesentlich die Codequalität.

Quote:
[...]
var temp = 35;
alert(format(
'Today the temperature reached %d°' + (bUseFahrenheit ? 'F' :
'C'), bUseFahrenheit ? CtoF(temp) : temp));
[...]
alert(format('Today the temperature reached %T', 35));

format() ruft dann nach Bedarf CtoF() mit dem übergebenen Argument
auf und fügt auch die passende Einheit hinzu.

Nein. Im ersten Fall wird der Programmcode mit Präsentationslogik (frag
mich jetzt nicht, warum das gemeinhin als "Logik" bezeichnet wird)
überfrachtet. [...]
Der zweite Fall ist nicht erweiterbar, er erfüllt das
Open-Closed-Principle nicht. Werden weitere Formate benötigt, muss der
Code von format/printf geändert werden, was nicht wünschenswert ist.
Stattdessen sollen Erweiterungen _ohne_ Änderungen an bestehendem Code
möglich sein.
Man kann eben nicht alles haben. [psf 3.2]


PointedEars


Reply With Quote
  #8  
Old   
Michael Schuerig
 
Posts: n/a

Default Re: Strings formatieren - 05-29-2005 , 02:32 PM



Thomas 'PointedEars' Lahn wrote:

Quote:
Michael Schuerig wrote:

Thomas 'PointedEars' Lahn wrote:
Michael Schuerig wrote:
Printf ist aber nicht das, was ich haben will. Ich brauche die
Funktion zum lokalisieren von Strings mit interpolierten
(interpositionierten?)
`Interpoliert' sicher nicht. MUSEN schon eher das andere.

Anscheinend bezeichnet das aber praktisch jeder und sein Hund

Die sind mir nicht bekannt.

trotzdem als Interpolation. Warum auch immer.

Das kommt darauf an, was Du damit meinst. MUSEN ist Interpolation ein
mathematisches Verfahren
(<http://de.wikipedia.org/wiki/Interpolation>). Interposition
(Dazwischenanordnung) ist MUSEN das, was Du mit den Variablenwerten im
String vorhast.
Um einen Eindruck zu bekommen, suche mal nach interpolation.pm.

Quote:
Konqueror/kjs

Ich habe hier auch Konqueror. Mit welcher Version hast Du genau
getestet?
3.4.0

Quote:
Der Formatstring, in dem auch der eval'te Text enthalten ist,
ist fest, keine Benutzereingabe.

Das ist in *Deiner* Anwendung Deiner Methode so. Wenn aber jemand
Deine Methode wiederverwenden möchte, kann er damit nicht guten
Gewissens Benutzereingaben formatieren, weil die von Dir geschaffene
Sicherheitslücke existiert.
Das ist richtig und dazu ist die Methode nicht gedacht. Du wirst in C
einem Benutzer auch nicht guten Gewissens die Möglichkeit geben, den
Formatstring für ein printf zu definieren.

Quote:
Damit ist Dein Code nicht allgemein brauchbar und daher
von geringerem Wert als universell einsetzbarer Code.
Den "universell einsetzbaren Code", der gleich mächtig ist, habe ich
aber noch nicht gesehen.

Quote:
Zeige mir ein Szenario, in dem es ein Angreifer gelingt, diesen
Formatstring zu ändern -- wo er aber keine andere, einfachere
Möglichkeit hat, sein böses Werk zu tun. [...]

Nein. Es geht hierbei ums (Programmier-)Prinzip: Bei gutem Design
werden solche Fallen erkannt und durch eine geeignete Implementation
von vornherein vermieden. Nicht umsonst heisst es: eval is evil,
und zwar nicht nur in JS. Google ist Dein Freund. [psf 6.1]
Ich weiss, das eval in vielen Situationen bösartig ist. Es ist nicht
auszuschliessen, dass ich das schon länger weiss, als du überhaupt
programmierst. Ich behalte mir vor, eval und Konsorten, goto,
gegebenenfalls auch comefrom (AOP...) zu verwenden, wenn ich das
jeweilige Mittel als geeignet ansehe.

Quote:
Es macht nichts anderes als das, was Du tust, nur an anderer,
sichererer Stelle.

Die Stelle ist aber wichtig...

Ja, es ist wichtig, dass die andere Stelle sicherer
ist, denn das beeinflusst wesentlich die Codequalität.
In diesem Fall aus meiner Sicht zum Schlechteren.

[Vorschlag von immer wieder neuen Erweiterungen eines "printf"-alike
format.]

Quote:
Man kann eben nicht alles haben. [psf 3.2]
Stimmt. Meine Entscheidung ist hier anders ausgefallen als Deine, bei
Berücksichtigung der selben Fakten. Ich habe die Flexibilität des Codes
höher gewertet als die Missbrauchsgefahr in einem nicht vorgesehenen
Einsatzszenario. Deine Entscheidung ist anders herum. Das steht dir
genauso frei, wie mir meine Entscheidung. Es nützte da auch nichts,
darauf zu bestehen, dass du aber bestimmt trotzdem recht habest.
Vergiss es, so geht's nicht. Zeige mir eine Implementierung der
Funktionalität, die meine Anforderung an Flexibilität und
Open-Closed-Principle erfüllt und ich werde dem gegenüber sehr
aufgeschlossen sein. Rechthaberei dagegen ist langweilig.

Michael

--
Michael Schuerig Airtight arguments have
mailto:michael (AT) schuerig (DOT) de vacuous conclusions.
http://www.schuerig.de/michael/ --A.O. Rorty, Explaining Emotions



Reply With Quote
  #9  
Old   
Thomas 'PointedEars' Lahn
 
Posts: n/a

Default Re: Strings formatieren - 05-29-2005 , 02:57 PM



Thomas 'Ingrid' Lahn wrote:

Quote:
Michael Schuerig wrote:
Thomas 'PointedEars' Lahn wrote:
[Nicht maskierte '{' und '}']
Danke. Korrigiert. Dummerweise hat es mit einem Browser doch
kompiliert.
Schlimm. Mit welchem?
Konqueror/kjs

Ich habe hier auch Konqueror. Mit welcher Version hast Du genau getestet?
Ich habe in

Mozilla/5.0 (compatible; Konqueror/3.3; Linux 2.4.30-20050424.190414+0200;
X11; i686; de, en_US) KHTML/3.3.2 (like Gecko)

getestet.

alert(/{{.*?}}/.test("{{}}"));

liefert dort tatsächlich `true' statt eines Syntaxfehlers wie in

Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8) Gecko/20050517
Firefox/1.0.4 (Debian package 1.0.4-2) Mnenhy/0.7.2.0

Und o.g. ist sogar eine gültige PCRE

,-<http://www.pcre.org/pcre.txt>
Quote:
[...]
REPETITION

A closing brace on its own is not a special character. [...]
An opening curly bracket that appears in a position where a quantifier is
not allowed, or one that does not match the syntax of a quantifier, is
taken as a literal character. For example, {,6} is not a quantifier, but
a literal string of four characters. [...]
aber eben nicht zu ECMAScript 3 kompatibel:

,-<ECMAScript 3, aktuelle Version vom 2000-03-24>
Quote:
[...]
15.10.1 Patterns

The RegExp constructor applies the following grammar to the input pattern
string. An error occurs if the grammar cannot interpret the string as an
expansion of Pattern.

Syntax

Pattern ::
Disjunction

Disjunction ::
Alternative
Alternative | Disjunction

Alternative ::
[empty]
Alternative Term

Term ::
Assertion
Atom
Atom Quantifier

Assertion ::
^
$
\ b
\ B

Quantifier ::
QuantifierPrefix
QuantifierPrefix ?

QuantifierPrefix ::
*
+
?
{ DecimalDigits }
{ DecimalDigits , }
{ DecimalDigits , DecimalDigits }

Atom ::
PatternCharacter
.
\ AtomEscape
CharacterClass
( Disjunction )
( ? : Disjunction )
( ? = Disjunction )
( ? ! Disjunction )

PatternCharacter :: SourceCharacter but not any of:
^ $ \ . * + ? ( ) [ ] { } |
Womit klar ist, dass PCRE ECMAScript-konformen REs zwar ähnlich sind,
letztere aber nicht zu ersteren kompatibel sind (was für mich neu ist).


PointedEars
--
Schweigend mitzulesen ist oft der einzige Weg, nicht als Trottel dazustehen.
-- Jakob Creutzig in dag° <xiveld1n1ef.fsf (AT) kendall (DOT) math.TU-Berlin.DE>


Reply With Quote
  #10  
Old   
Thomas 'PointedEars' Lahn
 
Posts: n/a

Default Re: Strings formatieren - 05-29-2005 , 03:25 PM



Michael Schuerig wrote:

Quote:
Thomas 'PointedEars' Lahn wrote:
Michael Schuerig wrote:
[{{ ist im Testbrowser eine gültige RegExp]
Ich habe hier auch Konqueror. Mit welcher Version hast Du genau
getestet?

3.4.0
Dann gibt's den Fehler also schon seit mindestens v3.3.

Quote:
Der Formatstring, in dem auch der eval'te Text enthalten ist,
ist fest, keine Benutzereingabe.

Das ist in *Deiner* Anwendung Deiner Methode so. Wenn aber jemand
Deine Methode wiederverwenden möchte, kann er damit nicht guten
Gewissens Benutzereingaben formatieren, weil die von Dir geschaffene
Sicherheitslücke existiert.

Das ist richtig und dazu ist die Methode nicht gedacht. Du wirst in C
einem Benutzer auch nicht guten Gewissens die Möglichkeit geben, den
Formatstring für ein printf zu definieren.
Doch, das ist aufgrund der klaren Definition von printf(3) gänzlich
ungefährlich (wie Du nach Lesen der Manpage hättest wissen können) und
findet daher vielfach Anwendung, z.B. bei xmms, meinem mp3-Bläher.

Quote:
Es geht hierbei ums (Programmier-)Prinzip: Bei gutem Design
werden solche Fallen erkannt und durch eine geeignete Implementation
von vornherein vermieden. Nicht umsonst heisst es: eval is evil,
und zwar nicht nur in JS. Google ist Dein Freund. [psf 6.1]

Ich weiss, das eval in vielen Situationen bösartig ist. Es ist nicht
auszuschliessen, dass ich das schon länger weiss, als du überhaupt
programmierst. [...]
*Gähn* Mal wieder eine neue Variante von Hellinger's Law. You lose.

Quote:
Damit ist Dein Code nicht allgemein brauchbar und daher
von geringerem Wert als universell einsetzbarer Code.

Den "universell einsetzbaren Code", der gleich mächtig ist, habe
ich aber noch nicht gesehen.
Dein Problem.


PointedEars
--
Exponentielles Wachstum ist so ungefähr das Schlimmste, was einem
System passieren kann. [...] Da geht's ab wie die Post! Mehr muss
man eigentlich gar nicht darüber wissen.
-- Prof. Dr. Harald Lesch in "Lesch & Co. 2: Geist und Materie"


Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.