Archive for October 2010
Bug berbahaya PostgreSQL+Zeos+Delphi
Kemarin satu-dua jam saya cari-cari bug yang menyebabkan objek yang saya buat tidak bisa menembus unit test. Cukup lama mencarinya karene bugnya kecil dan kejadiannya jarang sekali. Tetapi akibatnya bisa sangat berbahaya. Untung saya pakai unit test sehingga bug seperti ini bisa terekspose.
Saya menggunakan PostgreSQL sebagai databasenya, Delphi 2007 sebagai Devtool-nya, serta komponen Zeos versi 6.6.5-stable.
Problemnya ada pada sql yang bentuknya kurang lebih seperti ini
update myproduk set balance = balance-:amount where idproduk = :idproduk
Tidak ada yang aneh dari sql tersebut. Saya hanya mengurangi field balance dengan suatu nilai tertentu. Problem utamanya ada pada tanda – (minus). Perhatikan bahwa antara tanda minus dan :amount tidak diselingi spasi. Ini yang menjadi masalah.
Bila pada parameter :amount saya lewatkan nilai positif tidak jadi masalah. Tetapi bila saya lewatkan nilai negatif maka nilai balance tidak berubah. Cukup aneh!
Saya menduga (dan ternyata memang benar) bila parameter sql amount tersebut saya isi dengan -100 dan idproduk dengan 1, misalnya, maka perintah tersebut akan dianggap seperti perintah berikut ini
update myproduk set balance = balance--100 where idproduk = 1
Seperti kita tahu, dalam SQL standard, semua yang di belakang tanda -- akan dianggap sebagai comment alias tidak dijalankan. Jadi perintah tersebut sama artinya dengan
update myproduk set balance = balance
Mungkin perintah di atas tidak terlalu berbahaya karena bug berakibat tidak ada data yang berubah. Tapi bayangkan bila yang saya masukkan adalah perintah berikut
update myproduk set balance = balance+1000-:amount where idproduk = :idproduk
Akibatnya semua balance dala tabel produk tersebut takan bertambah 1000 !!!
Solusinya sebenarnya sederhana saja, yait antara tanda minus dengan parameter :amount diberi jarak (spasi). Dan masalahnya selesai.
Berikut ini screenshot eksperimen yang saya lakukan.
Sebelum tombol Test Query dijalankan.

Setelah tombol Test Query dijalankan nilai field balance untuk semua record bertambah dengan 1000
