memset(void *dst, int v, size_t n)
dst == NULL
it will cause Segmentation fault because dst isn't checked against NULL. Why not if (!dst) return NULL;
?For example, usingstrcmp(NULL, NULL)
causes Segmentation fault. But why?
char *a; /* Undefined */
char *b; /* Undefined */
strcmp(a, b);
Given that 0:0000 is IVT in DOS it would be a problem if you could not dereference (far*)0.Some older i.e DOS didn't
...
What I class as "unsafe" and worse than NULL, NULL is:
...Code:char *a; /* Undefined */ char *b; /* Undefined */ strcmp(a, b);
#include <stdio.h>
#include <string.h>
int main(int argc, char *const argv[])
{
char *a; /* Undefined */
char *b; /* Undefined */
printf("Hello, I would crash here, won't I? %d\n", strcmp(a, b));
return 0;
}
clang --analyze hello.c -o hello.xml
hello.c:9:55: warning: 1st function call argument is an uninitialized value
printf("Hello, I would crash here, won't I? %d\n", strcmp(a, b));
^~~~~~~~~~~~
1 warning generated.
cat hello.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>clang_version</key>
<string>FreeBSD clang version 6.0.1 (tags/RELEASE_601/final 335540) (based on LLVM 6.0.1)</string>
<key>files</key>
<array>
<string>hello.c</string>
</array>
<key>diagnostics</key>
<array>
<dict>
<key>path</key>
<array>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>6</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>6</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>6</integer>
<key>col</key><integer>10</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>'a' declared without an initial value</string>
<key>message</key>
<string>'a' declared without an initial value</string>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
<array>
<dict>
<key>start</key>
<array>
<dict>
<key>line</key><integer>6</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>6</integer>
<key>col</key><integer>7</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<key>end</key>
<array>
<dict>
<key>line</key><integer>9</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>9</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</dict>
</array>
</dict>
<dict>
<key>kind</key><string>control</string>
<key>edges</key>
<array>
<dict>
<key>start</key>
<array>
<dict>
<key>line</key><integer>9</integer>
<key>col</key><integer>4</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>9</integer>
<key>col</key><integer>9</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
<key>end</key>
<array>
<dict>
<key>line</key><integer>9</integer>
<key>col</key><integer>55</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>9</integer>
<key>col</key><integer>60</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</dict>
</array>
</dict>
<dict>
<key>kind</key><string>event</string>
<key>location</key>
<dict>
<key>line</key><integer>9</integer>
<key>col</key><integer>55</integer>
<key>file</key><integer>0</integer>
</dict>
<key>ranges</key>
<array>
<array>
<dict>
<key>line</key><integer>9</integer>
<key>col</key><integer>62</integer>
<key>file</key><integer>0</integer>
</dict>
<dict>
<key>line</key><integer>9</integer>
<key>col</key><integer>62</integer>
<key>file</key><integer>0</integer>
</dict>
</array>
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>1st function call argument is an uninitialized value</string>
<key>message</key>
<string>1st function call argument is an uninitialized value</string>
</dict>
</array>
<key>description</key><string>1st function call argument is an uninitialized value</string>
<key>category</key><string>Logic error</string>
<key>type</key><string>Uninitialized argument value</string>
<key>check_name</key><string>core.CallAndMessage</string>
<!-- This hash is experimental and going to change! -->
<key>issue_hash_content_of_line_in_context</key><string>98bb79a833b93ac5f7bc0a3d8846b0ce</string>
<key>issue_context_kind</key><string>function</string>
<key>issue_context</key><string>main</string>
<key>issue_hash_function_offset</key><string>4</string>
<key>location</key>
<dict>
<key>line</key><integer>9</integer>
<key>col</key><integer>55</integer>
<key>file</key><integer>0</integer>
</dict>
</dict>
</array>
</dict>
</plist>
hello.c:9:55: warning: Null pointer argument in call to string comparison function
printf("Hello, I would crash here, won't I? %d\n", strcmp(a, b));
^~~~~~~~~~~~
1 warning generated.
clang hello.c && ./a.out
Segmentation fault (core dumped)
Could you please elaborate?Bizarrely some C string handling code is unsafe (i.t toupper) if you use chars rather than int because it can return something outside the range.
Those functions accept an int. They use a lookup table. 8 bit character values above 127 are negative so you get a negative index into the lookup table array. The man page for toupper(3) has this warning: "The argument must be representable as an unsigned char or the value of EOF." If you use getc for fgetc - which return an int - you're okay. But if you use fread or fgets and then pick off individual characters without typecasting as unsigned - bad things happen.Could you please elaborate?
Exactly, so it's not toupper() being unsafe and rather just following the documentation -- if you don't provide the unsigned char value, you get what you asked for; though no bad things would happen, you'll just get the original character back.The argument must be representable as an unsigned char or the value of EOF.
Exactly, so it's not toupper() being unsafe and rather just following the documentation