AttachedFilePath
in package
フォームの添付ファイル。
値の形式に関する規則(アーカイブ領域の外を指さない・ファイル名がファイル名であること・ コピー先の拡張子を書き換えないこと)をこの型の不変条件として持つ。不正な値では インスタンスが存在し得ないため、確認画面・送信のどちらの経路でも再検証しなくてよい。
併せて、添付ファイルに対して行いたい操作(アップロード由来かの判定・実ファイルの 存在確認・一時ディレクトリへの移動)もこの型に集約する。パスの組み立て規則を知って いるのはこの型だけなので、呼び出し側が realPath と tempPath を取り違える余地を残さない。
Table of Contents
Properties
- $fieldName : string
- $fieldPath : string
- $fileName : string
- $originalName : string
- $realPath : string
- $relativePath : string
- $tempPath : string
- $temporaryDirectory : string
Methods
- create() : self
- 値の形式を検証してインスタンスを組み立てる
- equals() : bool
- exists() : bool
- コピー元に実ファイルがあるか
- extension() : string
- 拡張子(小文字)
- isFromUpload() : bool
- 正規のアップロード由来か
- moveToTemporaryDirectory() : bool
- 一時ディレクトリへ移動する
- requiresCopy() : bool
- コピー元とコピー先が別の場所か
- secret() : string
- Field へ書き戻す `@secret` の値
- __construct() : mixed
- assertExtensionIsPreserved() : void
- Why not 拡張子を自由にさせない: 一時ディレクトリはアーカイブ領域内にあり既定で Web 公開 されるため、コピー先の拡張子まで選べるとアップロード検証を通ったファイルを .php として 複製できてしまう。コピー元の拡張子と一致することを要求する。
- assertFileNameIsBareName() : void
- assertRelativePathIsWithinArchives() : void
- isInTemporaryDirectory() : bool
- 既に一時ディレクトリの下にあるか
Properties
$fieldName read-only
public
string
$fieldName
$fieldPath read-only
public
string
$fieldPath
$fileName read-only
public
string
$fileName
$originalName read-only
public
string
$originalName
$realPath read-only
public
string
$realPath
$relativePath read-only
public
string
$relativePath
$tempPath read-only
public
string
$tempPath
$temporaryDirectory read-only
private
string
$temporaryDirectory
Methods
create()
値の形式を検証してインスタンスを組み立てる
public
static create(string $archivesDir, string $temporaryDirectory, string $fieldName, string $relativePath, string $fileName, string $originalName) : self
Why not コピー元の実パスを引数で受け取らない: 実パスは常にアーカイブ領域と相対パスの 連結なので、両方を受け取ると呼び出し側が食い違う値を渡せてしまう。相対パスだけを 受け取り実パスは導出する。V2(Twig)フォームのようにアーカイブ領域を含む値が 送られてくる経路では、呼び出し側がアーカイブ領域を取り除いてから渡す。
Parameters
- $archivesDir : string
-
アーカイブ領域のパス(ARCHIVES_DIR)
- $temporaryDirectory : string
-
アーカイブ領域からの一時ディレクトリの相対パス
- $fieldName : string
-
@pathを除いたフィールド名 - $relativePath : string
-
コピー元のアーカイブ領域からの相対パス
- $fileName : string
-
一時ディレクトリへ置くファイル名(
@baseName) - $originalName : string
-
メール添付時のファイル名
Tags
Return values
selfequals()
public
equals(self $other) : bool
Parameters
- $other : self
Return values
boolexists()
コピー元に実ファイルがあるか
public
exists() : bool
Return values
boolextension()
拡張子(小文字)
public
extension() : string
Return values
stringisFromUpload()
正規のアップロード由来か
public
isFromUpload(array<string|int, string> $uploadedPaths) : bool
Why not アーカイブ領域内であることだけで許可しない: 確認画面はコピー成功後にコピー元を 削除するため、アーカイブ領域内なら何でも対象にできると、サイトの HTML から辿れる 公開済みメディアのパスを指定して未認証で削除できてしまう。
Why not @secret の一致で判定しない: @secret は md5({フィールド名}@{パス}) で
ソルトを持たないため、パスを指定できる攻撃者は同じ値を計算できる。
Why not アップロード済みの一覧を自分で参照しない: あの一覧はリクエスト単位の グローバル状態(Entry サービス)なので、引数で受け取って単体テスト可能に保つ。
Parameters
- $uploadedPaths : array<string|int, string>
-
同一リクエストでアップロードされたファイルのパス一覧
Return values
boolmoveToTemporaryDirectory()
一時ディレクトリへ移動する
public
moveToTemporaryDirectory() : bool
後で削除できるようコピーしてからコピー元を消す。コピーに失敗した場合はコピー元を 残す(消してしまうと添付ファイルが失われる)。既に一時ディレクトリにある場合は 何もせず成功として扱う。コピー元とコピー先が同じものを削除してはならないため。
Return values
bool —一時ディレクトリに実体が置かれている状態になったか
requiresCopy()
コピー元とコピー先が別の場所か
public
requiresCopy() : bool
確認画面から「修正する」で戻って再確認すると、既に一時ディレクトリへ移動済みの ファイルが対象になりコピー元とコピー先が一致する。
Return values
boolsecret()
Field へ書き戻す `@secret` の値
public
secret() : string
Return values
string__construct()
private
__construct(string $realPath, string $tempPath, string $fieldPath, string $relativePath, string $fileName, string $fieldName, string $originalName, string $temporaryDirectory) : mixed
Parameters
- $realPath : string
-
コピー元。アーカイブ領域を含む実パス
- $tempPath : string
-
コピー先。アーカイブ領域を含む一時ディレクトリのパス
- $fieldPath : string
-
Field へ書き戻す値。アーカイブ領域からの相対パス
- $relativePath : string
-
コピー元のアーカイブ領域からの相対パス
- $fileName : string
-
一時ディレクトリへ置くファイル名
- $fieldName : string
-
@pathを除いたフィールド名 - $originalName : string
-
メール添付時のファイル名
- $temporaryDirectory : string
-
アーカイブ領域からの一時ディレクトリの相対パス
assertExtensionIsPreserved()
Why not 拡張子を自由にさせない: 一時ディレクトリはアーカイブ領域内にあり既定で Web 公開 されるため、コピー先の拡張子まで選べるとアップロード検証を通ったファイルを .php として 複製できてしまう。コピー元の拡張子と一致することを要求する。
private
static assertExtensionIsPreserved(string $fieldName, string $relativePath, string $fileName) : void
Parameters
- $fieldName : string
- $relativePath : string
- $fileName : string
Tags
assertFileNameIsBareName()
private
static assertFileNameIsBareName(string $fieldName, string $fileName) : void
Parameters
- $fieldName : string
- $fileName : string
Tags
assertRelativePathIsWithinArchives()
private
static assertRelativePathIsWithinArchives(string $fieldName, string $relativePath) : void
Parameters
- $fieldName : string
- $relativePath : string
Tags
isInTemporaryDirectory()
既に一時ディレクトリの下にあるか
private
isInTemporaryDirectory() : bool