(重要なお知らせ)UTF.Unknown のライセンス表記の誤りについて、お詫びと訂正
UTF.Unknown のライセンス表記を間違えていました
当サイトで公開している文字エンコーディング関連のツールおよびクラスライブラリは、UTF.Unknown という海外製の NuGet パッケージを参照しています。
該当する製品は以下のとおりです。
- rmsmf
- txprobe
- mfsr
- mfprobe
- SnowStack.EncodingProbe
- SnowStack.EncodingProbe.PowerShell
つまり、当サイトから提供しているほとんどの OSS 製品が該当します。
これまで、この UTF.Unknown のライセンスを MIT ライセンス として説明・表記してきましたが、これは私の誤りでした。正しくは以下のライセンス規定になります。
UTF.Unknown
https://github.com/CharsetDetector/UTF-unknown
UTF.Unknown is subject to the Mozilla Public License Version 1.1
(the "License"). Alternatively, it may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"),
or the GNU Lesser General Public License Version 2.1 or later
(the "LGPL").
You may obtain a copy of the Mozilla Public License Version 1.1 at
https://www.mozilla.org/MPL/1.1/
日本語で言えば、Mozilla Public License 1.1 / GPL 2 以降 / LGPL 2.1 以降の三重ライセンスです。利用者はこの3つの中から1つを選んで利用できます。
誤った情報を長期間にわたって公開し続けてしまいましたことを、深くお詫び申し上げます。
緊急サイト更新
UTF.Unknown のライセンスについての説明を、正しい内容に修正しました。snow-stack.net の該当箇所の記事は修正済みです。
mfsr・mfprobe・txprobe・rmsmf 1.1.1.0 のリリース
各ツールのライセンス表示も修正した上で、最新モジュールのバージョン 1.1.1.0 をリリースしました。
機能面は前バージョンの 1.1.0.0 と変わっていません。-v オプションで表示するライセンス表示の内容のみを変更しています。
SnowStack.EncodingProbe および SnowStack.EncodingProbe.PowerShell についても、パッケージに同梱するサードパーティライセンス通知を修正しています。
本体と UTF.Unknown のライセンスは異なります
ライセンス表示を修正した上で、UTF.Unknown のライセンスについて改めて解説したいと思います。ライセンスの誤りをお詫びするだけでなく、正しく理解していただくための情報をお伝えするのが筋だと考えるためです。
UTF.Unknown のライセンス
UTF.Unknown は、Mozilla Universal Charset Detector の系譜にあるライブラリです。Mozilla のコードを起源としているため、Mozilla が古くから採用してきた三重ライセンスをそのまま引き継いでいます。
このうち中心となるのが Mozilla Public License 1.1(MPL 1.1) です。MPL 1.1 は、1998年に Netscape がブラウザのソースコードを公開する際、「ソースは公開させたいが、企業が商用製品に組み込むことも許したい」という相反する要求を両立させるために設計されました。
その答えが ファイル単位のコピーレフト という考え方です。
MPL 1.1 の義務が及ぶのは「Covered Code」、つまり元々 MPL が付されたソースファイルと、それに対する改変だけです。それらのファイルを改変した場合は MPL のまま公開する義務が生じますが、自分で新しく書いたファイルには義務が及びません。
GPL が派生著作物の全体に伝播するのとは、ここが決定的に違います。
MPL 1.1 の主な義務を整理すると、次のようになります。
| 条項 | 内容 |
|---|---|
| 第3.1条 | 改変した Covered Code は MPL のまま維持する |
| 第3.2条 | ソースコードを入手可能な状態にしておく |
| 第3.3条 | 改変した場合、変更日時と内容を記録する |
| 第3.5条 | 著作権表示・ライセンス表示を除去しない |
| 第3.6条 | 実行形式には別のライセンスを付けてよいが、ソースの入手方法を明示する |
| 第3.7条 | 独自コードと組み合わせた全体は、独自部分について自由なライセンスにできる |
なお、GitHub のリポジトリを見てもライセンスが自動判定されないのは、ルートに LICENSE ファイルが無く license/ ディレクトリに複数のライセンス文書が格納されているためです。私が誤解した一因もここにありました。とはいえ README には明記されており、確認を怠った私の落ち度です。
本体側(EncodingProbe・mfsr・mfprobe など)のライセンス
一方、当サイトが提供する以下の製品は、これまでどおり MIT ライセンス です。ここは変更ありません。
- rmsmf / txprobe
- mfsr / mfprobe
- SnowStack.EncodingProbe
- SnowStack.EncodingProbe.PowerShell
MIT ライセンスは、著作権表示とライセンス文を残すことだけを条件に、使用・複製・改変・再配布・商用利用・プロプライエタリ製品への組み込みまで、ほぼ無制限に認めるライセンスです。コピーレフトはありません。
なぜ本体は MIT のままでよいのか
「MPL 1.1 のライブラリを使っているのに、本体が MIT なのはおかしいのでは」と思われるかもしれません。ここが MPL 1.1 を理解する上で最も重要なポイントです。
当サイトの各ツールは、UTF.Unknown を NuGet パッケージのまま、一切改変せずに参照 しています。ソースコードを取り込んだり、書き換えたりはしていません。
この場合、
- UTF.Unknown のファイルは改変していないので、第3.1条・第3.3条の義務は発生しない
- UTF.Unknown は独立した別アセンブリ(DLL)として存在し、当方のコードとはファイルが分かれている
- したがって第3.7条の「Larger Work」にあたり、当方が書いた部分は自由なライセンスにできる
という整理になります。
MPL 1.1 が「ファイル単位」であることの実務的な意味が、まさにここに表れています。仮にこれが GPL のライブラリであれば、当方のツール全体が GPL になり、MIT で提供することはできませんでした。
当方に残る義務は、実質的に次の2点だけです。
- UTF.Unknown のライセンスを正しく表示すること(第3.5条)
- UTF.Unknown のソース入手先を明示すること(第3.2条・第3.6条)
今回の誤りは、まさにこの1点目に反していた ことになります。
両者の違いのまとめ
| 本体(EncodingProbe など) | UTF.Unknown | |
|---|---|---|
| ライセンス | MIT | MPL 1.1 / GPL 2+ / LGPL 2.1+ |
| コピーレフト | なし | ファイル単位(弱いコピーレフト) |
| 改変ファイルの公開義務 | なし | あり |
| ソース入手可能性の保証 | 不要 | 必要 |
| 特許の明示的許諾 | なし | あり(MPL 1.1) |
| ライセンス終了条項 | なし | あり |
同じパッケージの中に、条件の異なる2つのライセンスが同居している。それが実態です。
ご利用いただいている開発者の皆様への影響
ここが本記事で最もお伝えしたい部分です。
影響の範囲
当方のツールやライブラリを組み込んで製品やサービスを配布されている場合、その配布物には UTF.Unknown が含まれています。したがって、MPL 1.1 の義務が皆様にも及びます。
これまで「依存関係はすべて MIT」という前提で管理されていた場合、意図せず MPL 1.1 の表示義務を果たしていない状態になっている可能性があります。誤った情報をお伝えしたことが原因であり、重ねてお詫びいたします。
一方、以下のケースでは実質的な影響はありません。
- コマンドラインツール(mfsr / mfprobe / txprobe / rmsmf)を社内や個人で使っているだけの場合 — MPL 1.1 の義務は「配布」に伴って発生するため、使用のみであれば対応は不要です
- 社内システムに組み込んでいるが、外部に配布していない場合 — 同様に、配布行為がなければ義務は発生しません
対応していただきたいこと
配布を行っている場合、以下をご確認ください。
1. 最新版へのアップデート
各製品の 1.1.1.0 以降(SnowStack.EncodingProbe は最新版)にアップデートしてください。機能変更はありませんので、動作への影響はありません。修正済みのライセンス通知が同梱されます。
2. 自社製品のライセンス通知の修正
THIRD-PARTY-NOTICES.txt や、それに相当するライセンス一覧に UTF.Unknown を MIT として記載されている場合は、修正をお願いします。記載例は本記事冒頭のとおりです。
3. ソース入手先の明示
UTF.Unknown のソースコード入手先(https://github.com/CharsetDetector/UTF-unknown)を、配布物のどこかに記載してください。バージョン番号も併記しておくと、より確実です。
ライセンス管理の方法と注意事項
同じ失敗を繰り返さないために、私自身が今回学んだことを共有します。
推移的依存も確認する
今回の誤りの本質は、直接の依存先しか見ていなかった ことです。NuGet は依存パッケージのライセンスを自動的には表示してくれませんし、dotnet list package --include-transitive でパッケージ名は分かってもライセンスまでは出ません。
依存ツリー全体を対象にライセンスを棚卸しする習慣が必要でした。
自動チェックの導入
.NET 環境であれば、nuget-license というツールで依存パッケージのライセンスを機械的に列挙・検証できます。
dotnet tool install --global nuget-license
dotnet restore
nuget-license -i <ソリューションまたはプロジェクト> -t -a "MIT;Apache-2.0;MPL-1.1"
-t オプションが重要です。これを付けないと直接参照しているパッケージしか見ないため、推移的依存に含まれるライブラリを見落とします。今回の私の失敗も、依存ツリー全体を見ていなかったことが原因でした。
-a で許可するライセンスを列挙しておくと、許可リストにないライセンスが混入した時点で検証エラーになります。CI に組み込んでおけば、新しいパッケージを追加した瞬間にビルドが失敗して気づけます。MPL-1.1 を許可リストに明示的に入れておけば、「知らないうちに紛れ込んだ」のではなく「意識して許可した」状態になります。
なお .NET Framework プロジェクトの場合は、dotnet tool 版ではなく GitHub Releases で配布されている NuGetLicenseFramework.exe が必要になることがあります。また、dotnet-project-licenses という旧名のパッケージも NuGet 上に残っていますが、現在メンテナンスが続いているのは nuget-license のほうです。
ライセンスファイルの場所を鵜呑みにしない
GitHub の画面右側に表示されるライセンス名は、ルートの LICENSE ファイルを自動判定した結果です。UTF.Unknown のようにディレクトリに格納されている場合、判定されずに空欄になります。
空欄だったときこそ、README とリポジトリ内を丁寧に確認すべきでした。
ツールの出力も鵜呑みにしない
前述の nuget-license を使っていれば気づけた可能性は高いのですが、このツールも万能ではありません。
ライセンス情報の取得元は NuGet パッケージのメタデータ(.nuspec)です。古いパッケージでは非推奨の licenseUrl しか設定されておらず、SPDX 識別子が入っていないことがあります。その場合、出力には URL だけが並び、ライセンス種別は判定できません。リンク自体が切れている場合もあります。
つまり、出力に「Unknown」や生の URL が現れたら、そこは自分で調べろというサインです。ツールは見落としを検出してくれますが、見落としを自動で正しく解釈してくれるわけではありません。最終的には上流のリポジトリで確認するのが確実です。
三重ライセンスは「選択」を明示する
MPL / GPL / LGPL のような複数ライセンスの場合、どれを選択したかを明示しておくと、下流の開発者が判断しやすくなります。当方は MPL 1.1 を選択した旨を通知に記載しました。
このたびは、誤ったライセンス情報を長期にわたって公開し、ご利用の皆様にご迷惑をおかけしましたことを、改めて深くお詫び申し上げます。
なお、本記事はライセンスに関する私の理解を述べたものであり、法的助言ではありません。商用配布などで厳密な判断が必要な場合は、専門家にご確認くださいますようお願いいたします。
ご不明な点がありましたら、各リポジトリの Issue よりお問い合わせください。