memcpy(r, prefix, pl);
for (f = s, t = r + pl; f < s + length; f++) {
+ size_t remaining = s + length - f;
+ assert(remaining > 0);
- if (*f != '\\') {
+ if (*f != '\\') { /* a literal literal */
*(t++) = *f;
continue;
}
+ if (--remaining == 0) { /* copy trailing backslash verbatim */
+ *(t++) = *f;
+ break;
+ }
+
f++;
switch (*f) {
case 'x': {
/* hexadecimal encoding */
- int a, b;
+ int a = -1, b = -1;
- a = unhexchar(f[1]);
- b = unhexchar(f[2]);
+ if (remaining >= 2) {
+ a = unhexchar(f[1]);
+ b = unhexchar(f[2]);
+ }
if (a < 0 || b < 0 || (a == 0 && b == 0)) {
/* Invalid escape code, let's take it literal then */
case '6':
case '7': {
/* octal encoding */
- int a, b, c;
+ int a = -1, b = -1, c = -1;
- a = unoctchar(f[0]);
- b = unoctchar(f[1]);
- c = unoctchar(f[2]);
+ if (remaining >= 3) {
+ a = unoctchar(f[0]);
+ b = unoctchar(f[1]);
+ c = unoctchar(f[2]);
+ }
if (a < 0 || b < 0 || c < 0 || (a == 0 && b == 0 && c == 0)) {
/* Invalid escape code, let's take it literal then */
break;
}
- case 0:
- /* premature end of string. */
- *(t++) = '\\';
- goto finish;
-
default:
/* Invalid escape code, let's take it literal then */
*(t++) = '\\';
}
}
-finish:
*t = 0;
return r;
}
return (uint64_t) mem * (uint64_t) page_size();
}
-char* mount_test_option(const char *haystack, const char *needle) {
-
- struct mntent me = {
- .mnt_opts = (char*) haystack
- };
-
- assert(needle);
-
- /* Like glibc's hasmntopt(), but works on a string, not a
- * struct mntent */
-
- if (!haystack)
- return NULL;
-
- return hasmntopt(&me, needle);
-}
-
void hexdump(FILE *f, const void *p, size_t s) {
const uint8_t *b = p;
unsigned n = 0;