Limit the images that previews keep.

A preview that fails the captcha or the form token keeps no image. A session keeps one image, the directory has a size limit, and abandoned images go at the next upload.
This commit is contained in:
tim
2026-09-26 15:27:51 +02:00
parent fe30a0aaa1
commit c4fcef21aa
8 changed files with 215 additions and 42 deletions
+54 -18
View File
@@ -88,28 +88,64 @@ class UploadTest extends TestCase {
$this->assertFalse(save_uploaded_file());
}
public function testPruneDeletesTheSavedFileAndOldUploads(): void {
$saved = $this->pending();
$old = upload_dir() . '/' . str_repeat('c', 32);
$new = upload_dir() . '/' . str_repeat('d', 32);
$other = upload_dir() . '/keep-me';
foreach (array($old, $new, $other) as $file)
file_put_contents($file, 'x');
touch($old, time() - 86401);
touch($other, time() - 86401);
// Files in the upload directory: an old upload, a new one and a file that is not an upload
private function others(): array {
$files = array('old' => upload_dir() . '/' . str_repeat('c', 32), 'new' => upload_dir() . '/' . str_repeat('d', 32),
'other' => upload_dir() . '/keep-me');
foreach ($files as $file)
file_put_contents($file, 'xx');
touch($files['old'], time() - 86401);
touch($files['other'], time() - 86401);
return $files;
}
prune_images($saved);
public function testPruneImagesDeletesTheSessionUploadAndOldUploads(): void {
$saved = $this->pending();
$files = $this->others();
prune_images();
$this->assertFileDoesNotExist($saved);
$this->assertFileDoesNotExist($old);
$this->assertFileExists($new);
$this->assertFileExists($other);
$this->assertFileDoesNotExist($files['old']);
$this->assertFileExists($files['new']);
$this->assertFileExists($files['other']);
$this->assertArrayNotHasKey('pending_upload', $_SESSION);
}
public function testPruneLeavesFilesOutsideTheUploadDirectory(): void {
$outside = $this->tmp . '/' . str_repeat('e', 32);
file_put_contents($outside, 'x');
prune_images($outside);
$this->assertFileExists($outside);
public function testPruneUploadsKeepsTheSessionUploadUntilItIsOld(): void {
$pending = $this->pending();
prune_uploads();
$this->assertFileExists($pending);
touch($pending, time() - 86401);
prune_uploads();
$this->assertFileDoesNotExist($pending);
}
public function testRemovePendingUploadTouchesOnlyTheSessionFile(): void {
$files = $this->others();
remove_pending_upload();
$pending = $this->pending();
remove_pending_upload();
$this->assertFileDoesNotExist($pending);
$this->assertArrayNotHasKey('pending_upload', $_SESSION);
foreach ($files as $file)
$this->assertFileExists($file);
}
public function testUploadDirSizeCountsOnlyUploads(): void {
$this->others();
$this->pending('12345');
$this->assertSame(2 + 2 + 5, upload_dir_size());
}
public function testStoreUploadPrunesAndDropsTheLastUploadFirst(): void {
$last = $this->pending();
$files = $this->others();
$file = $this->tmp . '/local';
file_put_contents($file, 'x');
// Not a real upload, so nothing is kept, but the old files still go
$this->assertFalse(store_upload($file));
$this->assertFileDoesNotExist($last);
$this->assertFileDoesNotExist($files['old']);
$this->assertFileExists($files['new']);
$this->assertArrayNotHasKey('pending_upload', $_SESSION);
}
}