Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 2ae70bd4

Von Moritz Bunkus vor fast 5 Jahren hinzugefügt

  • ID 2ae70bd488265cab4a7cef8243b3660f7d35e83e
  • Vorgänger 63cb5b41
  • Nachfolger cd6bfeee

_make_record(_item): Zahlenattribute nicht mit leeren Strings setzen

Wir übergeben diverse Zahlenfelder als hidden inputs, ohne dass wir
prüfen, ob die überhaupt gesetzt sind:

1. Im Aufruf 1 ist z.B. `$::form->{customer_id} = undef`, oder es gibt
sogar nicht mal ein `$::form->{customer_id}`.
2. Dies wird ohne Prüfung auf den tatsächlichen Wert als Hidden
ausgegeben, und endet damit als `<input type="hidden"
name="customer_id" value="">`.
3. In Aufruf 2 kommt das dann als `$::form->{customer_id} = ''` an,
also als leerer String, egal, ob der Wert vorher `undef`, ein
leerer String war oder gar nicht existiert hat.

Wenn man nun, wie `_make_record_item`, über alle Schlüssel aus
`$::form` iteriert, und die korrespondierenden
Attributs-Setter-Funktionen einer RDBO-Instanz mit ihnen aufruft, so
werden somit Zahlen-Setter-Funktionen mit leeren Strings
aufgerufen. Das sorgt dafür, dass später bei einem Aufruf von
`$invoice->customer` versucht wird, ein Customer-Objekt aus der DB zu
laden (da ja durch den Aufruf von `…->customer_id(…)`, also das Setzen
des Relationship-Attributs, signalisiert wurde, dass die Relationship
aktiv ist).

Allerdings ist der Wert des Primärschlüsselattributes nun der leere
String, also im Perl-Sinne `false`. Das wiederum wertet Rose als
Versuch, ein Objekt ohne Angabe eines Primärschlüsselattributs zu
laden, was wiederum zu einer Fehlermeldung führt.

Kurz: Zahlenattribute aus RDBO-Instanzen dürfen gar nicht erst auf
leere Strings gesetzt werden. Sie dürfen nur gesetzt werden, wenn sie
auch tatsächliche Zahlenwerte enthalten sollen.

Fix #57.

Unterschiede anzeigen:

bin/mozilla/io.pl
1896 1896
      if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) {
1897 1897
        $obj->${\"$method\_as_date"}($value);
1898 1898
      } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Numeric|Float|DoublePrecsion)$/) {
1899
        $obj->${\"$method\_as_number"}($value);
1899
        $obj->${\"$method\_as_number"}(($value // '') eq '' ? undef : $value);
1900 1900
      } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::Boolean$/) {
1901 1901
        $obj->$method(!!$value);
1902
      } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Big)?(?:Int(?:eger)?|Serial)$/) {
1903
        $obj->$method(($value // '') eq '' ? undef : $value * 1);
1902 1904
      } else {
1903 1905
        $obj->$method($value);
1904 1906
      }
......
1947 1949
    if ($obj->meta->column($method)->isa('Rose::DB::Object::Metadata::Column::Date')) {
1948 1950
      $obj->${\"$method\_as_date"}($::form->{$method});
1949 1951
    } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Numeric|Float|DoublePrecsion)$/) {
1950
      $obj->${\"$method\_as_number"}($::form->{$method});
1952
      $obj->${\"$method\_as_number"}(($::form->{$method} // '') eq '' ? undef : $::form->{$method});
1951 1953
    } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::Boolean$/) {
1952 1954
      $obj->$method(!!$::form->{$method});
1955
    } elsif ((ref $obj->meta->column($method)) =~ /^Rose::DB::Object::Metadata::Column::(?:Big)?(?:Int(?:eger)?|Serial)$/) {
1956
      $obj->$method(($::form->{$method} // '') eq '' ? undef : $::form->{$method} * 1);
1953 1957
    } else {
1954 1958
      $obj->$method($::form->{$method});
1955 1959
    }

Auch abrufbar als: Unified diff