Booleans in PHP

PHP bezieht viele Einstellungen aus der php.ini und weiteren webserverspezifischen Dateien. Verschiedene PHP-Pakete prüfen die Einstellungen, um dem Nutzer auf Fehlkonfigurationen hinzuweisen. Wenn man aber nicht korrekt vergleicht, geht es richtig schief.

Der Code, der das Problem auslöst, ist Teil eines Webmailers:

$crit_opts = array(
   'mbstring.func_overload' => 0,
   'suhosin.session.encrypt' => 0,
   'session.auto_start' => 0,
   'file_uploads' => 1,
);
foreach ($crit_opts as $optname => $optval) {
   if ($optval != ini_get($optname)) {
      die("ERROR: Wrong '$optname' option value. Read REQUIREMENTS section in INSTALL file or use Roundcube Installer, please!");
   }
}

Gemäß Dokumentation liefert die Funktion get_ini von Flags (also Boolean-Werten) nur die Werte "0" oder "1"

A boolean ini value of "off" will be returned as an empty string or "0"
while a boolean ini value of "on" will be returned as "1".
The function can also return the literal string of INI value.

Der letzte Satz ist aber erst mit PHP 5.1 dazugekommen. So gesehen kann die Funktion mittlerweile "alles" liefern.

Man soll – wenn man die Werte benötigt – diese mit der neuen Funktion filter_var nachbearbeiten. Diese bietet eine explizite Filterfunktion für die Booleanswerte, die in der php.ini akzeptiert werden.

Ein kurzes Testscript zeigt das Problem deutlich:

<?
foreach (array(0,1,'on','off','yes','no','false','true') as $i) {
    print "$i - ";
    var_dump(filter_var($i,FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE));
    print "<br/>\n";
}
var_dump(ini_get('file_uploads'),
         filter_var(ini_get('file_uploads'),
                    FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)
         );
?>

Dieses liefert dann die folgenden Ergebnisse

0 - bool(false)  
1 - bool(true) 
on - bool(true) 
off - bool(false) 
yes - bool(true) 
no - bool(false) 
false - bool(false) 
true - bool(true) 
string(2) "On" bool(true) 

Es ist deutlich zu sehen, daß ini_get den Wert "On" liefert, der natürlich nicht der erwarteten "1" im Webmailercode entspricht.

Der Webmailer muß angepaßt werden. Er hat die Vergleiche in kanonischer Form durchzuführen. (Nicht vorhandene Variablen sind als "Falsch" zu betrachten.)

foreach ($crit_opts as $optname => $optval) {
    if (filter_var($optval,FILTER_VALIDATE_BOOLEAN)
       !==
       filter_var(ini_get($optname),FILTER_VALIDATE_BOOLEAN)) {
      die("ERROR: Wrong '$optname' option value. Read REQUIREMENTS section in INSTALL file or use Roundcube Installer, please!");
   }
}

Und tut.

Avatar
Lutz Donnerhacke 20.06.2013 15:18
Und der Bug ist geschlossen. http://trac.roundcube.net/changeset/39b905b7a8abafe57f5429952db390a97ffa047f/github
Avatar
Lutz Donnerhacke 20.06.2013 14:15
Bugticket ist offen: http://trac.roundcube.net/ticket/1489189

2 Kommentare

Post a comment

Verwandter Inhalt