mirror of
https://github.com/samba-team/samba.git
synced 2025-01-05 09:18:06 +03:00
c4f281e9ae
The LIBNDR_FLAG_ namespace is getting dangerously full, with only a single flag value (1 << 9) remaining for use. After that flag is put into use, we won’t be able to add any new flags without increasing the flag width to 64‐bit. Up to now we’ve used a haphazard mix of int, unsigned, and uint32_t to store these flags. Introduce a new type, ‘libndr_flags’, to be used consistently to hold LIBNDR flags. If in the future we find we need to move to 64‐bit flags, this type gives us an opportunity to do that. Bump the NDR version to 4.0.0 — an major version increment, for we’re changing the function ABI and adding the new symbol ndr_print_libndr_flags. Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
224 lines
8.9 KiB
C
224 lines
8.9 KiB
C
#include "includes.h"
|
|
#include "torture/ndr/ndr.h"
|
|
#include "torture/ndr/proto.h"
|
|
#include "../lib/util/dlinklist.h"
|
|
#include "param/param.h"
|
|
|
|
static const char *ascii = "ascii";
|
|
/* the following is equivalent to "kamelåså öäüÿéèóò" in latin1 */
|
|
static const char latin1[] = { 0x6b, 0x61, 0x6d, 0x65, 0x6c, 0xe5, 0x73,
|
|
0xe5, 0x20, 0xF6, 0xE4, 0xFC, 0xFF, 0xE9,
|
|
0xE8, 0xF3, 0xF2, 0x00 };
|
|
/* the following is equivalent to "kamelåså ☺☺☺ öäüÿéèóò" in utf8 */
|
|
static const char utf8[] = { 0x6b, 0x61, 0x6d, 0x65, 0x6c, 0xc3, 0xa5,
|
|
0x73, 0xc3, 0xa5, 0x20, 0xE2, 0x98, 0xBA,
|
|
0xE2, 0x98, 0xBA, 0xE2, 0x98, 0xBA, 0x20,
|
|
0xc3, 0xb6, 0xc3, 0xa4, 0xc3, 0xbc, 0xc3,
|
|
0xbf, 0xc3, 0xa9, 0xc3, 0xa8, 0xc3, 0xb3,
|
|
0xc3, 0xb2, 0x00 };
|
|
|
|
/* purely for convenience */
|
|
static const libndr_flags fl_ascii_null = LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM;
|
|
static const libndr_flags fl_ascii_noterm = LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_REMAINING;
|
|
static const libndr_flags fl_utf8_null = LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM;
|
|
static const libndr_flags fl_raw8_null = LIBNDR_FLAG_STR_RAW8|LIBNDR_FLAG_STR_NULLTERM;
|
|
|
|
static bool
|
|
test_ndr_push_string (struct torture_context *tctx, const char *string,
|
|
libndr_flags flags, enum ndr_err_code exp_ndr_err,
|
|
bool strcmp_pass)
|
|
{
|
|
TALLOC_CTX *mem_ctx;
|
|
struct ndr_push *ndr;
|
|
enum ndr_err_code err;
|
|
|
|
torture_comment(tctx,
|
|
"test_ndr_push_string %s flags 0x%"PRI_LIBNDR_FLAGS" expecting "
|
|
"err 0x%x and strcmp %s\n", string, flags, exp_ndr_err,
|
|
strcmp_pass?"pass":"fail");
|
|
if (exp_ndr_err != NDR_ERR_SUCCESS) {
|
|
torture_comment(tctx, "(ignore any Conversion error) ");
|
|
}
|
|
|
|
mem_ctx = talloc_named (NULL, 0, "test_ndr_push_string");
|
|
ndr = ndr_push_init_ctx(mem_ctx);
|
|
ndr_set_flags (&ndr->flags, flags);
|
|
|
|
err = ndr_push_string (ndr, NDR_SCALARS, string);
|
|
torture_assert_ndr_err_equal(tctx, err, exp_ndr_err,
|
|
"ndr_push_string: unexpected return code");
|
|
|
|
if (exp_ndr_err == NDR_ERR_SUCCESS) {
|
|
uint32_t expected_offset = strlen(string);
|
|
|
|
if (flags & LIBNDR_FLAG_STR_NULLTERM) {
|
|
expected_offset += 1;
|
|
}
|
|
|
|
torture_assert_int_equal(tctx,
|
|
ndr->offset, expected_offset,
|
|
"ndr_push_string: invalid length");
|
|
|
|
torture_assert(tctx, ndr->data != NULL,
|
|
"ndr_push_string: succeeded but NULL data");
|
|
|
|
torture_assert(tctx,
|
|
strcmp_pass == !strcmp(string, (char *)ndr->data),
|
|
"ndr_push_string: post-push strcmp");
|
|
|
|
}
|
|
|
|
talloc_free(mem_ctx);
|
|
return true;
|
|
}
|
|
|
|
static bool
|
|
test_ndr_pull_string (struct torture_context *tctx, const char *string,
|
|
libndr_flags flags, enum ndr_err_code exp_ndr_err,
|
|
bool strcmp_pass)
|
|
{
|
|
TALLOC_CTX *mem_ctx;
|
|
DATA_BLOB blob;
|
|
struct ndr_pull *ndr;
|
|
enum ndr_err_code err;
|
|
const char *result = NULL;
|
|
|
|
torture_comment(tctx,
|
|
"test_ndr_pull_string '%s' flags 0x%"PRI_LIBNDR_FLAGS" expecting "
|
|
"err 0x%x and strcmp %s\n", string, flags, exp_ndr_err,
|
|
strcmp_pass?"pass":"fail");
|
|
if (exp_ndr_err != NDR_ERR_SUCCESS) {
|
|
torture_comment(tctx, "(ignore any Conversion error) ");
|
|
}
|
|
|
|
mem_ctx = talloc_named (NULL, 0, "test_ndr_pull_string");
|
|
|
|
blob = data_blob_string_const(string);
|
|
ndr = ndr_pull_init_blob(&blob, mem_ctx);
|
|
torture_assert(mem_ctx, ndr, "ndr init failed");
|
|
ndr_set_flags (&ndr->flags, flags);
|
|
|
|
err = ndr_pull_string (ndr, NDR_SCALARS, &result);
|
|
torture_assert_ndr_err_equal(tctx, err, exp_ndr_err,
|
|
"ndr_pull_string: unexpected return code");
|
|
|
|
if (exp_ndr_err == NDR_ERR_SUCCESS) {
|
|
torture_assert(tctx, result != NULL,
|
|
"ndr_pull_string: NULL data");
|
|
torture_assert(tctx, strcmp_pass == !strcmp(string, result),
|
|
"ndr_pull_string: post-pull strcmp");
|
|
torture_assert(tctx, result != NULL,
|
|
"ndr_pull_string succeeded but result NULL");
|
|
}
|
|
|
|
talloc_free(mem_ctx);
|
|
return true;
|
|
}
|
|
|
|
static bool
|
|
torture_ndr_string(struct torture_context *torture)
|
|
{
|
|
const char *saved_dos_cp = talloc_strdup(torture, lpcfg_dos_charset(torture->lp_ctx));
|
|
|
|
torture_assert(torture,
|
|
test_ndr_push_string (torture, ascii, fl_ascii_null,
|
|
NDR_ERR_SUCCESS, true),
|
|
"test_ndr_push_string(ASCII, STR_ASCII|STR_NULL)");
|
|
torture_assert(torture,
|
|
test_ndr_push_string (torture, ascii, fl_ascii_noterm,
|
|
NDR_ERR_SUCCESS, true),
|
|
"test_ndr_push_string(ASCII, STR_ASCII|STR_NOTERM|REMAINING)");
|
|
torture_assert(torture,
|
|
test_ndr_push_string (torture, "", fl_ascii_null,
|
|
NDR_ERR_SUCCESS, true),
|
|
"test_ndr_push_string('', STR_ASCII|STR_NULL)");
|
|
torture_assert(torture,
|
|
test_ndr_push_string (torture, "", fl_ascii_noterm,
|
|
NDR_ERR_SUCCESS, true),
|
|
"test_ndr_push_string('', STR_ASCII|STR_NOTERM|REMAINING)");
|
|
torture_assert(torture,
|
|
test_ndr_push_string (torture, utf8, fl_utf8_null,
|
|
NDR_ERR_SUCCESS, true),
|
|
"test_ndr_push_string(UTF8, STR_UTF8|STR_NULL)");
|
|
torture_assert(torture,
|
|
test_ndr_push_string (torture, utf8, fl_raw8_null,
|
|
NDR_ERR_SUCCESS, true),
|
|
"test_ndr_push_string(UTF8, STR_RAW8|STR_NULL)");
|
|
torture_assert(torture,
|
|
test_ndr_push_string (torture, latin1, fl_raw8_null,
|
|
NDR_ERR_SUCCESS, true),
|
|
"test_ndr_push_string(LATIN1, STR_RAW8|STR_NULL)");
|
|
torture_assert(torture,
|
|
test_ndr_push_string (torture, utf8, fl_ascii_null,
|
|
NDR_ERR_CHARCNV, false),
|
|
"test_ndr_push_string(UTF8, STR_ASCII|STR_NULL)");
|
|
torture_assert(torture,
|
|
test_ndr_push_string (torture, latin1, fl_ascii_null,
|
|
NDR_ERR_CHARCNV, false),
|
|
"test_ndr_push_string(LATIN1, STR_ASCII|STR_NULL)");
|
|
|
|
|
|
torture_assert(torture,
|
|
test_ndr_pull_string (torture, ascii, fl_ascii_null,
|
|
NDR_ERR_SUCCESS, true),
|
|
"test_ndr_pull_string(ASCII, STR_ASCII|STR_NULL)");
|
|
torture_assert(torture,
|
|
test_ndr_pull_string (torture, utf8, fl_utf8_null,
|
|
NDR_ERR_SUCCESS, true),
|
|
"test_ndr_pull_string(UTF8, STR_UTF8|STR_NULL)");
|
|
torture_assert(torture,
|
|
test_ndr_pull_string (torture, utf8, fl_raw8_null,
|
|
NDR_ERR_SUCCESS, true),
|
|
"test_ndr_pull_string(UTF8, STR_RAW8|STR_NULL)");
|
|
torture_assert(torture,
|
|
test_ndr_pull_string (torture, latin1, fl_raw8_null,
|
|
NDR_ERR_SUCCESS, true),
|
|
"test_ndr_pull_string(LATIN1, STR_RAW8|STR_NULL)");
|
|
|
|
/* Depending on runtime config, the behavior of ndr_pull_string on
|
|
* incorrect combinations of strings and flags (latin1 with ASCII
|
|
* flags, for example) may differ; it may return NDR_ERR_CHARCNV, or
|
|
* it may return NDR_ERR_SUCCESS but with a string that has been
|
|
* mutilated, depending on the value of "dos charset". We test for
|
|
* both cases here. */
|
|
|
|
lpcfg_do_global_parameter(torture->lp_ctx, "dos charset", "ASCII");
|
|
reload_charcnv(torture->lp_ctx);
|
|
|
|
torture_assert(torture,
|
|
test_ndr_pull_string (torture, latin1, fl_ascii_null,
|
|
NDR_ERR_CHARCNV, false),
|
|
"test_ndr_pull_string(LATIN1, STR_ASCII|STR_NULL)");
|
|
torture_assert(torture,
|
|
test_ndr_pull_string (torture, utf8, fl_ascii_null,
|
|
NDR_ERR_CHARCNV, false),
|
|
"test_ndr_pull_string(UTF8, STR_ASCII|STR_NULL)");
|
|
|
|
lpcfg_do_global_parameter(torture->lp_ctx, "dos charset", "CP850");
|
|
reload_charcnv(torture->lp_ctx);
|
|
|
|
torture_assert(torture,
|
|
test_ndr_pull_string (torture, latin1, fl_ascii_null,
|
|
NDR_ERR_SUCCESS, false),
|
|
"test_ndr_pull_string(LATIN1, STR_ASCII|STR_NULL)");
|
|
torture_assert(torture,
|
|
test_ndr_pull_string (torture, utf8, fl_ascii_null,
|
|
NDR_ERR_SUCCESS, false),
|
|
"test_ndr_pull_string(UTF8, STR_ASCII|STR_NULL)");
|
|
|
|
lpcfg_do_global_parameter(torture->lp_ctx, "dos charset", saved_dos_cp);
|
|
reload_charcnv(torture->lp_ctx);
|
|
|
|
return true;
|
|
}
|
|
|
|
struct torture_suite *ndr_string_suite(TALLOC_CTX *ctx)
|
|
{
|
|
struct torture_suite *suite = torture_suite_create(ctx, "ndr_string");
|
|
|
|
torture_suite_add_simple_test(suite, "ndr_string", torture_ndr_string);
|
|
suite->description = talloc_strdup(suite, "NDR - string-conversion focused push/pull tests");
|
|
|
|
return suite;
|
|
}
|