Setting a renderer on JComboBox
When setting a custom renderer to a JComboBox, the usual way is to extend a DefaultListCellRenderer and override the getListCellRendererComponent() method. However, this may lead to ugly comboboxes on some Look and Feels. As you can see on the top combobox, it is rendered considerably smaller and with the letters sticked to the left border, just by using a DefaultListCellRenderer. The Look and Feel seems to use a special renderer class for proper rendering, as it is shown in the combobox below.
A solution is to use a proxy ListCellRenderer instead, which only converts the value and then delegates the rendering to the original renderer. For example:
public class ListCellRendererProxy implements ListCellRenderer {
private final ListCellRenderer delegate;
public ListCellRendererProxy(ListCellRenderer delegate) {
this.delegate = delegate;
}
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
// modify the value here...
return delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
}
The renderer proxy can be used like this:
JComboBox cbx = new JComboBox(); ListCellRenderer oldRenderer = cbx.getRenderer(); cbx.setRenderer(new ListCellRendererProxy(oldRenderer));
The combobox items are now converted to a string by a custom cell renderer, but are still rendered by the original renderer implementation of the current Look and Feel. However, while a single DefaultListCellRenderer instance can be shared with many JComboBox, a new renderer proxy needs to be instanciated per combobox.
Métro endlich für Android
Eigentlich bin ich ja glücklich auf Android umgestiegen. Es gibt nur eine App meines guten alten Palm TX, die ich wirklich vermisse: Métro. Mit dem Programm kann man sich in etlichen Städten der Welt eine Route mit öffentlichen Verkehrsmitteln berechnen lassen. Auch wenn keine richtigen Fahrpläne, sondern nur Streckenpläne verwendet werden, ist die Datenbank dank des Alters von Métro sehr umfangreich und wird gut gepflegt. Mir hat Métro auf etlichen Städtetouren und auch daheim viel Zeit und Umwege erspart. Es ist einfach unverzichtbar.
Schon lange versprechen die Entwickler, auch eine Android-Version herauszubringen. Und jetzt ist es endlich soweit!
Das Tool ist allerdings noch in einem recht frühen Stadium. Ein paar Features, die ich in der Palm-Version lieb gewonnen habe, fehlen. Außerdem ist die App nicht im Market und muss direkt installiert werden. Aber das ist alles sicherlich nur eine Frage der Zeit. Métro für Android erfüllt jedenfalls schon jetzt seine eigentliche Aufgabe.
Und jetzt kann ich meinen Palm TX endlich ganz einmotten. 
PHP 5.3.7, eine Analyse
Das PHP-Entwicklerteam veröffentlichte vor wenigen Tagen die Version 5.3.7, nur um schon wenige Tage später vor deren Verwendung zu warnen. Der Grund dafür war ein Fehler in der Funktion crypt(), welche bei bestimmten Hash-Verfahren lediglich das Salt zurückliefert. Das kann dazu führen, dass nach einem Update auf PHP 5.3.7 keine Benutzer sich mehr auf einem Webauftritt einloggen können oder sich bei einer Passwortänderung nach einem Update auf eine spätere PHP-Version nicht mehr einloggen können. In PHP 5.3.8 wurde der Fehler wieder behoben.
Dieser Artikel ist der Versuch einer Analyse, wie es zu dem Fehler kam und warum er erst nach der Release bemerkt wurde.
Die PHP-Funktion crypt() ist in der Datei php_crypt_r.c implementiert. Folgender Codeausschnitt baut dort den Passwort-Hash zusammen:
memcpy(passwd, MD5_MAGIC, MD5_MAGIC_LEN); strlcpy(passwd + MD5_MAGIC_LEN, sp, sl + 1); strcat(passwd, "$");
strcat() fügt eine Zeichenkette an das Ende eines Puffers. Die Funktion gilt als unsicher, da sie nicht prüft, ob der Zielpuffer genügend Speicherplatz zur Verfügung stellt. Wird die Zeichenkette zu lang, wird der nachfolgende Speicherbereich beschädigt – ein typisches Problem bei C-Sprachen.
Aus dem Grund wurde der Aufruf durch eine sicherere Funktion ersetzt. Leider ist aber gut gemeint das Gegenteil von gut gemacht.
memcpy(passwd, MD5_MAGIC, MD5_MAGIC_LEN); strlcpy(passwd + MD5_MAGIC_LEN, sp, sl + 1); strlcat(passwd, "$", 1);
strlcat() stellt sicher, dass der Puffer nicht über sein Ende hinaus beschrieben wird. Dazu wird dessen Größe übergeben. Und genau hier lag das Problem, denn statt der Größe von passwd wurde anscheinend die Größe des zu kopierenden Textes übergeben, nämlich 1. Da passwd zu dem Zeitpunkt bereits deutlich mehr als ein Zeichen enthält, tut strlcat() genau das, was es tun soll, nämlich gar nichts. Das “$”-Zeichen wird nicht angehängt, das tatsächliche Ergebnis weicht damit von dem gewünschten Ergebnis ab.
Solch ein Fehler ist eigentlich ein Lehrbuchbeispiel für Unit-Tests, und der Kommentar zum Bugfix (Revision 315218) deutet auch an, dass ein solcher existiert:
Unbreak crypt() (fix bug #55439)
# If you want to remove static analyser messages, be my guest,
# but please run unit tests after
Tatsächlich gibt es einen Test, der die crypt()-Funktion mit bestimmten Werten aufruft und das Ergebnis mit einem erwarteten Ergebnis vergleicht. Dieser Test schlägt Alarm, wenn er ausgeführt wird.
Dass PHP 5.3.7 dennoch veröffentlicht wurde, lässt eigentlich nur einen Schluss zu: Der Unit-Test wurde nicht ausgeführt oder der Alarm wurde schlichtweg ignoriert. Spätestens beim Bau der finalen Version unmitelbar vor der Veröffentlichung hätte dies aber stattfinden müssen. Alles andere wäre grob fahrlässig.
Zusammengefasst hatte der Fehler also folgende Ursachen:
- die für C-Sprachen üblichen Probleme bei der sicheren Verarbeitung von Zeichenketten
- eine missverständliche oder nicht verstandene Dokumentation der Funktion
strlcat() - keine verbindlich vorgeschriebene fehlerfreie Ausführung der Unit-Tests vor der Freigabe einer Release
Insbesondere der letzte Punkt wiegt schwer und wirft ein schlechtes Licht auf die verantwortlichen PHP-Entwickler.
Abschalten!
Schon Peter Lustig verkündete diese Aufforderung am Ende jeder Löwenzahn-Sendung. Aber was tun, wenn der Computer nicht will?
Einige Systeme mit Fedora 15 sind von dem Bug im Kernel betroffen. Der Rechner fährt dann zwar normal herunter und geht aus, schaltet sich nach wenigen Sekunden aber wieder ein und fährt erneut hoch. Zuverlässig abschalten lässt er sich nicht, was besonders bei Computern lästig ist, auf die man nur schlechten oder gar keinen Zugriff hat. Bei mir sind von vier Fedora 15-Systemen zwei von diesem Bug betroffen, die Quote scheint also recht hoch zu sein.
Bis der Bug beseitigt ist, kann man sich behelfen, indem man mit Root-Rechten an die Datei /etc/rc.local folgende Zeile an das Ende anfügt:
echo " LID" > /proc/acpi/wakeup
(Das Leerzeichen vor LID ist beabsichtigt!)
Nach dem nächsten Neustart lässt sich der Rechner dann wieder zuverlässig herunterfahren. Und sobald der Kernel-Bug beseitigt ist, kann die Zeile auch wieder aus der /etc/rc.local entfernt werden.
Fotos der Japan-Tour 2010 sind online
Letztes Jahr (also noch vor Fukushima, als die Welt noch in Ordnung war) haben wir uns einen langen Wunsch erfüllt und eine zehntägige Reise durch Japan gemacht.
Aus Sorge vor der Sprach- und Kulturbarriere war es eine geführte Bustour mit mehreren Stationen:
Als kleines Extra habe ich außerdem noch eine Kuriosa-Sammung zusammengestellt.
Zusammengefasst gibt es die Tour unter dem Tag Japan 2010.
Insgesamt war es eine wunderbare, interessante und lehrreiche Reise, und wir planen bereits den nächsten Besuch. Diesmal aber ohne Bustour, sondern auf eigene Faust. Japan ist eines der sichersten Reiseländer der Welt, und mit viel Geduld und ein wenig Englisch kriegt man die meisten Probleme bewältigt.
Wie in meinem Blog (in der Beta-Phase) üblich, habe ich die einzelnen Artikel auf den richtigen Zeitraum zurückdatiert. Viel Spaß beim Betrachten!
Pimp my Gnome, Teil 5: Schneller zum Ziel
Gnome 3 lässt sich um einiges schneller und komfortabler bedienen, wenn man die richtigen Abkürzungen kennt.
Eine ausführliche Liste hat das Gnome-Team in seinem Gnome Shell Cheat Sheet zusammengestellt. In diesem Artikel gibt es eine Auswahl der wichtigsten Kürzel.
Pimp my Gnome, Teil 4: Zwei Bildschirme und Wetter-Update
Ich hatte nun die Gelegenheit, Gnome 3 an einem System mit zwei Bildschirmen zu verwenden. Grundsätzlich funktioniert es, aber das Verhalten war dennoch überraschend. Wenn man nach dem Thema im Internet sucht, findet man außerdem Hinweise darauf, dass bei zwei Bildschirmen mit unterschiedlichen Auflösungen oder bei mehr als zwei Bildschirmen die Bedienung problematisch sein kann.
Seit den letzten Artikeln hat sich außerdem bei den Extensions etwas getan.
Pimp my Gnome, Teil 3: Bugs und Workarounds
Gnome 3 ist noch recht jung und hat hier und da noch ein paar Ecken und Kanten, die hoffentlich bald geradegeschliffen sind. Bis dahin müssen wir uns mit so genannten Workarounds behelfen.
Der Übergang zwischen Bug und Feature ist bekanntermaßen fließend, so dass manches von dem Folgenden vielleicht besser in den Teil 2 gepasst hätte. Wie auch immer, packen wir’s an...
Pimp my Gnome, Teil 2: Geschmacksfragen
Das Design von Gnome 3 ist wohldurchdacht. Einstellmöglichkeiten sind kaum vorgesehen, man möchte den Anwender nicht durch zu viele Einstellschrauben verwirren. So attraktiv ein einheitlicher “Desktop von der Stange” auf unerfahrene Anwender wirken mag, so abschreckender wirkt er auf Anwender, die entsprechendes Wissen haben und sich ihre Arbeitsoberfläche maßschneidern möchten.
Mit ein paar Kniffen kann man aber trotzdem Anpassungen vornehmen. Dieser Artikel beschreibt ein paar davon.
Pimp my Gnome, Teil 1: Extensions
Man kann es nicht schönreden: Ein standardmäßig installiertes Gnome 3 hat in etwa den Coolness-Faktor einer Waschmaschine und den Bedienkomfort eines Plattenspielers. Nachdem sich der erste Schock gelegt hat, wird es nun Zeit zu schauen, wie sich zumindest die gröbsten Unzulänglichkeiten beseitigen lassen. Dieser Mehrteiler mit offenem Ende nennt sich “Pimp my Gnome” und wird die Tricks dokumentieren, die ich auf dem Weg zu meinem erhofften Gnome 3-Glück finden werde.
Den Anfang machen die Gnome Extensions. Und die sind tatsächlich ziemlich cool.
