add notion about non-null
[ss1617.git] / prefast / MartLubbers_prefast_exercise.cpp
1 /*
2 * Mart Lubbers (s4109503)
3 */
4 #include "stdafx.h"
5 #include "stdio.h"
6 #undef __analysis_assume
7 #include <CodeAnalysis\SourceAnnotations.h>
8
9 #define BUF_SIZE 100
10 #define STR_SIZE 200
11
12 void zeroing();
13
14 char *my_alloc(size_t size)
15 {
16 //FIXED
17 char *ch = (char *)calloc(size, 1);
18 if (ch == NULL){
19 perror("malloc");
20 exit(EXIT_FAILURE);
21 }
22 return ch;
23 }
24
25 bool input([SA_Post(Tainted=SA_Yes)] _Out_cap_c_(BUF_SIZE) char *buf)
26 {
27 //FIXED
28 return (gets_s(buf, BUF_SIZE) != NULL) ? true : false;
29 }
30
31 [returnvalue:SA_Post(Tainted=SA_Yes)] char *do_read()
32 {
33 //FIXED
34 char *buf = my_alloc(STR_SIZE);
35 printf("Allocated a string at %p", buf);
36 if(!input(buf)){
37 puts("Error!");
38 exit(EXIT_FAILURE);
39 }
40 if (buf[0] == '\0')
41 printf("empty string");
42 return buf;
43 }
44
45 void copy_data([SA_Pre(Tainted=SA_Yes)]_In_count_c_(STR_SIZE) char *buf1, [SA_Post(Tainted=SA_Yes)] _Out_cap_c_(STR_SIZE) char *buf2)
46 {
47 memcpy(buf2,buf1,STR_SIZE);
48 buf2[STR_SIZE-1] = NULL; // null terminate, just in case
49 }
50
51 int execute([SA_Pre(Tainted=SA_No)] _In_count_c_(BUF_SIZE) char *buf)
52 {
53 return system(buf); // pass buf as command to be executed by the OS
54 }
55
56 void validate([SA_Pre(Tainted=SA_Yes)][SA_Post(Tainted=SA_No)] _Inout_count_c_(BUF_SIZE) char *buf)
57 {
58 // This is a magical validation method, which turns tainted data
59 // into untainted data, for which the code not shown.
60 //
61 // A real implementation might for example use a whitelist to filter
62 // the string.
63 }
64
65 _Check_return_ int test_ready()
66 {
67 // code not shown
68 return 1;
69 }
70
71 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
72 {
73 char *buf1 = do_read();
74 char *buf2 = my_alloc(BUF_SIZE);
75 zeroing();
76 //FIXED
77 if(test_ready() != 0){
78 printf("Test not ready\n");
79 exit(EXIT_FAILURE);
80 }
81 //FIXED
82 validate(buf1);
83 execute(buf1);
84
85 char* buf3 = do_read();
86 copy_data(buf3, buf2);
87 //FIXED
88 validate(buf2);
89 execute(buf2);
90
91 char *buf4 = do_read();
92 //FIXED
93 validate(buf4);
94 execute(buf4);
95 }
96
97 // *****************************************************************
98
99 void zero(_Out_cap_(len) int *buf, int len)
100 {
101 int i;
102 //FIXED
103 for(i = 0; i < len; i++)
104 buf[i] = 0;
105 }
106
107 void zeroboth(
108 _Out_cap_(len) int *buf, int len,
109 _Out_cap_(len3) int *buf3, int len3)
110 {
111 int *buf2 = buf;
112 int len2 = len;
113 zero(buf2, len2);
114 zero(buf3, len3);
115 }
116
117 void zeroboth2(_Out_cap_(len3) int *buf, int len, _Out_cap_(len) int *buf3, int len3)
118 {
119 zeroboth(buf, len3, buf3, len);
120 }
121
122 void zeroing()
123 {
124 int elements[200];
125 int oelements[100];
126 //FIXED
127 zeroboth2(elements, 100, oelements, 200);
128 }