phpbar.de logo

Mailinglisten-Archive

[php] SID in den Bookmarks

[php] SID in den Bookmarks

Markus Dobel php_(at)_phpcenter.de
Fri, 29 Jun 2001 21:04:21 +0200


On Fri, Jun 29, 2001 at 10:32:43AM +0200, Andreas Otto wrote:
> Hi Markus,
> 
> > Das INSERT durch ein REPLACE zu ersetzen macht die Klasse ct_sql
> > MySQL-Spezifisch. Mein Patch funktioniert mit allen Datenbanken, da
> > generisches SQL.
> 
> Wie sieht denn Dein Patch aus? Da ich gerade an einem völlig von
> Frames verseuchten Projekt arbeite hatte ich mir bislang damit
> geholfen page_close() nicht in jeder Datei auzurufen. Ist aber
> fehleranfällige Fleissarbeit.

Patch: Siehe ein paar Postings weiter oben. Leider scheint es keinen
aktiven PHPlib-Maintainer zu geben, bzw dieser scheint keine Lust/Zeit
zu haben, diesen Patch irgendwie einzuarbeiten *und* auch zu releasen.

Ob das bei Frames wirklich hilft weiss ich aber nicht, bzw. ich bin mir
sicher, dass es das Problem mit Frames nicht beseitigt. Sessions in der
PHPlib-Implementation (In der PHP4-Version wahrscheinlich auch)
vertrauen darauf, dass zu einem Zeitpunkt zu einer Session nur ein
geoeffnetes Dokument gehoert. Bei Frames kann es (kommt es vielleicht
sogar zwangslaeufig?) Dazu, dass zwei oder mehr Dokumente gleichzeitig
bearbeitet werden und somit konkurrierende page_open/closes laufen.
Dadurch kannst Du Dir die Session-Variablen zerschiessen. Beispiel: Man
stelle sich vor, Frame1 und Frame2 werden parallel verarbeitet.

Frame1: 
page_open(); // $s ist eine session-var und hat z.B. jetzt den Wert 2
$s++;

(Meanwhile in a secret room) Frame2:
page_open(); // An dieser Stelle hat $s immernoch 2, weil in
             // Frame1 noch kein page_close() kam.
$unwichtigevariable=bla;

(Wir befinden uns wieder in Frame1)
page_close();  // Seite ist zuende, $s ist 3 und so gespeichert.

(Wieder in Frame2)
page_close();  

So. und gerade eben haben wir $s wieder mit dem Wert 2 ueberschrieben.
Sollte $s eine wichtige Variable gewesen sein, darf man *jetzt*
anfangen, zu weinen. Um das zu vermeiden, muesste man staendig den
lokalen Variablenbestand gegen den gespeicherten synchronisieren. Das
wird teuer, aufwendig und kompliziert.

Der Patch hilft nur dagegen, dass MySQL moppert, wenn man zweimal
innerhalb einer Sekunde die selbe Session updated und waehrenddessen
keine Aenderungen an den Session-Variablen vorgenommen hat. Man spricht
dabei von Lochfrass bzw. Race Condition. 

<detail OT-ness="medium"> 

  In diesem Fall gibt mysql_affected_rows() naemlich 0 zurueck, da in
  mysql_affected_rows() die Anzahl der durch den Update
  *veraenderten* Zeilen zurueckgibt, und nicht etwa die Anzahl der durch
  die WHERE-Clause *gematchten* Zeilen. Andere Datenbanken scheinen die
  zweite Variante zurueckzugeben. 

  Btw.: Mangels anderer Datenbanken kann ich das hier nicht
  nachvollziehen, wuesste es aber gern genau. Was gibt Eure
  Lieblingsdatenbank fuer affected_rows zurueck, wenn man ein 

    UPDATE tabelle SET spalte=spalte;

  ausfuehrt? Bei MySQL ist es 0, obwohl im Prinzip alle Spalten angefasst
  wurden. Oder noch interessanter:

    UPDATE tabelle SET spalte=spalte*spalte;

  Speziell, wenn der Wert von spalte 0 oder 1 ist. 

  Die MySQL-CLI unterscheidet da auch zwischen "gefunden" (Match in der
  WHERE-Clause bzw. "alle", wenns keine WHERE-Clause gibt) und
  "geaendert", und diese Zahlen stimmen auch. In PHP durch die Funktion
  mysql_affected_rows() verfuegbar ist nur der "geaendert"-Wert.
  ct_sql braeuchte an der besagten Stelle den anderen. Das Wort
  "affected" ist hier zweideutig und es wird in der Doku leider auch
  nicht genauer erlaeutert.

</detail>

Genau das passiert ja bei Frames auch, deutet da aber darauf hin, dass
man potentiell wichtige Session-Daten vernichtet (In diesem Fall wuerde
uebrigens dann die "Duplicate..."-Meldung netterweise nicht kommen).
Wenn Du nichts kaputtmachen willst, solltest Du also bei
Frames-Applikationen immer nur *in einem Frame* Session-Daten
aendern... und Dich in den anderen Frames nicht drauf verlassen, dass
sie immer den erwarteten Wert haben.

Ich hatte den "Fehler" hier Aufgrund von http-Redirects im schnellen
LAN, wo auch in einer Sekunde zwei mal die Session-Daten unveraendert
refreshed wurden. Aber eben sequentiell (und somit ungefaehrlich) und
nicht parallel.

Gruss, Mar "genug getippert... Wochenende" kus

-- 
Spiegel-Leser wissen mehr. Fuer ein Semester-Abo!
http://www.kawo2.rwth-aachen.de/~mdobel/semesterabo.html


php::bar PHP Wiki   -   Listenarchive