mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
vfs_snapper: add DBus string encoding and decoding helpers
Snapper uses the following mechanism for encoding and decoding strings used in DBus traffic: Characters above 127 (0x7F - ASCII DEL) must be encoded hexadecimal as "\x??". As a consequence "\" must be encoded as "\\". This change adds string encoding and decoding helpers to vfs_snapper. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11055 Signed-off-by: David Disseldorp <ddiss@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
f72fa6390b
commit
3d48fc9673
@ -91,6 +91,130 @@ static NTSTATUS snapper_err_ntstatus_map(const char *snapper_err_str)
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Strings are UTF-8. Other characters must be encoded hexadecimal as "\x??".
|
||||
* As a consequence "\" must be encoded as "\\".
|
||||
*/
|
||||
static NTSTATUS snapper_dbus_str_encode(TALLOC_CTX *mem_ctx, const char *in_str,
|
||||
char **_out_str)
|
||||
{
|
||||
size_t in_len;
|
||||
char *out_str;
|
||||
int i;
|
||||
int out_off;
|
||||
int out_len;
|
||||
|
||||
if (in_str == NULL) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
in_len = strlen(in_str);
|
||||
|
||||
/* output can be max 4 times the length of @in_str, +1 for terminator */
|
||||
out_len = (in_len * 4) + 1;
|
||||
|
||||
out_str = talloc_array(mem_ctx, char, out_len);
|
||||
if (out_str == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
out_off = 0;
|
||||
for (i = 0; i < in_len; i++) {
|
||||
size_t pushed;
|
||||
|
||||
if (in_str[i] == '\\') {
|
||||
pushed = snprintf(out_str + out_off, out_len - out_off,
|
||||
"\\\\");
|
||||
} else if ((unsigned char)in_str[i] > 127) {
|
||||
pushed = snprintf(out_str + out_off, out_len - out_off,
|
||||
"\\x%02x", (unsigned char)in_str[i]);
|
||||
} else {
|
||||
/* regular character */
|
||||
*(out_str + out_off) = in_str[i];
|
||||
pushed = sizeof(char);
|
||||
}
|
||||
if (pushed >= out_len - out_off) {
|
||||
/* truncated, should never happen */
|
||||
talloc_free(out_str);
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
out_off += pushed;
|
||||
}
|
||||
|
||||
*(out_str + out_off) = '\0';
|
||||
*_out_str = out_str;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS snapper_dbus_str_decode(TALLOC_CTX *mem_ctx, const char *in_str,
|
||||
char **_out_str)
|
||||
{
|
||||
size_t in_len;
|
||||
char *out_str;
|
||||
int i;
|
||||
int out_off;
|
||||
int out_len;
|
||||
|
||||
if (in_str == NULL) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
in_len = strlen(in_str);
|
||||
|
||||
/* output cannot be larger than input, +1 for terminator */
|
||||
out_len = in_len + 1;
|
||||
|
||||
out_str = talloc_array(mem_ctx, char, out_len);
|
||||
if (out_str == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
out_off = 0;
|
||||
for (i = 0; i < in_len; i++) {
|
||||
int j;
|
||||
char hex_buf[3];
|
||||
unsigned int non_ascii_byte;
|
||||
|
||||
if (in_str[i] != '\\') {
|
||||
out_str[out_off] = in_str[i];
|
||||
out_off++;
|
||||
continue;
|
||||
}
|
||||
|
||||
i++;
|
||||
if (in_str[i] == '\\') {
|
||||
out_str[out_off] = '\\';
|
||||
out_off++;
|
||||
continue;
|
||||
} else if (in_str[i] != 'x') {
|
||||
goto err_invalid_src_encoding;
|
||||
}
|
||||
|
||||
/* non-ASCII, encoded as two hex chars */
|
||||
for (j = 0; j < 2; j++) {
|
||||
i++;
|
||||
if ((in_str[i] == '\0') || !isxdigit(in_str[i])) {
|
||||
goto err_invalid_src_encoding;
|
||||
}
|
||||
hex_buf[j] = in_str[i];
|
||||
}
|
||||
hex_buf[2] = '\0';
|
||||
|
||||
sscanf(hex_buf, "%x", &non_ascii_byte);
|
||||
out_str[out_off] = (unsigned char)non_ascii_byte;
|
||||
out_off++;
|
||||
}
|
||||
|
||||
out_str[out_off] = '\0';
|
||||
*_out_str = out_str;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
err_invalid_src_encoding:
|
||||
DEBUG(0, ("invalid encoding %s\n", in_str));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
static DBusConnection *snapper_dbus_conn_create(void)
|
||||
{
|
||||
DBusError err;
|
||||
|
Loading…
Reference in New Issue
Block a user