1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#include <assert.h> /* assert */
#include <string.h> /* memcpy, strcpy, strncat, strndup */
#include <stdlib.h> /* strto[u?]ll */
/* "Checked" memcpy */
void *__memcpy_chk(void *dest, const void *src, size_t len, size_t destlen)
{
assert(dest != NULL);
assert(src != NULL);
assert(len <= destlen);
if(src < dest)
{
assert(!(src + len >= dest));
} else {
assert(!(dest + len >= src));
}
return memcpy(dest, src, len);
}
/* "Checked" strncat */
char *__strncat_chk(char *dest, const char *src, size_t n, size_t destlen)
{
assert(dest != NULL);
assert(src != NULL);
assert(n <= destlen);
return strncat(dest, src, n);
}
/* "Checked" strcat */
char *__strcat_chk(char *dest, const char *src, size_t destlen)
{
return strncat(dest, src, destlen - 1);
}
/* "Checked" strncpy */
char *__strncpy_chk(char *dest, const char *src, size_t n, size_t destlen)
{
assert(dest != NULL);
assert(src != NULL);
assert(strlen(src) < destlen);
return strncpy(dest, src, n);
}
/* "Checked" strcpy */
char *__strcpy_chk(char *dest, const char *src, size_t destlen)
{
assert(dest != NULL);
assert(src != NULL);
assert(strlen(src) < destlen);
return strcpy(dest, src);
}
/* Literally a useless __ alias. */
char *__strndup(const char *str, size_t count)
{
return strndup(str, count);
}
/* The existance of this method, and the fact it is used in real code, gives
* me nightmares. */
void *rawmemchr(const void *s, int c)
{
const unsigned char *haystack = s;
unsigned char needle = (unsigned char)c;
while(*haystack++ != needle);
return (void *)haystack;
}
extern __typeof(rawmemchr) __rawmemchr __attribute__((weak, alias("rawmemchr")));
/* Another useless __ alias */
char *__strtok_r(char *str, const char *delim, char **saveptr)
{
return strtok_r(str, delim, saveptr);
}
/* The "global" definition of strsep in glibc, used when architecture dependent
* assembler versions aren't good enough. */
char *__strsep_g(char **stringp, const char *delim)
{
return strsep(stringp, delim);
}
/* Some day, when musl supports LC_NUMERIC, we can probably remove these */
long long int strtoll_l(const char *nptr, char **endptr, int base, locale_t locale)
{
return strtoll(nptr, endptr, base);
}
unsigned long long int strtoull_l(const char *nptr, char **endptr, int base, locale_t locale)
{
return strtoull(nptr, endptr, base);
}
|