Statement on glibc/iconv Vulnerability

定数式における列挙型の値

列挙型の case は、定数として表現されているので、 ほとんどの定数式の中で静的な値として使えます。 つまり、プロパティのデフォルト値や、 static 変数のデフォルト値、引数のデフォルト値、 グローバル定数やクラス定数の値として使えます。 列挙型の case 以外の値は使えませんが、 通常の定数は、列挙型の case を参照できます。

しかしながら、列挙型の中で ArrayAccess のような暗黙のマジックメソッドの呼び出しを行うことは、 定数や static な定義では許されません。 なぜなら、結果の値が保証できなくなりますし、 副作用がまったくないことも保証できないからです。 関数コールやメソッドコール、そしてプロパティへのアクセスは、 引き続き定数式では不正な操作として扱われます。

<?php

// これは、完全に正しい列挙型の定義です
enum Direction implements ArrayAccess
{
case
Up;
case
Down;

public function
offsetExists($offset): bool
{
return
false;
}

public function
offsetGet($offset): mixed
{
return
null;
}

public function
offsetSet($offset, $value): void
{
throw new
Exception();
}

public function
offsetUnset($offset): void
{
throw new
Exception();
}
}

class
Foo
{
// これは、許されています。
const DOWN = Direction::Down;

// これは、許可されません。結果の値が保証できない可能性があります。
const UP = Direction::Up['short'];
// Fatal error: Cannot use [] on enums in constant expression
}

// これは、完全に正しいコードです。定数式ではないからです。
var_dump("\$x is " . var_export($x, true));

$foo = new Foo();
?>
add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top