@ @ requires \valid_read(ministream + (0 .. ministream_size-1)); @ requires \valid_read(minifat + (0 .. minifat_entries-1)); @ requires \initialized(ministream + (0 .. ministream_size-1)); @ requires \initialized(minifat + (0 .. minifat_entries-1)); @ requires uMiniSectorShift==6; @ requires 48 <= len <= 1024*1024; @ ensures \result!=\null ==> \valid((char *)\result + (0 .. len-1));
| 1410 | @ ensures \result!=\null ==> \initialized((char *)\result + (0 .. len-1)); |
| 1411 | @*/ |
| 1412 | static void *OLE_read_ministream(const unsigned char *ministream, |
| 1413 | const uint32_t *minifat, const unsigned int minifat_entries, const unsigned int uMiniSectorShift, |
| 1414 | const unsigned int miniblock_start, const unsigned int len, const unsigned int ministream_size) |
| 1415 | { |
| 1416 | unsigned char *dataPt; |
| 1417 | unsigned int mblock=miniblock_start; |
| 1418 | unsigned int size_read; |
| 1419 | /*@ assert uMiniSectorShift==6; */ |
| 1420 | #ifdef DISABLED_FOR_FRAMAC |
| 1421 | const unsigned int len_aligned=(1024*1024+(1<<uMiniSectorShift)-1) / (1<<uMiniSectorShift) * (1<<uMiniSectorShift); |
| 1422 | #else |
| 1423 | const unsigned int len_aligned=(len+(1<<uMiniSectorShift)-1) / (1<<uMiniSectorShift) * (1<<uMiniSectorShift); |
| 1424 | #endif |
| 1425 | dataPt=(unsigned char *)MALLOC(len_aligned); |
| 1426 | /*@ |
| 1427 | @ loop invariant uMiniSectorShift==6; |
| 1428 | @ loop invariant 48 <= len <= 1024*1024; |
| 1429 | @ loop invariant 0 <= size_read < len + (1<<uMiniSectorShift); |
| 1430 | @ loop invariant size_read > 0 ==> \initialized(dataPt + size_read - (1<<uMiniSectorShift) + (0 .. (1<<uMiniSectorShift)- 1)); |
| 1431 | @ loop invariant size_read > 0 ==> \initialized(dataPt + (0 .. size_read - 1)); |
| 1432 | @ loop variant len - size_read; |
| 1433 | @*/ |
| 1434 | for(size_read=0; |
| 1435 | size_read < len; |
| 1436 | size_read+=(1<<uMiniSectorShift)) |
| 1437 | { |
| 1438 | if(mblock >= minifat_entries) |
| 1439 | { |
| 1440 | free(dataPt); |
| 1441 | return NULL; |
| 1442 | } |
| 1443 | if(mblock >= ministream_size>>uMiniSectorShift) |
| 1444 | { |
| 1445 | free(dataPt); |
| 1446 | return NULL; |
| 1447 | } |
| 1448 | /*@ assert mblock < ministream_size>>uMiniSectorShift; */ |
| 1449 | memcpy(&dataPt[size_read], &ministream[mblock<<uMiniSectorShift], (1<<uMiniSectorShift)); |
| 1450 | /*@ assert \initialized(dataPt + size_read + (0 .. (1<<uMiniSectorShift)-1)); */ |
| 1451 | /*@ assert \valid_read(minifat + mblock); */ |
| 1452 | mblock=le32(minifat[mblock]); |
| 1453 | } |
| 1454 | /*@ assert \initialized(dataPt + (0 .. len - 1)); */ |
| 1455 | return dataPt; |
| 1456 | } |
| 1457 | |
| 1458 | /*@ |
| 1459 | @ requires \valid(file); |
no test coverage detected