オンラインツールのライセンス表示は、なぜあんなに雑なのか
HEIC変換のライブラリを探していて、heic2any が libheif の作者本人からライセンス違反を指摘されているのを見つけた。libheif は LGPL なのに、コンパイル済みのコードを同梱したまま MIT で配布し、表示義務も果たしていない、という指摘だ。数年前に立てられたまま、解決していない。
他人事として読んでいたのだが、気になって自分のサイトのビルド成果物を grep した。著作権表示が1件も残っていなかった。
MITは「ライセンス名を書けば済む」ではない
MITライセンスの条文はこうなっている。
> The above copyright notice and this permission notice shall be included in> all copies or substantial portions of the Software.
「上記の著作権表示」と「この許諾表示」を含めることが条件だ。「MITです」と名前を書くだけでは満たさない。著作権者の名前と、許諾文の本体が要る。
このサイトはZIP生成に JSZip を使っている。最初に作った表示ページには、ライブラリ名・バージョン・ライセンス名・入手先・用途を載せていた。一見きちんとしているが、肝心の著作権表示と許諾文が無かった。
ビルドすると著作権表示は消える
JSZip の配布ファイルには、ちゃんと表示が付いている。
/*!
JSZip v3.10.2 - A JavaScript class for generating and reading zip files
(c) 2009-2016 Stuart Knightley <stuart [at] stuartk.com>
Dual licenced under the MIT license or GPLv3.
JSZip uses the library pako released under the MIT license
*/
先頭の /*! は「このコメントは消さないでほしい」という慣習的な印だ。多くの圧縮ツールが、この印の付いたコメントを残す設定を持っている。
それでも、本番ビルド後のファイルを調べるとこうなる。
| 探した文字列 | 配布ファイル | ビルド後 |
|---|---|---|
Stuart Knightley | 1 | 0 |
Dual licen | 1 | 0 |
(c) 2009 | 1 | 0 |
全部消えていた。 配布物から消えた以上、表示できる場所はもうライセンス表示ページしか残っていない。何もしなければ、義務を果たさないまま公開される。
ここが一番の落とし穴だと思う。手を抜いたのではなく、消えたことに気づかない。ビルドの出力を grep して初めて分かる。
1つ入れたつもりが、5つ入っていた
もうひとつ、調べて分かったことがある。npm install jszip で入れたのは1つのはずだった。ビルド後のチャンクを調べると、中身はこうなっていた。
| ライブラリ | バージョン | ライセンス | 著作権者 |
|---|---|---|---|
| JSZip | 3.10.2 | MIT / GPLv3 | Stuart Knightley 他3名 |
| pako | 1.0.11 | MIT AND Zlib | Vitaly Puzrin, Andrei Tuputcyn |
| lie | 3.3.0 | MIT | Calvin Metcalf, Jordan Harband |
| setimmediate | 1.0.5 | MIT | Barnesandnoble.com, llc 他 |
| immediate | 3.0.6 | MIT | Barnesandnoble.com, llc 他 |
JSZip の圧縮処理は pako が担っていて、それが配布ファイルに同梱されている。さらにその先にも依存がある。npm install 1回で、表示義務が5件増えていた。
面白いのは、数えるべき対象が package.json とは一致しないことだ。JSZip は readable-stream にも依存していると書いてあるが、ブラウザ向けのビルドでは別のものに差し替えられていて、配布物には入っていなかった。特徴的な文字列で調べると、こうなる。
| 探した文字列 | 由来 | チャンク内 |
|---|---|---|
invalid distance too far back | pako | あり |
Cannot resolve promise with itself | lie | あり |
MessageChannel | immediate | あり |
_readableState | readable-stream | なし |
書いてあるのに入らないものがあり、書いていないのに入るものがある。数えるなら、依存の一覧ではなく、実際に配るファイルを見るしかない。
「MIT」と書いてあっても、それだけとは限らない
数え終わったつもりで、もう一段あった。
pako の npm の license 欄は MIT AND Zlib になっている。ところが同梱されている LICENSE ファイルを開くと、MITの文面しか入っていない。Zlib はどこにあるのか、とソースを開いて分かった。
// (C) 1995-2013 Jean-loup Gailly and Mark Adler
// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
//
// This software is provided 'as-is', without any express or implied
// warranty. ...
Jean-loup Gailly と Mark Adler。zlib の作者だ。pako は zlib を JavaScript に移植したもので、元の著作権表示がソースの12ファイルに残っている。LICENSE ファイルには書かれていない。
面白いのは、zlib ライセンスが表示について何と言っているかだ。
> 1. ...If you use this software in a product, an acknowledgment in the product> documentation would be appreciated but is not required.
> 3. This notice may not be removed or altered from any source distribution.
謝辞は「あればありがたいが、必須ではない」。削除を禁じているのは「ソース配布物」からで、minify済みのJavaScriptがそれに当たるかは、はっきりしない。
つまりこの2名については、載せなくても違反とは言い切れない。それでも載せることにした。判断が微妙なときに省くのは、この記事で書いてきた「雑な表示」そのものだからだ。
LGPLはもっと厳しい
冒頭の heic2any が引っかかったのは、表示義務だけではない。LGPL は「利用者がそのライブラリを差し替えられること」も求める。バンドルに静的に混ぜ込んでしまうと、差し替える手段が無くなる。
MITやApache-2.0なら、表示さえすれば混ぜ込んで構わない。LGPLが混ざった瞬間に、配り方そのものを変える必要が出てくる。このサイトがHEIC変換を後回しにしているのはそのためで、別ファイルとして読み込む作りにしてから入れることにしている。
やったこと
1. ライセンス表示のページを作る。 消えるものは、別の場所に置き直すしかない2. 原文をそのまま載せる。 翻訳も要約もしない。「含めること」が条件なので、整形して意味が変わると条件を満たさなくなる3. 直接入れたものではなく、配布物に入るものを数える。package.json ではなく、ビルド成果物を grep する4. ビルドのたびに確認する。 表示が残っているかは、出力を見ないと分からない
雑な表示が多いのは、たぶん悪意ではない。ビルドすると消えることと、入れた覚えのないものが入ること、この2つが見えないからだと思う。どちらも grep 一発で分かるのに、やってみるまで気づかない。自分がそうだった。