ndr_print_time_t: void (struct ndr_print *, const char *, time_t)
ndr_print_timespec: void (struct ndr_print *, const char *, const struct timespec *)
ndr_print_timeval: void (struct ndr_print *, const char *, const struct timeval *)
+ndr_print_u16string: void (struct ndr_print *, const char *, const uint16_t *)
ndr_print_udlong: void (struct ndr_print *, const char *, uint64_t)
ndr_print_udlongr: void (struct ndr_print *, const char *, uint64_t)
ndr_print_uid_t: void (struct ndr_print *, const char *, uid_t)
ndr_pull_timespec: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, struct timespec *)
ndr_pull_timeval: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, struct timeval *)
ndr_pull_trailer_align: enum ndr_err_code (struct ndr_pull *, size_t)
+ndr_pull_u16string: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, const uint16_t **)
ndr_pull_udlong: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, uint64_t *)
ndr_pull_udlongr: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, uint64_t *)
ndr_pull_uid_t: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, uid_t *)
ndr_push_timespec: enum ndr_err_code (struct ndr_push *, ndr_flags_type, const struct timespec *)
ndr_push_timeval: enum ndr_err_code (struct ndr_push *, ndr_flags_type, const struct timeval *)
ndr_push_trailer_align: enum ndr_err_code (struct ndr_push *, size_t)
+ndr_push_u16string: enum ndr_err_code (struct ndr_push *, ndr_flags_type, const uint16_t *)
ndr_push_udlong: enum ndr_err_code (struct ndr_push *, ndr_flags_type, uint64_t)
ndr_push_udlongr: enum ndr_err_code (struct ndr_push *, ndr_flags_type, uint64_t)
ndr_push_uid_t: enum ndr_err_code (struct ndr_push *, ndr_flags_type, uid_t)
NDR_SCALAR_PROTO(ipv4address, const char *)
NDR_SCALAR_PROTO(ipv6address, const char *)
NDR_SCALAR_PROTO(string, const char *)
+NDR_SCALAR_PROTO(u16string, const uint16_t *)
NDR_SCALAR_PROTO(double, double)
enum ndr_err_code ndr_pull_policy_handle(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct policy_handle *r);
return ret+strlen(*string)+1;
}
+/**
+ pull a UTF‐16 string from the wire
+*/
+_PUBLIC_ enum ndr_err_code ndr_pull_u16string(struct ndr_pull *ndr,
+ ndr_flags_type ndr_flags,
+ const uint16_t **s)
+{
+ uint16_t *as = NULL;
+ const char *const src_str = (char *)ndr->data + ndr->offset;
+ size_t src_len = 0;
+
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return NDR_ERR_SUCCESS;
+ }
+
+ if (ndr->flags & LIBNDR_ENCODING_FLAGS) {
+ return ndr_pull_error(
+ ndr,
+ NDR_ERR_STRING,
+ "Unsupported string flags 0x%" PRI_LIBNDR_FLAGS
+ "passed to ndr_pull_u16string()\n",
+ ndr->flags & LIBNDR_STRING_FLAGS);
+ }
+
+ switch (ndr->flags & LIBNDR_STRING_FLAGS) {
+ case LIBNDR_FLAG_STR_NULLTERM:
+ /*
+ * We ensure that src_len cannot equal 0 by
+ * requiring that there be enough bytes for at least
+ * the NULL terminator
+ */
+ NDR_PULL_NEED_BYTES(ndr, 2);
+ src_len = utf16_null_terminated_len_n(src_str,
+ ndr->data_size -
+ ndr->offset);
+ break;
+
+ default:
+ return ndr_pull_error(
+ ndr,
+ NDR_ERR_STRING,
+ "Unsupported string flags 0x%" PRI_LIBNDR_FLAGS
+ "passed to ndr_pull_u16string()\n",
+ ndr->flags & LIBNDR_STRING_FLAGS);
+ }
+
+ NDR_PULL_NEED_BYTES(ndr, src_len);
+ as = talloc_utf16_strlendup(ndr->current_mem_ctx,
+ src_str,
+ src_len);
+ if (as == NULL) {
+ return ndr_pull_error(ndr,
+ NDR_ERR_ALLOC,
+ "Failed to talloc_utf16_strlendup() in "
+ "ndr_pull_u16string()");
+ }
+
+ NDR_CHECK(ndr_pull_advance(ndr, src_len));
+ *s = as;
+
+ return NDR_ERR_SUCCESS;
+}
+
+/**
+ push a UTF‐16 string onto the wire
+*/
+_PUBLIC_ enum ndr_err_code ndr_push_u16string(struct ndr_push *ndr,
+ ndr_flags_type ndr_flags,
+ const uint16_t *s)
+{
+ size_t s_len;
+
+ if (!(ndr_flags & NDR_SCALARS)) {
+ return NDR_ERR_SUCCESS;
+ }
+
+ if (s == NULL) {
+ return ndr_push_error(
+ ndr,
+ NDR_ERR_INVALID_POINTER,
+ "NULL pointer passed to ndr_push_u16string()");
+ }
+
+ s_len = utf16_null_terminated_len(s);
+ if (s_len > UINT32_MAX) {
+ return ndr_push_error(
+ ndr,
+ NDR_ERR_LENGTH,
+ "length overflow in ndr_push_u16string()");
+ }
+
+ if (ndr->flags & LIBNDR_ENCODING_FLAGS) {
+ return ndr_push_error(
+ ndr,
+ NDR_ERR_STRING,
+ "Unsupported string flags 0x%" PRI_LIBNDR_FLAGS
+ "passed to ndr_push_u16string()\n",
+ ndr->flags & LIBNDR_STRING_FLAGS);
+ }
+
+ switch (ndr->flags & LIBNDR_STRING_FLAGS) {
+ case LIBNDR_FLAG_STR_NULLTERM:
+ NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)s, s_len));
+ break;
+
+ default:
+ if (ndr->flags & LIBNDR_FLAG_REMAINING) {
+ NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)s, s_len));
+ break;
+ }
+
+ return ndr_push_error(
+ ndr,
+ NDR_ERR_STRING,
+ "Unsupported string flags 0x%" PRI_LIBNDR_FLAGS
+ "passed to ndr_push_u16string()\n",
+ ndr->flags & LIBNDR_STRING_FLAGS);
+ }
+
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_u16string(struct ndr_print *ndr,
+ const char *name,
+ const uint16_t *s)
+{
+ return ndr_print_array_uint8(ndr,
+ name,
+ (const uint8_t *)s,
+ utf16_len(s));
+}
+
static uint32_t guess_string_array_size(struct ndr_pull *ndr, ndr_flags_type ndr_flags)
{
/*
'udlongr' => 4,
'DATA_BLOB' => 4,
'string' => 4,
+ 'u16string' => 4,
'string_array' => 4, #???
'time_t' => 4,
'uid_t' => 8,
$self->pidl("}");
}
+sub ConvertU16StringFromPythonData($$$$$)
+{
+ my ($self, $mem_ctx, $py_var, $target, $fail) = @_;
+
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("uint16_t *str = NULL;");
+ $self->pidl("");
+ $self->pidl("str = PyUtf16String_FromBytes(");
+ $self->pidl(" $mem_ctx, $py_var);");
+ $self->pidl("if (str == NULL) {");
+ $self->indent;
+ $self->pidl("$fail");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+ $self->pidl("$target = str;");
+ $self->deindent;
+ $self->pidl("}");
+}
+
sub ConvertObjectFromPythonData($$$$$$;$$)
{
my ($self, $mem_ctx, $cvar, $ctype, $target, $fail, $location, $switch) = @_;
return;
}
+ if ($actual_ctype->{TYPE} eq "SCALAR" and
+ $actual_ctype->{NAME} eq "u16string") {
+ $self->ConvertU16StringFromPythonData($mem_ctx, $cvar, $target, $fail);
+ return;
+ }
+
if ($actual_ctype->{TYPE} eq "SCALAR" and $actual_ctype->{NAME} eq "NTSTATUS") {
$self->pidl("$target = NT_STATUS(PyLong_AsLong($cvar));");
return;
return "PyString_FromStringOrNULL($cvar)";
}
+ if ($ctypename eq "u16string") {
+ return "PyBytes_FromUtf16StringOrNULL($cvar)";
+ }
+
# Not yet supported
if ($ctypename eq "string_array") {
return "pytalloc_GenericObject_reference_ex($mem_ctx, $cvar)";
my @reference_scalars = (
"string", "string_array", "nbt_string", "dns_string",
"wrepl_nbt_name", "dnsp_name", "dnsp_string",
- "ipv4address", "ipv6address"
+ "ipv4address", "ipv6address", "u16string"
);
my @non_fixed_size_scalars = (
"string", "string_array", "nbt_string", "dns_string",
- "wrepl_nbt_name", "dnsp_name", "dnsp_string"
+ "wrepl_nbt_name", "dnsp_name", "dnsp_string",
+ "u16string"
);
# a list of known scalar types
"pointer" => "void*",
"DATA_BLOB" => "DATA_BLOB",
"string" => "const char *",
+ "u16string" => "const uint16_t *",
"string_array" => "const char **",
"time_t" => "time_t",
"uid_t" => "uid_t",
{
my ($t) = @_;
- return ($t eq "string");
+ return ($t eq "string" or $t eq "u16string");
}
sub RegisterScalars()
use strict;
use warnings;
-use Test::More tests => 57;
+use Test::More tests => 58;
use FindBin qw($RealBin);
use lib "$RealBin";
use Util;
is(1, is_scalar("mytypedef"));
is(1, scalar_is_reference("string"));
+is(1, scalar_is_reference("u16string"));
is(0, scalar_is_reference("uint32"));
is(0, scalar_is_reference({TYPE => "STRUCT", NAME => "echo_foobar"}));