summaryrefslogtreecommitdiffstats
path: root/src/basic/escape.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic/escape.c')
-rw-r--r--src/basic/escape.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/basic/escape.c b/src/basic/escape.c
index 75a1d68..2067be4 100644
--- a/src/basic/escape.c
+++ b/src/basic/escape.c
@@ -451,6 +451,12 @@ char* octescape(const char *s, size_t len) {
assert(s || len == 0);
+ if (len == SIZE_MAX)
+ len = strlen(s);
+
+ if (len > (SIZE_MAX - 1) / 4)
+ return NULL;
+
t = buf = new(char, len * 4 + 1);
if (!buf)
return NULL;
@@ -471,6 +477,33 @@ char* octescape(const char *s, size_t len) {
return buf;
}
+char* decescape(const char *s, const char *bad, size_t len) {
+ char *buf, *t;
+
+ /* Escapes all chars in bad, in addition to \ and " chars, in \nnn decimal style escaping. */
+
+ assert(s || len == 0);
+
+ t = buf = new(char, len * 4 + 1);
+ if (!buf)
+ return NULL;
+
+ for (size_t i = 0; i < len; i++) {
+ uint8_t u = (uint8_t) s[i];
+
+ if (u < ' ' || u >= 127 || IN_SET(u, '\\', '"') || strchr(bad, u)) {
+ *(t++) = '\\';
+ *(t++) = '0' + (u / 100);
+ *(t++) = '0' + ((u / 10) % 10);
+ *(t++) = '0' + (u % 10);
+ } else
+ *(t++) = u;
+ }
+
+ *t = 0;
+ return buf;
+}
+
static char* strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
assert(bad);
assert(t);