lib/mangle: cleanup, add unhexmangle
* use strchr() rather than for() * small refactoring in mangle code * add un-hex-mangle Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
cd49218679
commit
95387b6696
|
@ -8,6 +8,8 @@
|
|||
extern char *mangle(const char *s);
|
||||
|
||||
extern void unmangle_to_buffer(const char *s, char *buf, size_t len);
|
||||
void unhexmangle_to_buffer(const char *s, char *buf, size_t len);
|
||||
|
||||
extern char *unmangle(const char *s, char **end);
|
||||
|
||||
static inline void unmangle_string(char *s)
|
||||
|
@ -15,5 +17,10 @@ static inline void unmangle_string(char *s)
|
|||
unmangle_to_buffer(s, s, strlen(s) + 1);
|
||||
}
|
||||
|
||||
static inline void unhexmangle_string(char *s)
|
||||
{
|
||||
unhexmangle_to_buffer(s, s, strlen(s) + 1);
|
||||
}
|
||||
|
||||
#endif /* UTIL_LINUX_MANGLE_H */
|
||||
|
||||
|
|
57
lib/mangle.c
57
lib/mangle.c
|
@ -13,41 +13,40 @@
|
|||
#include "mangle.h"
|
||||
#include "c.h"
|
||||
|
||||
#define isoctal(a) (((a) & ~7) == '0')
|
||||
#define isoctal(a) (((a) & ~7) == '0')
|
||||
|
||||
#define from_hex(c) (isdigit(c) ? c - '0' : tolower(c) - 'a' + 10)
|
||||
|
||||
#define is_unwanted_char(x) (strchr(" \t\n\\", (unsigned int) x) != NULL)
|
||||
|
||||
static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
|
||||
|
||||
char *mangle(const char *s)
|
||||
{
|
||||
char *ss, *sp;
|
||||
size_t n;
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
n = strlen(s);
|
||||
ss = sp = malloc(4*n+1);
|
||||
ss = sp = malloc(4 * strlen(s) + 1);
|
||||
if (!sp)
|
||||
return NULL;
|
||||
while(1) {
|
||||
for (n = 0; n < sizeof(need_escaping); n++) {
|
||||
if (*s == need_escaping[n]) {
|
||||
*sp++ = '\\';
|
||||
*sp++ = '0' + ((*s & 0300) >> 6);
|
||||
*sp++ = '0' + ((*s & 070) >> 3);
|
||||
*sp++ = '0' + (*s & 07);
|
||||
goto next;
|
||||
}
|
||||
if (is_unwanted_char(*s)) {
|
||||
*sp++ = '\\';
|
||||
*sp++ = '0' + ((*s & 0300) >> 6);
|
||||
*sp++ = '0' + ((*s & 070) >> 3);
|
||||
*sp++ = '0' + (*s & 07);
|
||||
} else {
|
||||
*sp++ = *s;
|
||||
if (!*s)
|
||||
break;
|
||||
}
|
||||
*sp++ = *s;
|
||||
if (*s == 0)
|
||||
break;
|
||||
next:
|
||||
s++;
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
|
||||
|
||||
void unmangle_to_buffer(const char *s, char *buf, size_t len)
|
||||
{
|
||||
size_t sz = 0;
|
||||
|
@ -70,6 +69,28 @@ void unmangle_to_buffer(const char *s, char *buf, size_t len)
|
|||
*buf = '\0';
|
||||
}
|
||||
|
||||
void unhexmangle_to_buffer(const char *s, char *buf, size_t len)
|
||||
{
|
||||
size_t sz = 0;
|
||||
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
while(*s && sz < len - 1) {
|
||||
if (*s == '\\' && sz + 4 < len - 1 && s[1] == 'x' &&
|
||||
isxdigit(s[2]) && isxdigit(s[3])) {
|
||||
|
||||
*buf++ = from_hex(s[2]) << 4 | from_hex(s[3]);
|
||||
s += 4;
|
||||
sz += 4;
|
||||
} else {
|
||||
*buf++ = *s++;
|
||||
sz++;
|
||||
}
|
||||
}
|
||||
*buf = '\0';
|
||||
}
|
||||
|
||||
static inline char *skip_nonspaces(const char *s)
|
||||
{
|
||||
while (*s && !(*s == ' ' || *s == '\t'))
|
||||
|
@ -110,7 +131,7 @@ char *unmangle(const char *s, char **end)
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "usage: %s --mangle | --unmangle <string>\n",
|
||||
fprintf(stderr, "usage: %s --mangle|unmangle <string>\n",
|
||||
program_invocation_short_name);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue