@ @ requires fr->file_check==&file_check_zip; @ requires valid_file_check_param(fr); @ ensures valid_file_check_result(fr); @ assigns *fr->handle, fr->file_size; @ assigns fr->time, fr->offset_ok, fr->offset_error; @ assigns Frama_C_entropy_source, errno; @ assigns first_filename[0 .. 255]; @ assigns msoffice, sh3d, ext_msoffice, expected_compressed_size; @*/
| 1026 | @ assigns msoffice, sh3d, ext_msoffice, expected_compressed_size; |
| 1027 | @*/ |
| 1028 | static void file_check_zip(file_recovery_t *fr) |
| 1029 | { |
| 1030 | const char *ext=NULL; |
| 1031 | unsigned int file_nbr=0; |
| 1032 | fr->file_size = 0; |
| 1033 | fr->offset_error=0; |
| 1034 | fr->offset_ok=0; |
| 1035 | /* fr->time is already set to 0 but it helps frama-c */ |
| 1036 | fr->time=0; |
| 1037 | first_filename[0]='\0'; |
| 1038 | if(my_fseek(fr->handle, 0, SEEK_SET) < 0) |
| 1039 | return ; |
| 1040 | /*@ |
| 1041 | @ loop assigns *fr->handle, fr->file_size, ext, file_nbr; |
| 1042 | @ loop assigns fr->time, fr->offset_ok, fr->offset_error; |
| 1043 | @ loop assigns Frama_C_entropy_source, errno; |
| 1044 | @ loop assigns first_filename[0 .. 255]; |
| 1045 | @ loop assigns msoffice, sh3d, ext_msoffice, expected_compressed_size; |
| 1046 | @*/ |
| 1047 | while (1) |
| 1048 | { |
| 1049 | uint64_t file_size_old; |
| 1050 | char buf_header[sizeof(uint32_t)]; |
| 1051 | const uint32_t *header_ptr=(const uint32_t *)&buf_header; |
| 1052 | uint32_t header; |
| 1053 | int status; |
| 1054 | if(file_nbr>=0xffffffff || fr->file_size >= 0x8000000000000000 - 4) |
| 1055 | { |
| 1056 | fr->offset_error = fr->file_size; |
| 1057 | fr->file_size = 0; |
| 1058 | return; |
| 1059 | } |
| 1060 | /*@ assert fr->file_size < 0x8000000000000000 - 4; */ |
| 1061 | if (fread(&buf_header, 4, 1, fr->handle)!=1) |
| 1062 | { |
| 1063 | #ifdef DEBUG_ZIP |
| 1064 | log_trace("Failed to read block header\n"); |
| 1065 | #endif |
| 1066 | fr->offset_error=fr->file_size; |
| 1067 | fr->file_size=0; |
| 1068 | return; |
| 1069 | } |
| 1070 | #if defined(__FRAMAC__) |
| 1071 | Frama_C_make_unknown(&buf_header, 4); |
| 1072 | #endif |
| 1073 | header = le32(*header_ptr); |
| 1074 | #ifdef DEBUG_ZIP |
| 1075 | log_trace("Header 0x%08X at 0x%llx\n", header, (long long unsigned int)fr->file_size); |
| 1076 | log_flush(); |
| 1077 | #endif |
| 1078 | fr->file_size += 4; |
| 1079 | file_size_old=fr->file_size; |
| 1080 | /*@ assert fr->file_size < 0x8000000000000000; */ |
| 1081 | |
| 1082 | switch (header) |
| 1083 | { |
| 1084 | case ZIP_CENTRAL_DIR: /* Central dir */ |
| 1085 | status = zip_parse_central_dir(fr); |
no test coverage detected