diff options
| author | ilotterytea <iltsu@alright.party> | 2025-06-25 00:13:02 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2025-06-25 00:13:02 +0500 |
| commit | 17cdae613d339d31aacabfd232fdd9f67bea6c3a (patch) | |
| tree | 8824c7c0e55bdec8d1eaf129d97257b3fbbfede9 | |
| parent | c734db91064944637e361f90ed90b30d48a7d910 (diff) | |
feat: custom swf parser because swftools is obsolete
| -rw-r--r-- | lib/file.php | 87 | ||||
| -rw-r--r-- | lib/thumbnails.php | 10 | ||||
| -rw-r--r-- | public/catalogue.php | 13 | ||||
| -rw-r--r-- | public/index.php | 4 | ||||
| -rwxr-xr-x | public/static/img/icons/file_flash.png | bin | 0 -> 582 bytes | |||
| -rw-r--r-- | public/upload.php | 7 |
6 files changed, 101 insertions, 20 deletions
diff --git a/lib/file.php b/lib/file.php index 61c4fb8..0b250ca 100644 --- a/lib/file.php +++ b/lib/file.php @@ -1,6 +1,89 @@ <?php include_once $_SERVER['DOCUMENT_ROOT'] . '/../config.php'; +function is_swf_file($filename) +{ + if (!is_readable($filename)) { + return false; + } + + $fh = fopen($filename, 'rb'); + if (!$fh) + return false; + + $header = fread($fh, 8); + fclose($fh); + + if (strlen($header) < 8) { + return false; + } + + $signature = substr($header, 0, 3); + $version = ord($header[3]); + + if (in_array($signature, ['FWS', 'CWS', 'ZWS'])) { + if ($version >= 6 && $version <= 50) { + return true; + } + } + + return false; +} + +function parse_swf_file(string $file_path): array +{ + $fh = fopen($file_path, 'rb'); + if (!$fh) { + throw new RuntimeException('Failed to open the file!'); + } + + $chunk = fread($fh, 512 * 1024); + fclose($fh); + + if (strlen($chunk) < 9) { + throw new RuntimeException('File too short.'); + } + + $signature = substr($chunk, 0, 3); + if (!in_array($signature, ['FWS', 'CWS', 'ZWS'])) { + throw new RuntimeException('Not a valid SWF.'); + } + + if ($signature === 'CWS') { + $decompressed = gzuncompress(substr($chunk, 8)); + if ($decompressed === false) { + throw new RuntimeException('Bad compressed SWF.'); + } + $data = $decompressed; + } else if ($signature === 'ZWS') { + throw new RuntimeException('LZMA SWF is not supported'); + } else { + $data = substr($chunk, 8); + } + + $bits = ord($data[0]) >> 3; + $bitstr = ''; + for ($i = 0; $i < ceil((5 + 4 * $bits) / 8); $i++) { + $bitstr .= str_pad(decbin(ord($data[$i])), 8, '0', STR_PAD_LEFT); + } + + $nbits = bindec(substr($bitstr, 0, 5)); + $pos = 5; + $xmin = bindec(substr($bitstr, $pos, $nbits)); + $pos += $nbits; + $xmax = bindec(substr($bitstr, $pos, $nbits)); + $pos += $nbits; + $ymin = bindec(substr($bitstr, $pos, $nbits)); + $pos += $nbits; + $ymax = bindec(substr($bitstr, $pos, $nbits)); + $pos += $nbits; + + $width = ($xmax - $xmin) / 20; + $height = ($ymax - $ymin) / 20; + + return [$width, $height]; +} + function verify_mimetype(string $file_path, string $mimetype): bool { $path = escapeshellarg($file_path); @@ -15,9 +98,7 @@ function verify_mimetype(string $file_path, string $mimetype): bool exec($cmd, $output, $exitCode); return $exitCode === 0; } else if ($mimetype == 'application/x-shockwave-flash') { - $cmd = "swfdump $path 2>&1"; - exec($cmd, $output, $exitCode); - return $exitCode === 0; + return is_swf_file($file_path); } throw new RuntimeException("Illegal type for MIME verifications: $mimetype"); diff --git a/lib/thumbnails.php b/lib/thumbnails.php index 5e99087..5afc775 100644 --- a/lib/thumbnails.php +++ b/lib/thumbnails.php @@ -10,15 +10,7 @@ function generate_image_thumbnail(string $src_path, string $dst_path, int $width $result_code = null; - if (str_ends_with($src_path, ".swf")) { - exec(command: "swfrender $input_path -o $output_path", result_code: $result_code); - if ($result_code != 0) { - return $result_code; - } - exec(command: "magick $output_path -resize {$width}x{$height} -loop 0 $output_path", result_code: $result_code); - } else { - exec(command: "magick $input_path -resize {$width}x{$height} -loop 0 $output_path", result_code: $result_code); - } + exec(command: "magick $input_path -resize {$width}x{$height} -loop 0 $output_path", result_code: $result_code); return $result_code; } diff --git a/public/catalogue.php b/public/catalogue.php index f2a5cd6..764b7d2 100644 --- a/public/catalogue.php +++ b/public/catalogue.php @@ -77,15 +77,20 @@ unset($f); <div class="brick<?= isset($file['color']) ? " {$file['color']}" : '' ?>"> <a href="/<?= sprintf('%s.%s', $file['id'], $file['extension']) ?>"> <i title="<?= $file['thumb_title'] ?>"> - <?php if (str_starts_with($file['mime'], 'image/') || str_starts_with($file['mime'], 'video/') || $file['mime'] == 'application/x-shockwave-flash'): ?> + <?php if (str_starts_with($file['mime'], 'image/') || str_starts_with($file['mime'], 'video/')): ?> <img src="<?= sprintf('%s/%s.webp', FILE_THUMBNAIL_DIRECTORY_PREFIX, $file['id']) ?>" alt="No thumbnail." loading="lazy"> <?php elseif (str_starts_with($file['mime'], 'audio/')): ?> - <img src="/static/img/icons/file_audio.png" alt="No thumbnail." loading="lazy"> + <img src="/static/img/icons/file_audio.png" alt="No thumbnail." loading="lazy" width="64" + height="64"> <?php elseif (str_starts_with($file['mime'], 'text/')): ?> - <img src="/static/img/icons/file_text.png" alt="No thumbnail." loading="lazy"> + <img src="/static/img/icons/file_text.png" alt="No thumbnail." loading="lazy" width="64" + height="64"> + <?php elseif ($file['mime'] == 'application/x-shockwave-flash'): ?> + <img src="/static/img/icons/file_flash.png" alt="No thumbnail." loading="lazy" width="64" + height="64"> <?php else: ?> - <img src="/static/img/icons/file.png" alt="No thumbnail."> + <img src="/static/img/icons/file.png" alt="No thumbnail." width="64" height="64"> <?php endif; ?> </i> </a> diff --git a/public/index.php b/public/index.php index a9ddec3..4d912c3 100644 --- a/public/index.php +++ b/public/index.php @@ -659,7 +659,9 @@ $privacy_exists = is_file($_SERVER['DOCUMENT_ROOT'] . '/static/PRIVACY.txt'); thumbnailPath = '/static/img/icons/file_audio.png'; } else if (file.mime.startsWith('text/')) { thumbnailPath = '/static/img/icons/file_text.png'; - } else if (!file.mime.startsWith('image/') && !file.mime.startsWith('video/') && file.mime != 'application/x-shockwave-flash') { + } else if (file.mime == 'application/x-shockwave-flash') { + thumbnailPath = '/static/img/icons/file_flash.png'; + } else if (!file.mime.startsWith('image/') && !file.mime.startsWith('video/')) { thumbnailPath = '/static/img/icons/file.png'; } else { thumbnailSize = 'max-width:100%; max-height: 100%;'; diff --git a/public/static/img/icons/file_flash.png b/public/static/img/icons/file_flash.png Binary files differnew file mode 100755 index 0000000..5769120 --- /dev/null +++ b/public/static/img/icons/file_flash.png diff --git a/public/upload.php b/public/upload.php index c5a2e7e..15a66d2 100644 --- a/public/upload.php +++ b/public/upload.php @@ -207,7 +207,7 @@ try { if ( FILE_THUMBNAILS && ( ( - (str_starts_with($file_data['mime'], 'image/') || $file_data['mime'] == 'application/x-shockwave-flash') && + str_starts_with($file_data['mime'], 'image/') && $thumbnail_error = generate_image_thumbnail( FILE_UPLOAD_DIRECTORY . "/{$file_id}.{$file_data['extension']}", FILE_THUMBNAIL_DIRECTORY . "/{$file_id}.webp", @@ -255,8 +255,9 @@ try { } else if (str_starts_with($file_data['mime'], 'text/')) { $file_data['metadata']['line_count'] = intval(trim(shell_exec('wc -l < ' . escapeshellarg($file_path)))); } else if ($file_data['mime'] == 'application/x-shockwave-flash') { - $file_data['metadata']['width'] = intval(substr(trim(shell_exec("swfdump -X $file_path_escaped")), 3)); - $file_data['metadata']['height'] = intval(substr(trim(shell_exec("swfdump -Y $file_path_escaped")), 3)); + [$width, $height] = parse_swf_file($file_path); + $file_data['metadata']['width'] = $width; + $file_data['metadata']['height'] = $height; } $file_data['urls'] = [ |
