From 3d87d7c1f2fe3504226e1dc80149befa77ff7061 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Tue, 20 Jan 2015 18:23:04 +0100 Subject: [PATCH] XXX don't push - unit tests for vfs_snapper string encode/decode vfs_snapper_test.c includes copies of the vfs_snapper string encoder and decoder functions, so isn't suitable for upstream. --- source4/torture/local/local.c | 1 + source4/torture/local/vfs_snapper_test.c | 202 +++++++++++++++++++++++++++++++ source4/torture/local/wscript_build | 3 + 3 files changed, 206 insertions(+) create mode 100644 source4/torture/local/vfs_snapper_test.c diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c index f69c95e..d37636f 100644 --- a/source4/torture/local/local.c +++ b/source4/torture/local/local.c @@ -69,6 +69,7 @@ torture_dsdb_syntax, torture_registry, torture_local_verif_trailer, + torture_local_vfs_snapper, NULL }; diff --git a/source4/torture/local/vfs_snapper_test.c b/source4/torture/local/vfs_snapper_test.c new file mode 100644 index 0000000..c3c1f71 --- /dev/null +++ b/source4/torture/local/vfs_snapper_test.c @@ -0,0 +1,202 @@ +/* + Unix SMB/CIFS implementation. + + unit test suite for vfs_snapper + + Copyright (C) David Disseldorp 2015 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include + +#include "includes.h" +#include "lib/param/param.h" +#include "torture/torture.h" +#include "torture/local/proto.h" + +/* + * 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 bool test_vfs_snapper_str(struct torture_context *tctx) +{ + char *out; + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(tctx); + torture_assert(tctx, mem_ctx != NULL, "memory"); + + status = snapper_dbus_str_encode(mem_ctx, "stuff n' that", &out); + torture_assert_ntstatus_ok(tctx, status, "encode failed"); + torture_assert_str_equal(tctx, out, "stuff n' that", ""); + + status = snapper_dbus_str_encode(mem_ctx, "\\has a slash in it", &out); + torture_assert_ntstatus_ok(tctx, status, "encode failed"); + torture_assert_str_equal(tctx, out, "\\\\has a slash in it", ""); + + status = snapper_dbus_str_encode(mem_ctx, "こんにちは", &out); + torture_assert_ntstatus_ok(tctx, status, "encode failed"); + torture_assert_str_equal(tctx, out, + "\\xe3\\x81\\x93\\xe3\\x82\\x93\\xe3\\x81\\xab" + "\\xe3\\x81\\xa1\\xe3\\x81\\xaf", ""); + + status = snapper_dbus_str_decode(mem_ctx, "\\\\xslash nohex", &out); + torture_assert_ntstatus_ok(tctx, status, "decode failed"); + torture_assert_str_equal(tctx, out, "\\xslash nohex", ""); + + status = snapper_dbus_str_decode(mem_ctx, + "\\xe6\\x82\\xa8\\xe5\\xa5\\xbd", + &out); + torture_assert_ntstatus_ok(tctx, status, "decode failed"); + torture_assert_str_equal(tctx, out, "您好", ""); + + talloc_free(mem_ctx); + + return true; +} + +struct torture_suite *torture_local_vfs_snapper(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, + "vfs_snapper"); + + torture_suite_add_simple_test(suite, + "string_encode_decode", + test_vfs_snapper_str); + + return suite; +} diff --git a/source4/torture/local/wscript_build b/source4/torture/local/wscript_build index eb0b99b..ec1eee8 100644 --- a/source4/torture/local/wscript_build +++ b/source4/torture/local/wscript_build @@ -21,6 +21,9 @@ TORTURE_LOCAL_SOURCE = '''../../../lib/util/charset/tests/iconv.c TORTURE_LOCAL_DEPS = 'RPC_NDR_ECHO TDR LIBCLI_SMB MESSAGING iconv POPT_CREDENTIALS TORTURE_AUTH TORTURE_UTIL TORTURE_NDR TORTURE_LIBCRYPTO share torture_registry PROVISION ldb samdb replace-test' +if bld.SAMBA3_IS_ENABLED_MODULE('vfs_snapper'): + TORTURE_LOCAL_SOURCE += ' vfs_snapper_test.c' + bld.SAMBA_MODULE('TORTURE_LOCAL', source=TORTURE_LOCAL_SOURCE, autoproto='proto.h', -- 2.1.2