Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 16268] ファイルの概要

このコミットは、Go言語の image/png パッケージにおけるエラーメッセージの不具合を修正するものです。具体的には、Encode 関数内で画像サイズが無効な場合に返されるエラーメッセージにおいて、幅(width)の値が誤って2回出力されてしまう問題を解決しています。これにより、ユーザーに対してより正確なエラー情報が提供されるようになります。

コミット

commit 1294f14f1fb632a963df2af39a97b496e49fe9a8
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date:   Mon May 6 09:59:33 2013 -0700

    image/png: fix error message to not return width twice
    
    Fixes #5413
    
    R=golang-dev, dave, adg
    CC=golang-dev
    https://golang.org/cl/9153045
---
 src/pkg/image/png/writer.go | 2 +--
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pkg/image/png/writer.go b/src/pkg/image/png/writer.go
index 093d47193b..629452cbfa 100644
--- a/src/pkg/image/png/writer.go
+++ b/src/pkg/image/png/writer.go
@@ -436,7 +436,7 @@ func Encode(w io.Writer, m image.Image) error {
 	// also rejected.
 	mw, mh := int64(m.Bounds().Dx()), int64(m.Bounds().Dy())
 	if mw <= 0 || mh <= 0 || mw >= 1<<32 || mh >= 1<<32 {\n-\t\treturn FormatError(\"invalid image size: \" + strconv.FormatInt(mw, 10) + \"x\" + strconv.FormatInt(mw, 10))\n+\t\treturn FormatError(\"invalid image size: \" + strconv.FormatInt(mw, 10) + \"x\" + strconv.FormatInt(mh, 10))\n \t}\n \n \tvar e encoder\n```

## GitHub上でのコミットページへのリンク

[https://github.com/golang/go/commit/1294f14f1fb632a963df2af39a97b496e49fe9a8](https://github.com/golang/go/commit/1294f14f1fb632a963df2af39a97b496e49fe9a8)

## 元コミット内容

image/png: fix error message to not return width twice

Fixes #5413

R=golang-dev, dave, adg CC=golang-dev https://golang.org/cl/9153045


## 変更の背景

このコミットは、Go言語の標準ライブラリである `image/png` パッケージにおいて、PNG画像をエンコードする際に発生するエラーメッセージの誤りを修正するために行われました。具体的には、Go issue #5413 で報告された問題に対応しています。

Go issue #5413 の内容は、`image/png` パッケージの `Encode` 関数が、無効な画像サイズ(例えば、幅や高さが0以下、または非常に大きい値)を受け取った際に返すエラーメッセージが不正確であるというものでした。本来であれば "invalid image size: WIDTHxHEIGHT" の形式で幅と高さを表示すべきところ、誤って "invalid image size: WIDTHxWIDTH" のように幅の値を2回表示してしまっていました。

このようなエラーメッセージの誤りは、開発者が問題の原因を特定する際に混乱を招く可能性があります。特に、画像処理のような数値的な正確性が求められる分野では、エラーメッセージの正確性はデバッグの効率に直結します。この修正は、ユーザーがより迅速かつ正確に問題に対処できるよう、エラーメッセージの品質を向上させることを目的としています。

## 前提知識の解説

このコミットを理解するためには、以下のGo言語の概念と画像処理に関する基本的な知識が必要です。

*   **`image` パッケージ**: Go言語の標準ライブラリで、基本的な画像処理機能を提供します。`image.Image` インターフェースは、様々な画像フォーマット(PNG, JPEGなど)を抽象化して扱えるように定義されています。
*   **`image/png` パッケージ**: `image` パッケージの一部で、PNG形式の画像をエンコード(書き出し)およびデコード(読み込み)するための機能を提供します。
*   **`io.Writer` インターフェース**: データを書き込むための汎用的なインターフェースです。`image/png.Encode` 関数は、このインターフェースを実装する任意の型(例: `os.File`, `bytes.Buffer`)にPNGデータを書き出すことができます。
*   **`image.Image.Bounds()` メソッド**: `image.Image` インターフェースが持つメソッドで、画像の境界(矩形)を `image.Rectangle` 型で返します。
*   **`image.Rectangle.Dx()` メソッド**: `image.Rectangle` 型のメソッドで、矩形の幅(X軸方向のサイズ)を返します。
*   **`image.Rectangle.Dy()` メソッド**: `image.Rectangle` 型のメソッドで、矩形の高さ(Y軸方向のサイズ)を返します。
*   **`strconv.FormatInt(i int64, base int)` 関数**: `strconv` パッケージの関数で、`int64` 型の整数 `i` を指定された基数 `base`(例: 10進数なら `10`)の文字列に変換します。
*   **`FormatError` 型**: `image/png` パッケージ内で定義されているエラー型で、PNGフォーマットに関するエラーを示すために使用されます。
*   **PNG (Portable Network Graphics)**: 可逆圧縮のビットマップ画像フォーマットです。ウェブ上で広く利用されており、透明度(アルファチャンネル)をサポートします。

## 技術的詳細

このコミットの技術的な核心は、エラーメッセージの文字列生成ロジックの修正にあります。

`src/pkg/image/png/writer.go` ファイルの `Encode` 関数は、`image.Image` インターフェースを実装する画像データと `io.Writer` インターフェースを実装する出力先を受け取り、画像をPNG形式でエンコードします。

エンコード処理の初期段階で、入力された画像のサイズ(幅 `mw` と高さ `mh`)が有効であるかどうかのチェックが行われます。具体的には、幅または高さが0以下であるか、あるいは `1<<32` (約40億) 以上である場合に、無効な画像サイズとしてエラーを返します。これは、PNGの仕様やシステムのリソース制約に起因する可能性があります。

問題のあったコードは以下の部分でした。

```go
return FormatError("invalid image size: " + strconv.FormatInt(mw, 10) + "x" + strconv.FormatInt(mw, 10))

ここで、strconv.FormatInt(mw, 10) が2回使われており、結果としてエラーメッセージが "invalid image size: WIDTHxWIDTH" の形式になっていました。これは、幅 (mw) と高さ (mh) の両方を表示すべき箇所で、誤って幅の値を繰り返してしまっていた単純なタイプミスです。

修正後のコードは以下のようになります。

return FormatError("invalid image size: " + strconv.FormatInt(mw, 10) + "x" + strconv.FormatInt(mh, 10))

この変更により、2回目の strconv.FormatInt の引数が mw から mh に修正され、エラーメッセージは期待通り "invalid image size: WIDTHxHEIGHT" の形式で出力されるようになりました。これにより、開発者はエラーメッセージから画像の正確な寸法(幅と高さ)を把握できるようになり、デバッグ作業が容易になります。

この修正は、Go言語の標準ライブラリの品質と信頼性を向上させるための、細部への注意と継続的な改善の一例と言えます。

コアとなるコードの変更箇所

--- a/src/pkg/image/png/writer.go
+++ b/src/pkg/image/png/writer.go
@@ -436,7 +436,7 @@ func Encode(w io.Writer, m image.Image) error {
 	// also rejected.
 	mw, mh := int64(m.Bounds().Dx()), int64(m.Bounds().Dy())
 	if mw <= 0 || mh <= 0 || mw >= 1<<32 || mh >= 1<<32 {\n-\t\treturn FormatError(\"invalid image size: \" + strconv.FormatInt(mw, 10) + \"x\" + strconv.FormatInt(mw, 10))\n+\t\treturn FormatError(\"invalid image size: \" + strconv.FormatInt(mw, 10) + \"x\" + strconv.FormatInt(mh, 10))\n \t}\n \n \tvar e encoder\n```

## コアとなるコードの解説

変更は `src/pkg/image/png/writer.go` ファイルの `Encode` 関数内、具体的には437行目で行われています。

元のコード:
```go
return FormatError("invalid image size: " + strconv.FormatInt(mw, 10) + "x" + strconv.FormatInt(mw, 10))

この行では、FormatError 関数を呼び出してエラーを生成しています。エラーメッセージの文字列は、"invalid image size: " に続けて、画像の幅 mw を文字列化したもの、"x"、そして再び幅 mw を文字列化したものを連結して作成されていました。これにより、例えば幅が100、高さが200の無効な画像の場合、「invalid image size: 100x100」という誤ったメッセージが出力されていました。

修正後のコード:

return FormatError("invalid image size: " + strconv.FormatInt(mw, 10) + "x" + strconv.FormatInt(mh, 10))

修正後のコードでは、2回目の strconv.FormatInt の引数が mw から mh に変更されています。mh は画像の高さ(height)を表す変数です。この変更により、エラーメッセージは "invalid image size: " に続けて、幅 mw"x"、そして高さ mh を正確に連結したものとなります。これにより、上記の例では「invalid image size: 100x200」という正しいエラーメッセージが出力されるようになります。

この修正は非常に小さいですが、エラーメッセージの正確性を確保し、デバッグ時のユーザーエクスペリエンスを大幅に向上させる重要な変更です。

関連リンク

参考にした情報源リンク