WordPress Bug: auto upgrade plugin ทำปลั๊กอินพัง

หลังจาก @lewcpe ช่วยลง FTP บนเครื่องที่ภาคให้แล้ว ก็ได้โอกาสลองใช้ฟีเจอร์สั่ง Auto-upgrade ของ wordpress ฟีเจอร์นี้คือการที่ wordpress จะทำการ upgrade ตัว plugin ให้เราโดยอัตโนมัติ เพียงแค่เรากรอก user/pass ของ FTP เข้าไปแล้ว WordPress จะเข้าไปจัดการให้เราเอง

 Wordpress Auto-Upgrade
ตัวอย่างหน้า Upgrade

เมื่อระบบพร้อม เราก็ทดลองกับ wassup plugin เป็นตัวแรก ทุกอย่างก็ผ่านไปด้วยดี จนกระทั่งขั้นตอนการอัพเกรดเสร็จเรียบร้อย แต่เมื่อกดไปหน้าไหนก็จะเจอข้อความโวยวายดังนี้อยู่บนหัว

Warning: include_once(…blabla…/blog/wp-content/plugins/wassup/) [function.include-once]: failed to open stream: Success in …blabla…/blog/wp-settings.php on line 425

จากข้อความข้างบน แปลว่ามีปัญหากับคำสั่ง include_once ในไฟล์ wp-settings.php บรรทัดที่ 425

เอาแล้วไง! ก็เริ่ม debug หาสาเหตุไปเรื่อยๆ จนพบว่ามันเกิดจากตัวแปร $plugin ที่ปกติต้องชี้ไปยังไฟล์ มันดันขึ้นเป็นโฟลเดอร์ แต่เจ้า include_once นั้นออกแบบมาให้อ่านไฟล์ มันก็เลยโวยวายออกมา

เรื่องที่ตัวแปร $plugin มี directory path โผล่มานี่ช่างมันเพราะขี้เกียจหา ประเด็นคือทำไม php มันยังรัน include_once ทั้งๆที่ก่อนหน้านั้นก็มี if คอยตรวจสอบตัวแปร $plugin อยู่ตั้งหลายเงื่อนไข ลองดูโค้ด

424
425
if (  != $plugin && 0 == validate_file($plugin) && file_exists(WP_PLUGIN_DIR . '/' . $plugin) )
    include_once(WP_PLUGIN_DIR . '/' . $plugin);

ถึงได้พบว่าปัญหาอยู่ตรงเงื่อนไขหลังสุด file_exists(path) เนื่องจากคำสั่งนี้จะ return TRUE ไม่ว่า path ที่ใส่มาจะเป็น file หรือ directory ก็ตาม ทำให้ค่า $plugin ที่ถูกส่งมาในสภาพ directory นั้นผ่านเงื่อนไขนี้ไปได้ แล้วไปรันต่อใน include_once บรรทัดถัดมา

อันนี้แก้ไม่ยาก แค่เปลี่ยนไปใช้คำสั่ง is_file(path) แทนก็จบ เพราะคำสั่งนี้ทั้งตรวจสอบว่า path ที่ส่งให้คือ file หรือเปล่า โค้ดใหม่ก็จะเป็น

424
425
if (  != $plugin && 0 == validate_file($plugin) && is_file(WP_PLUGIN_DIR . '/' . $plugin) )
    include_once(WP_PLUGIN_DIR . '/' . $plugin);

เพียงเท่านี้! ข้อความ Warning มากมายก็จะอันตรธานหายไป

ทีนี้เมื่อเราแก้ได้แล้วจะเก็บไว้คนเดียวก็ยังไงๆอยู่ ก็เลยตัดสินใจรายงานบั๊กไปยังทางทีมงาน WordPress เนี่ยแหละปัญหา หลังจากอ่านขั้นตอนการ Report Bugs แล้ว ก็เริ่มถอดใจ

ตอนแรกเกือบจะเปลี่ยนใจไม่แจ้งแล้ว แต่ลองไปค้นหาบั๊กเก่าๆดู ถึงได้พบว่ามีคนเจอปัญหาเดียวกันเมื่อสัปดาห์ที่แล้วนี่เอง แล้วเค้าก็เขียน Patch ไว้ให้เรียบร้อยแล้ว เป็นอันว่าคงแก้ไขในรุ่นที่จะถึงใกล้ๆนี้

Bug reported
Report Bug

wps.diff
Patch ที่มีคนส่งมาให้

ว่าแล้วก็มาอัพบล๊อกเก็บเป็นข้อมูลไว้ ถ้ามันยังไม่แก้ในรุ่นใกล้ๆ เผื่อเราลงใหม่จะได้รู้ว่าต้องแก้ไปตรงไหนบ้าง