原來 ZendFramework 1 還有在出新版...

在「Zend Framework 1.12.18 Released!」這邊看到因為「ZF2016-11: Potential Insufficient Entropy Vulnerability in ZF1」而推出新版的消息...

另外在「Changelog 1.12.18」這頁可以看到還是有一些 bugfix,所以其實都還是有在維護?(記憶中以為現在沒在管了...)

Composer 出現 lock file out of date 的解法

之前也有遇到,結果 Lorna Jane Mitchell 寫了一篇「Handling Composer "lock file out of date" Warning」給了不少解法。

第一種是 composer upgrade,直接全部升級。

第二種是先用 composer update --dry-run 看看是不是有人加到 composer.json 後忘記更新,如果是的話再用 composer update [package] 處理。

第三種是用 composer update nothing 閉上眼睛更新 hash 值,當作什麼都沒看到 XDDD

Sometimes this is the right answer so it's a handy trick to know!. I seem to see these kinds of issues in people's projects quite often (I'm a consultant, I see a lot of projects) so I thought I'd share my usual tactics for getting things sorted - if you have any tricks of your own to share, I'd love to hear them :)

該說很「實用」嗎 XDDD

PostgreSQL 9.5 釋出,UPSERT!

PostgreSQL 9.5 正式發行,這次新增了大家期待已久的 UPSERT 功能:「PostgreSQL 9.5: UPSERT, Row Level Security, and Big Data」。

SQL:2003 正式定義出 UPSERT,被稱為 Merge,不過看網路上一般還是比較習慣 UPSERT 這個用法:

A relational database management system uses SQL MERGE (also called upsert) statements to INSERT new records or UPDATE existing records depending on whether condition matches.

也就是當沒資料的時候就 INSERT,有資料的時候就 UPDATE 的語法。常見的使用情境是拿來當 counter 用 (雖然這很傷資料庫的效能)。

沒有 UPSERT 的時候只能用 transaction 或是 store procedure 搭出來,效能上會比在 database engine 裡實作來的差,所以 UPSERT 還是被實作出來了。

PostgreSQL 9.5 預定提供的 Row Locking 改善

在「More Concurrency: Improved Locking In PostgreSQL」這邊提到 PostgreSQL 的 Row Locking 的改善,也就是 SELECT ... FOR UPDATESELECT ... FOR SHARE

查了一下 SELECT 的文件,在 7.2 開始提供 FOR UPDATE (PostgreSQL: Documentation: 7.2: SELECT),在 8.1 開始提供 FOR SHARE (PostgreSQL: Documentation: 8.1: SELECT),以維基百科上的紀錄來看,7.2 是 2002 年二月,8.1 是 2005 年十一月,都是已經提很久的功能了。

FOR UPDATEFOR SHARE 可以降低對 transaction 的依賴程度,PostgreSQL 的預設值是 READ COMMITTED,配合 Row Locking 就已經可以做到不少效果了,不需要用到 SERIALIZABLE 等級。

而在最新的 PostgreSQL 9.5 (目前還是開發版),則又多提供了 FOR UPDATE SKIP LOCKED 功能,以官方提供的範例來說,就可以直接避開選位造成的 lock 問題了:

This makes sense because 100 users checking for a free seat concurrently will get 100 different rows. The consequence is that you are not stuck with 1 CPU but you can nicely scale out to all CPUs in the system. As conflicts cannot happen anymore, nobody has to wait on somebody else.

對 locking 控制的更細微。

PostgreSQL 9.5 的 UPSERT

在「Upsert Lands in PostgreSQL 9.5 – a First Look」這邊提到了 PostgreSQL 9.5 支援的 UPSERT 操作。

UPSERT 的定義是:

(computing, database) An operation that inserts rows into a database table if they do not already exist, or updates them if they do.

如果不存在就 INSERT,如果存在就 UPDATE,然後取一部分的字變成 UPSERT。由於要偵測「存在」,只能用在有 primary key 或是有 unique 條件時的表格上。

作者給的範例講解了 PostgreSQL 9.5 上的語法:

INSERT INTO products (
    upc,
    title,
    description,
    link)
VALUES (
    123456789,
    ‘Figment #1 of 5’,
    ‘THE NEXT DISNEY ADVENTURE IS HERE - STARRING ONE OF DISNEY'S MOST POPULAR CHARACTERS! ’,
    ‘http://www.amazon.com/dp/B00KGJVRNE?tag=mypred-20'
    )
ON CONFLICT DO UPDATE SET description=excluded.description;

這邊用的是 ON CONLIFCT DO UPDATE SET,在 MySQL 則是用 ON DUPLICATE UPDATE

PHP 5.3 的最後一版,PHP 5.3.29

正式公告出來了,PHP 5.3.29 是 PHP 5.3 的最後一個版本:「PHP 5.3.29 is available, PHP 5.3 reaching end of life」。

PHP 5.3 到 5.4 參考「Migrating from PHP 5.3.x to PHP 5.4.x」這篇,而 PHP 5.4 到 5.5 則是參考「Migrating from PHP 5.4.x to PHP 5.5.x」這篇,最主要的是 Backward Incompatible Changes 這頁 (兩個 migrate 文件都有),說明有哪些變更是不相容的。

如果可以的話,直接將 PHP 5.3 升級到 PHP 5.5 會是比較適合的選擇。(因為 5.4 升級到 5.5 幾乎沒有問題,可以參考 Backward Incompatible Changes 頁面,根本就沒幾項 XD)

微軟的 IE6+ 安全性更新

即使 Windows XP 在上個月就已經停止安全性更新,但這次的 CVE-2014-1776 影響層面還是太廣,微軟還是提供 Windows XP 用戶相關的 patch (透過 Windows Update 發送):

Use-after-free vulnerability in VGX.DLL in Microsoft Internet Explorer 6 through 11 allows remote attackers to execute arbitrary code or cause a denial of service (memory corruption) via unspecified vectors, as exploited in the wild in April 2014.

在「Security Update Released to Address Recent Internet Explorer Vulnerability」也可以看到說明。

看到 use-after-free 這個詞就想到 OpenSSL 前陣子也來一發 CVE-2010-5298 (居然是 2010 年的 CVE),讓人... XD

PHP Composer 的安全性問題

ComposerPHP 上新一代的套件管理軟體。

Composer 與之前各種方案不同的地方在於,後面掛了 Packagist 這個 PHP package archivist,讓使用者很方便的取得套件 (以及更新)。

其中有一個功能是 replace,表示我所開發的這個套件「宣稱」可以取代其他套件 (通常是 API compatible)。

看到這個功能的時候,以為是要讓 Packagist 能夠串起連結。畢竟偶而會發生「這個套件最新版是 2008 年了,到底有沒有後續維護啊」的情況。如果 Packagist 官方網站可以串起連結,可以節省開發者時間,而且也可以利用 Packagist 上的熱門度來決定要用哪一個後繼者。

但實際上與預期的不同,Composer 的預設值是會「自動」尋找更新並且真的使用,也就是前幾天被丟出來的議題:「Composer is wide open with a massive security vulnerability」。

攻擊者只要在 Packagist 上面上傳一堆含有惡意程式碼的套件 (並且利用 replace 宣稱可以取代 ZF2 或是 Laravel),受害者在 composer update 的時候就有機會抓到這些有惡意程式碼的套件。

而最糟糕的是,主要開發者認為這不是問題,還寫了一大篇文章顧左右而言他之後說「錯覺啦~」:「Composer: Replace, Conflict & Forks Explained」:

Replace is not a bug. Don’t run composer update in automated systems. Forks are allowed on Packagist. Don’t be an idiot when publishing a fork. Got an unexpected fork on update? Your dependencies conflict with the original package. Use conflict (syntax like require) in your composer.json to blacklist the fork and see an explanation of the dependency issue.

於是發現問題的人就爆炸了。

依照往例,vendor 不覺得是問題的安全漏洞,只能把事情弄大爆出來逼 vendor 修。

修正在「Limit Replace / Provides to packages required by name in root package or any dep」這裡。最新版的 Composer 裡已經納入這個修正了。

UPSERT

維基百科對 UPSERT 的說明:(取自「Merge (SQL)」條目)

A relational database management system uses SQL MERGE (also called upsert) statements to INSERT new records or UPDATE existing records depending on whether or not a condition matches.

MySQL 裡的兩種語法其實就是在實做這個需求:

  • REPLACE INTO ...
  • INSERT INTO ... ON DUPLICATE KEY UPDATE ...

而前者其實是後者的一個特例 (當 INSERT 發現有 dupe key 時把現有的 record 改成與 INSERT 時相同的條件)。

而計數器是後者常見的 case 之一:當 record 不存在的時候塞一筆進去,並且將 counter 設為 1;當 record 存在的時候對 counter 加一更新。像是這樣的 SQL query:

INSERT INTO my_table SET id = ?, num = 1 ON DUPLICATE KEY UPDATE num = num + 1;

由於這是常見的需求,使得這個語法是目前少數 MySQL 比 PostgreSQL 好用的地方。

在「A Case for Upserts」這篇就看到抱怨 PostgreSQL 不實做這個功能...

不過我覺得作者寫得有點誇張,INSERT INTO ... ON DUPLICATE KEY UPDATE ... 應該是可以模擬出來的功能:當 INSERT 失敗後再跑 UPDATE。而 REPLACE INTO ... 是特例,也就當然可以模擬出來。

Diablo III 將移除拍賣場 (包含了現金交易市場以及遊戲金幣交易市場)...

英文版的公告內容:「Diablo® III Auction House Update」,以及中文版的公告內容:「《暗黑破壞神®III》拍賣場最新消息」。

重點文字有兩段,第一段是說明未來的遊戲金幣交易以及現金交易將被移除:

With that in mind, we want to let everyone know that we've decided to remove the gold and real-money auction house system from Diablo III.

因此,我們想讓大家知道,我們已決定移除《暗黑破壞神III》的金幣拍賣場和現金拍賣場系統。

第二段的重點是中止的時間點:

Please note that the shutdown will occur on March 18, 2014. We will keep everyone informed as we work through this process.

請注意,拍賣場系統將會在2014年3月18日關閉。一旦有最新消息,我們將會另行通知大家。