| 
									
										
										
										
											2021-11-01 01:58:56 +08:00
										 |  |  | <?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', | 
					
						
							| 
									
										
										
										
											2022-06-09 05:30:23 +08:00
										 |  |  |         'audio/aac', | 
					
						
							|  |  |  |         'audio/midi', | 
					
						
							|  |  |  |         'audio/mpeg', | 
					
						
							|  |  |  |         'audio/ogg', | 
					
						
							|  |  |  |         'audio/opus', | 
					
						
							|  |  |  |         'audio/wav', | 
					
						
							|  |  |  |         'audio/webm', | 
					
						
							| 
									
										
										
										
											2022-06-09 06:50:42 +08:00
										 |  |  |         'audio/x-m4a', | 
					
						
							| 
									
										
										
										
											2022-01-04 21:10:35 +08:00
										 |  |  |         'image/apng', | 
					
						
							| 
									
										
										
										
											2021-11-01 01:58:56 +08:00
										 |  |  |         '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'; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-11-01 21:26:02 +08:00
										 |  |  | } |