@@ -1813,7 +1813,95 @@ static void zend_file_cache_unserialize(zend_persistent_script *script,
18131813 zend_file_cache_unserialize_early_bindings (script , buf );
18141814}
18151815
1816- zend_persistent_script * zend_file_cache_script_load (zend_file_handle * file_handle , bool force_file_cache_only )
1816+ // Function to validate the file cache and return a boolean result
1817+ bool zend_file_cache_script_validate (zend_file_handle * file_handle )
1818+ {
1819+ int fd ;
1820+ char * filename ;
1821+ zend_file_cache_metainfo info ;
1822+ unsigned int actual_checksum ;
1823+ void * mem ;
1824+
1825+ if (!file_handle || !file_handle -> opened_path ) {
1826+ return false;
1827+ }
1828+
1829+ filename = zend_file_cache_get_bin_file_path (file_handle -> opened_path );
1830+ fd = zend_file_cache_open (filename , O_RDONLY | O_BINARY );
1831+ if (fd < 0 ) {
1832+ goto failure ; // Open failed
1833+ }
1834+
1835+ if (zend_file_cache_flock (fd , LOCK_SH ) != 0 ) {
1836+ goto failure_close ; // Flock failed
1837+ }
1838+
1839+
1840+ if (read (fd , & info , sizeof (info )) != sizeof (info )) {
1841+ zend_accel_error (ACCEL_LOG_WARNING , "opcache cannot read from file '%s' (info)\n" , filename );
1842+ goto failure_unlock_close ;
1843+ }
1844+
1845+ // Verify header
1846+ if (memcmp (info .magic , "OPCACHE" , 8 ) != 0 || memcmp (info .system_id , zend_system_id , 32 ) != 0 ) {
1847+ zend_accel_error (ACCEL_LOG_WARNING , "opcache invalid header in file '%s'\n" , filename );
1848+ goto failure_unlock_close ;
1849+ }
1850+
1851+ // Verify timestamp if required
1852+ if (ZCG (accel_directives ).validate_timestamps &&
1853+ zend_get_file_handle_timestamp (file_handle , NULL ) != info .timestamp ) {
1854+ goto failure_unlock_close ;
1855+ }
1856+
1857+ checkpoint = zend_arena_checkpoint (CG (arena ));
1858+ #if defined(__AVX__ ) || defined(__SSE2__ )
1859+ /* Align to 64-byte boundary */
1860+ mem = zend_arena_alloc (& CG (arena ), info .mem_size + info .str_size + 64 );
1861+ mem = (void * )(((uintptr_t )mem + 63L ) & ~63L );
1862+ #else
1863+ mem = zend_arena_alloc (& CG (arena ), info .mem_size + info .str_size );
1864+ #endif
1865+
1866+ if (read (fd , mem , info .mem_size + info .str_size ) != (ssize_t )(info .mem_size + info .str_size )) {
1867+ zend_accel_error (ACCEL_LOG_WARNING , "opcache cannot read from file '%s' (mem)\n" , filename );
1868+ zend_arena_release (& CG (arena ), checkpoint );
1869+ goto failure_unlock_close ;
1870+ }
1871+ if (zend_file_cache_flock (fd , LOCK_UN ) != 0 ) {
1872+ zend_accel_error (ACCEL_LOG_WARNING , "opcache cannot unlock file '%s'\n" , filename );
1873+ }
1874+ close (fd );
1875+
1876+ /* verify checksum */
1877+ if (ZCG (accel_directives ).file_cache_consistency_checks &&
1878+ (actual_checksum = zend_adler32 (ADLER32_INIT , mem , info .mem_size + info .str_size )) != info .checksum ) {
1879+ zend_accel_error (ACCEL_LOG_WARNING , "corrupted file '%s' excepted checksum: 0x%08x actual checksum: 0x%08x\n" , filename , info .checksum , actual_checksum );
1880+ zend_arena_release (& CG (arena ), checkpoint );
1881+ goto failure ;
1882+ }
1883+
1884+ zend_arena_release (& CG (arena ), checkpoint );
1885+ zend_file_cache_flock (fd , LOCK_UN );
1886+ close (fd );
1887+ efree (filename );
1888+ return true; // Validation successful
1889+
1890+ failure_unlock_close :
1891+ zend_file_cache_flock (fd , LOCK_UN );
1892+ failure_close :
1893+ close (fd );
1894+ failure :
1895+ if (!ZCG (accel_directives ).file_cache_read_only ) {
1896+ zend_file_cache_unlink (filename );
1897+ }
1898+ efree (filename );
1899+
1900+ return false; // Validation failed
1901+ }
1902+
1903+
1904+ zend_persistent_script * zend_file_cache_script_load (zend_file_handle * file_handle )
18171905{
18181906 zend_string * full_path = file_handle -> opened_path ;
18191907 int fd ;
@@ -1928,7 +2016,6 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
19282016 }
19292017
19302018 if (!file_cache_only &&
1931- !force_file_cache_only &&
19322019 !ZCSG (restart_in_progress ) &&
19332020 !ZCSG (restart_pending ) &&
19342021 !ZSMMG (memory_exhausted ) &&
0 commit comments