73 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
| <?php
 | |
| 
 | |
| namespace BookStack\Util;
 | |
| 
 | |
| use finfo;
 | |
| 
 | |
| /**
 | |
|  * Helper class to sniff out the mime-type of content resulting in
 | |
|  * a mime-type that's relatively safe to serve to a browser.
 | |
|  */
 | |
| class WebSafeMimeSniffer
 | |
| {
 | |
|     /**
 | |
|      * @var string[]
 | |
|      */
 | |
|     protected $safeMimes = [
 | |
|         'application/json',
 | |
|         'application/octet-stream',
 | |
|         'application/pdf',
 | |
|         'audio/aac',
 | |
|         'audio/midi',
 | |
|         'audio/mpeg',
 | |
|         'audio/ogg',
 | |
|         'audio/opus',
 | |
|         'audio/wav',
 | |
|         'audio/webm',
 | |
|         'audio/x-m4a',
 | |
|         'image/apng',
 | |
|         'image/bmp',
 | |
|         'image/jpeg',
 | |
|         'image/png',
 | |
|         'image/gif',
 | |
|         'image/webp',
 | |
|         'image/avif',
 | |
|         'image/heic',
 | |
|         'text/css',
 | |
|         'text/csv',
 | |
|         'text/javascript',
 | |
|         'text/json',
 | |
|         'text/plain',
 | |
|         'video/x-msvideo',
 | |
|         'video/mp4',
 | |
|         'video/mpeg',
 | |
|         'video/ogg',
 | |
|         'video/webm',
 | |
|         'video/vp9',
 | |
|         'video/h264',
 | |
|         'video/av1',
 | |
|     ];
 | |
| 
 | |
|     /**
 | |
|      * Sniff the mime-type from the given file content while running the result
 | |
|      * through an allow-list to ensure a web-safe result.
 | |
|      * Takes the content as a reference since the value may be quite large.
 | |
|      */
 | |
|     public function sniff(string &$content): string
 | |
|     {
 | |
|         $fInfo = new finfo(FILEINFO_MIME_TYPE);
 | |
|         $mime = $fInfo->buffer($content) ?: 'application/octet-stream';
 | |
| 
 | |
|         if (in_array($mime, $this->safeMimes)) {
 | |
|             return $mime;
 | |
|         }
 | |
| 
 | |
|         [$category] = explode('/', $mime, 2);
 | |
|         if ($category === 'text') {
 | |
|             return 'text/plain';
 | |
|         }
 | |
| 
 | |
|         return 'application/octet-stream';
 | |
|     }
 | |
| }
 |