@ @ requires \valid(IN); @ requires \valid_read(fat + (0 .. fat_entries-1)); @ requires 9 == uSectorShift || 12 == uSectorShift; @ requires 0 < len <= 1024*1024; @ requires \separated(IN, fat + (..), &errno, &Frama_C_entropy_source); @ ensures \result!=\null ==> \valid((char *)\result + (0 .. len - 1)); @ ensures \result!=\null ==> \initialized((char *)\result + (0 .. len - 1)); @*
| 685 | @ ensures \result!=\null ==> \initialized((char *)\result + (0 .. len - 1)); |
| 686 | @*/ |
| 687 | static void *OLE_read_stream(FILE *IN, |
| 688 | const uint32_t *fat, const unsigned int fat_entries, const unsigned int uSectorShift, |
| 689 | const unsigned int block_start, const unsigned int len, const uint64_t offset) |
| 690 | { |
| 691 | //@ split uSectorShift; |
| 692 | char *dataPt; |
| 693 | unsigned int block; |
| 694 | unsigned int i; |
| 695 | /*@ assert 9 == uSectorShift || 12 == uSectorShift; */ |
| 696 | const unsigned int i_max=((len+(1<<uSectorShift)-1) >> uSectorShift); |
| 697 | #ifdef DISABLED_FOR_FRAMAC |
| 698 | dataPt=(char *)MALLOC(((1024*1024+(1<<uSectorShift)-1) >> uSectorShift) << uSectorShift); |
| 699 | #else |
| 700 | dataPt=(char *)MALLOC(i_max << uSectorShift); |
| 701 | #endif |
| 702 | /*@ assert \valid(dataPt + ( 0 .. len-1)); */ |
| 703 | /*@ |
| 704 | @ loop invariant 0 <= i <= i_max; |
| 705 | @ loop invariant i > 0 ==> \initialized(dataPt + ((i-1)<<uSectorShift) + (0 .. (1<<uSectorShift)- 1)); |
| 706 | @ loop invariant i > 0 ==> \initialized(dataPt + (0 .. (i<<uSectorShift)- 1)); |
| 707 | @ loop variant i_max - i; |
| 708 | @*/ |
| 709 | for(i=0, block=block_start; |
| 710 | i < i_max; |
| 711 | i++, block=le32(fat[block])) |
| 712 | { |
| 713 | if(!(block < fat_entries)) |
| 714 | { |
| 715 | free(dataPt); |
| 716 | return NULL; |
| 717 | } |
| 718 | if(OLE_read_block(IN, &dataPt[i<<uSectorShift], uSectorShift, block, offset)<0) |
| 719 | { |
| 720 | free(dataPt); |
| 721 | return NULL; |
| 722 | } |
| 723 | /*@ assert \initialized(dataPt + ((i<<uSectorShift) .. (i<<uSectorShift) + (1<<uSectorShift)- 1)); */ |
| 724 | /*@ assert \initialized(dataPt + (i<<uSectorShift) + (0 .. (1<<uSectorShift)- 1)); */ |
| 725 | } |
| 726 | /*@ assert \initialized(dataPt + (0 .. (i_max<<uSectorShift)- 1)); */ |
| 727 | /*@ assert \initialized(dataPt + (0 .. len - 1)); */ |
| 728 | /*@ assert \valid(dataPt + (0 .. len - 1)); */ |
| 729 | return dataPt; |
| 730 | } |
| 731 | |
| 732 | /*@ |
| 733 | @ requires \valid(IN); |
no test coverage detected