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 fa == fb;
}
-int chattr_fd(int fd, bool b, int mask) {
- int old_attr, new_attr;
+int chattr_fd(int fd, bool b, unsigned mask) {
+ unsigned old_attr, new_attr;
assert(fd >= 0);
+ if (mask == 0)
+ return 0;
+
if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
return -errno;
return 0;
}
-int chattr_path(const char *p, bool b, int mask) {
+int chattr_path(const char *p, bool b, unsigned mask) {
_cleanup_close_ int fd = -1;
+ assert(p);
+
+ if (mask == 0)
+ return 0;
+
fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
if (fd < 0)
return -errno;