[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Wed Dec 4 06:36:03 UTC 2019


The branch, master has been updated
       via  eddd6c52678 pidl: don't export parser class methods
       via  8429418a88e pidl s4/TDR: use Parse::Pidl::Base
       via  12f6698f76e pidl s4/TDR: use conventional ->{res} name
       via  fd68ba8a10a pidl: s4/NDR/Parser uses Pidl::Base
       via  574c8db54cf pidl s4/NDR/Client: use Pidl::Base
       via  3fc222a1225 pidl s4/NDR/Client: fix pidl_both()
       via  803d9cf8dd7 pidl s4::Python uses Pidl::Base
       via  5513558bb42 pidl:: adjust s4::Python pidl_hdr() to be the same as others
       via  4f0fba18867 pidl Samba3::ClientNDR uses Pidl::Base
       via  a78f69cb7d3 pidl: optionally annotate output for debug purposes
       via  0cb2e6ac4c7 pidl: add a base class for PIDL parsers
       via  12cccf34473 pygpo: use correct method flags
       via  d15a3797c79 librpc: Avoid spinning on string_array elements with a short input
       via  bf8063e369a librpc ndr: Tests for ndr_pull_string
       via  7127a615cbd librpc ndr: Infinite loop parsing Suplemental creds
      from  787adfbcc93 s4:heimdal_build: move krb5-types.h into include/krb5-types.h

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit eddd6c52678b28131d5dba67e6a8eaf4e5696a92
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sun Dec 1 22:41:06 2019 +1300

    pidl: don't export parser class methods
    
    These methods are not used or usable as exported functions. The
    correct (and actual) usage is along these lines;
    
        require Parse::Pidl::Samba3::ClientNDR;
        my $generator = new Parse::Pidl::Samba3::ClientNDR();
        my ($c_code,$h_code) = $generator->Parse($ndr, $header, $c_header);
    
    where the methods are either explicitly referenced (new A::B::C),
    or are called from the blessed object, neither of which need
    exporting.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Wed Dec  4 06:35:06 UTC 2019 on sn-devel-184

commit 8429418a88e803592f57e1997bfbe0f639f422c0
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sat Nov 30 16:59:31 2019 +1300

    pidl s4/TDR: use Parse::Pidl::Base
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 12f6698f76e29854d5097a266fb4e1658d88ae96
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sun Dec 1 17:43:20 2019 +1300

    pidl s4/TDR: use conventional ->{res} name
    
    rather than ->{ret}, meaning this class can be moved to a Pidl::Base subclass
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit fd68ba8a10adf7439f842a787943b1ec4580d837
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sat Nov 30 16:55:15 2019 +1300

    pidl: s4/NDR/Parser uses Pidl::Base
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 574c8db54cf1ba06516a5036269bffd81e20d602
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sat Nov 30 16:49:06 2019 +1300

    pidl s4/NDR/Client: use Pidl::Base
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 3fc222a1225658706444fd8118f9477b6a4baba4
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sat Nov 30 16:37:43 2019 +1300

    pidl s4/NDR/Client: fix pidl_both()
    
    This function was clearly meant to be adding output to both the .c and
    .h files, but was only adding it to the .h due to a typo.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 803d9cf8dd7d1767a7d9ac6e846450eb99ba8d5e
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sat Nov 30 16:31:27 2019 +1300

    pidl s4::Python uses Pidl::Base
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 5513558bb422132632da08574d02f3a568622138
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sat Nov 30 16:30:48 2019 +1300

    pidl:: adjust s4::Python pidl_hdr() to be the same as others
    
    The common case is for pidl_hdr() to add a "\n", which we can
    easily do here, allowing this to be merged into the Pidl::Base borg.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 4f0fba18867faa0578d63c26054d04afd7f8b019
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sat Nov 30 16:25:54 2019 +1300

    pidl Samba3::ClientNDR uses Pidl::Base
    
    We need to modify the '@ISA = ' line, because it overwrites
    the inheritance from Pidl::Base.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit a78f69cb7d374adae470ac5e3dd9f3ac8175292e
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sat Nov 30 16:22:22 2019 +1300

    pidl: optionally annotate output for debug purposes
    
    It can sometimes be hard to tell which bit of pidl generated which bit
    of C. This commit wants to help.
    
    If the PIDL_DEVELOPER environment variable is set (via waf
    --pidl-developer or some other means), pidl will annotate *most* C
    indicating which lines were generated by which bits of pidl. It looks
    something like this:
    
    _PUBLIC_ enum ndr_err_code ndr_push_auth_session_info(struct ndr_push *ndr, int ndr_flags, const struct auth_session_info *r)
    {  //:PIDL: Parse::Pidl::Samba4::NDR::Parser::ParseTypePushFunction  lib/Parse/Pidl/Samba4/NDR/Parser.pm:3079
    	NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);  //:PIDL: Parse::Pidl::Samba4::NDR::Parser::ParseStructPush  lib/Parse/Pidl/Samba4/NDR/Parser.pm:604
    	if (ndr_flags & NDR_SCALARS) {
    		NDR_CHECK(ndr_push_align(ndr, 5));  //:PIDL: Parse::Pidl::Samba4::NDR::Parser::ParseStructPushPrimitives  lib/Parse/Pidl/Samba4/NDR/Parser.pm:1448
    		NDR_CHECK(ndr_push_unique_ptr(ndr, r->security_token));  //:PIDL: Parse::Pidl::Samba4::NDR::Parser::ParsePtrPush  lib/Parse/Pidl/Samba4/NDR/Parser.pm:604
    		NDR_CHECK(ndr_push_unique_ptr(ndr, r->unix_token));
    		NDR_CHECK(ndr_push_unique_ptr(ndr, r->info));
    		NDR_CHECK(ndr_push_unique_ptr(ndr, r->unix_info));
    		NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, 0));
    		/* [ignore] 'torture' */  //:PIDL: Parse::Pidl::Samba4::NDR::Parser::ParseElementPushLevel  lib/Parse/Pidl/Samba4/NDR/Parser.pm:729
    		NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->session_key));  //:PIDL: Parse::Pidl::Samba4::NDR::Parser::ParseDataPush  lib/Parse/Pidl/Samba4/NDR/Parser.pm:604
    		NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, 0));  //:PIDL: Parse::Pidl::Samba4::NDR::Parser::ParsePtrPush  lib/Parse/Pidl/Samba4/NDR/Parser.pm:604
    		/* [ignore] 'credentials' */  //:PIDL: Parse::Pidl::Samba4::NDR::Parser::ParseElementPushLevel  lib/Parse/Pidl/Samba4/NDR/Parser.pm:729
    
    The comments starting with '//:PIDL:' have the function name, the filename,
    and line number. The comment follows the ordinary output, and uses the '//'
    style so as not to interfere with multiline /* */ comments if they happen
    to exist.
    
    A '//:PIDL:' comment is added whenever the pidl function or indentation
    level changes, and very occasionally at other places if pidl runs for a
    while without either of these things happening.
    
    This does not affect pidl parsers that do not inherit from Parse::Pidl::Base,
    and is careful to have no performance impact on non-debug generation.
    
    This may help with semi-automated flow analysis.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 0cb2e6ac4c730e504cf40ec328e90874a2267d7e
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Sat Nov 30 15:22:16 2019 +1300

    pidl: add a base class for PIDL parsers
    
    There are about 5 object-oriented parsers, all with their own
    effectively identical but differently spelt versions of pidl(),
    pidl_hdr(), indent(), and deindent(). With this commit we add a base
    class that they can all use.
    
    The ultimate aim is to be able to add some debugging instrumentation
    that benefits all[1] the parsers.
    
    [1] The parsers (e.g. Samba::ServerNDR) which use global scope rather
    than objects will not be affected.
    
    The versions of the functions in this file follow the most
    sophisticated versions of the soon-to-be subclasses. For example, the
    pidl() function avoids spurious whitespace and puts #define at column
    0, following the Python parser.
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 12cccf3447333dfd4f5e437cd57ca5ec68724fdd
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Tue Dec 3 11:17:26 2019 +1300

    pygpo: use correct method flags
    
    The METH_KEYWORDS argument must always be combined with METH_VARARGS.
    
    In Python up to 3.7 this was checked at runtime, and as we had no callers to
    get_unix_path() in Python we never noticed. In Python 3.8 it is checked at
    import time, and everyone notices even if they aren't directly using GPOs.
    
    Found and reported by Val Kulkov.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14209
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit d15a3797c7949140c872e82cc42d4f7301a9bf82
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Nov 7 14:19:24 2019 +1300

    librpc: Avoid spinning on string_array elements with a short input
    
    Without this protection we will spin during decode of a string_array or nstring_array
    that is terminated by only a single NUL byte, not two as required by UTF-16.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13874
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit bf8063e369a227eecc902f90277fc59d9d0ad167
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Mon Dec 2 15:54:08 2019 +1300

    librpc ndr: Tests for ndr_pull_string
    
    Tests to ensure that ndr_pull_string handles zero and one byte length
    data correctly for both character strings and UTF-16 strings.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13874
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

commit 7127a615cbd742695cea5865533c1ee7098ecc10
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Wed Dec 4 08:46:57 2019 +1300

    librpc ndr: Infinite loop parsing Suplemental creds
    
    Fuzzing by Michael Hanselmann found an infinite loop parsing a malformed
    supplemental credentials structure.  There are no server-side
    network-accessible calls using this code.
    
    This patch adds an ndrdump blackbox test to replicate the issue.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13874
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 buildtools/wafsamba/samba_autoconf.py    |   3 +
 buildtools/wafsamba/samba_pidl.py        |   6 +-
 buildtools/wafsamba/wscript              |   3 +
 libgpo/pygpo.c                           |   2 +-
 librpc/ndr/ndr_string.c                  |   7 ++
 librpc/tests/test_ndr_string.c           | 140 +++++++++++++++++++++++++++++++
 librpc/wscript_build                     |  11 +++
 pidl/lib/Parse/Pidl/Base.pm              |  99 ++++++++++++++++++++++
 pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm  |  10 +--
 pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm |  12 +--
 pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm |  29 +------
 pidl/lib/Parse/Pidl/Samba4/Python.pm     |  50 ++---------
 pidl/lib/Parse/Pidl/Samba4/TDR.pm        |  12 +--
 pidl/tests/samba3-cli.pl                 |   2 +-
 pidl/tests/tdr.pl                        |  12 +--
 python/samba/tests/blackbox/ndrdump.py   |  13 +++
 source4/selftest/tests.py                |   2 +
 17 files changed, 309 insertions(+), 104 deletions(-)
 create mode 100644 librpc/tests/test_ndr_string.c
 create mode 100644 pidl/lib/Parse/Pidl/Base.pm


Changeset truncated at 500 lines:

diff --git a/buildtools/wafsamba/samba_autoconf.py b/buildtools/wafsamba/samba_autoconf.py
index 1ccee54bb63..4615e201422 100644
--- a/buildtools/wafsamba/samba_autoconf.py
+++ b/buildtools/wafsamba/samba_autoconf.py
@@ -725,6 +725,9 @@ def SAMBA_CONFIG_H(conf, path=None):
     if Options.options.debug:
         conf.ADD_CFLAGS('-g', testflags=True)
 
+    if Options.options.pidl_developer:
+        conf.env.PIDL_DEVELOPER_MODE = True
+
     if Options.options.developer:
         conf.env.DEVELOPER_MODE = True
 
diff --git a/buildtools/wafsamba/samba_pidl.py b/buildtools/wafsamba/samba_pidl.py
index 3fecfa90eb9..a34c871d183 100644
--- a/buildtools/wafsamba/samba_pidl.py
+++ b/buildtools/wafsamba/samba_pidl.py
@@ -69,6 +69,10 @@ def SAMBA_PIDL(bld, pname, source,
     if cpp == "CPP=xlc_r":
         cpp = ""
 
+    if bld.env['PIDL_DEVELOPER_MODE']:
+        pidl_dev = 'PIDL_DEVELOPER=1 '
+    else:
+        pidl_dev = ''
 
     if bld.CONFIG_SET("CC"):
         if isinstance(bld.CONFIG_GET("CC"), list):
@@ -76,7 +80,7 @@ def SAMBA_PIDL(bld, pname, source,
         else:
             cc = 'CC="%s"' % bld.CONFIG_GET("CC")
 
-    t = bld(rule='cd ${PIDL_LAUNCH_DIR} && %s %s ${PERL} ${PIDL} --quiet ${OPTIONS} --outputdir ${OUTPUTDIR} -- "${IDLSRC}"' % (cpp, cc),
+    t = bld(rule='cd ${PIDL_LAUNCH_DIR} && %s%s %s ${PERL} ${PIDL} --quiet ${OPTIONS} --outputdir ${OUTPUTDIR} -- "${IDLSRC}"' % (pidl_dev, cpp, cc),
             ext_out    = '.c',
             before     = 'c',
             update_outputs = True,
diff --git a/buildtools/wafsamba/wscript b/buildtools/wafsamba/wscript
index 9987c6e4fcc..b9f2f495617 100644
--- a/buildtools/wafsamba/wscript
+++ b/buildtools/wafsamba/wscript
@@ -102,6 +102,9 @@ def options(opt):
     gr.add_option('--enable-developer',
                    help=("Turn on developer warnings and debugging"),
                    action="store_true", dest='developer', default=False)
+    gr.add_option('--pidl-developer',
+                   help=("annotate PIDL-generated code for developers"),
+                   action="store_true", dest='pidl_developer', default=False)
     gr.add_option('--disable-warnings-as-errors',
                    help=("Do not treat all warnings as errors (disable -Werror)"),
                    action="store_true", dest='disable_warnings_as_errors', default=False)
diff --git a/libgpo/pygpo.c b/libgpo/pygpo.c
index 581d20e0649..97bbb3ec528 100644
--- a/libgpo/pygpo.c
+++ b/libgpo/pygpo.c
@@ -118,7 +118,7 @@ out:
 static PyMethodDef GPO_methods[] = {
 	{"get_unix_path", PY_DISCARD_FUNC_SIG(PyCFunction,
 					      py_gpo_get_unix_path),
-		METH_KEYWORDS,
+		METH_VARARGS | METH_KEYWORDS,
 		NULL },
 	{NULL}
 };
diff --git a/librpc/ndr/ndr_string.c b/librpc/ndr/ndr_string.c
index 0fefc887c30..eb0af57a6ab 100644
--- a/librpc/ndr/ndr_string.c
+++ b/librpc/ndr/ndr_string.c
@@ -118,9 +118,16 @@ _PUBLIC_ enum ndr_err_code ndr_pull_string(struct ndr_pull *ndr, int ndr_flags,
 		break;
 
 	case LIBNDR_FLAG_STR_NULLTERM:
+		/*
+		 * We ensure that conv_str_len cannot return 0 by
+		 * requring that there be enough bytes for at least
+		 * the NULL terminator
+		 */
 		if (byte_mul == 1) {
+			NDR_PULL_NEED_BYTES(ndr, 1);
 			conv_src_len = ascii_len_n((const char *)(ndr->data+ndr->offset), ndr->data_size - ndr->offset);
 		} else {
+			NDR_PULL_NEED_BYTES(ndr, 2);
 			conv_src_len = utf16_len_n(ndr->data+ndr->offset, ndr->data_size - ndr->offset);
 		}
 		byte_mul = 1; /* the length is now absolute */
diff --git a/librpc/tests/test_ndr_string.c b/librpc/tests/test_ndr_string.c
new file mode 100644
index 00000000000..6baa41bec31
--- /dev/null
+++ b/librpc/tests/test_ndr_string.c
@@ -0,0 +1,140 @@
+/*
+ * Tests for librpc ndr_string.c
+ *
+ * Copyright (C) Catalyst.NET Ltd 2019
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * from cmocka.c:
+ * These headers or their equivalents should be included prior to
+ * including
+ * this header file.
+ *
+ * #include <stdarg.h>
+ * #include <stddef.h>
+ * #include <setjmp.h>
+ *
+ * This allows test applications to use custom definitions of C standard
+ * library functions and types.
+ *
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "librpc/ndr/ndr_string.c"
+
+/*
+ * Try and pull a null terminated string from a zero length buffer
+ * Should fail for both 1 byte, and 2 byte character strings.
+ */
+static void test_pull_string_zero_len_nul_term(void **state)
+{
+	struct ndr_pull ndr = {0};
+	enum ndr_err_code err;
+	int flags = NDR_SCALARS;
+	uint8_t data[] = {0x0, 0x0};
+	const char *s = NULL;
+
+	ndr.flags = LIBNDR_FLAG_STR_UTF8 | LIBNDR_FLAG_STR_NULLTERM;
+	ndr.data = data;
+	ndr.data_size = 0;
+	err = ndr_pull_string(&ndr, flags, &s);
+	assert_int_equal(err, NDR_ERR_BUFSIZE);
+	assert_null(s);
+	assert_int_equal(0, ndr.offset);
+
+	ndr.flags = LIBNDR_FLAG_STR_NULLTERM;
+	ndr.offset = 0;
+	err = ndr_pull_string(&ndr, flags, &s);
+	assert_int_equal(err, NDR_ERR_BUFSIZE);
+	assert_null(s);
+	assert_int_equal(0, ndr.offset);
+
+}
+
+/*
+ * Try and pull a null terminated string from a 1 byte buffer
+ * Should succeed for 1 byte character and
+ *        fail    for 2 byte character strings.
+ */
+static void test_pull_string_len_1_nul_term(void **state)
+{
+	struct ndr_pull ndr = {0};
+	enum ndr_err_code err;
+	int flags = NDR_SCALARS;
+	const char *s = NULL;
+	uint8_t data[] = {0x0, 0x0};
+
+	ndr.flags = LIBNDR_FLAG_STR_UTF8 | LIBNDR_FLAG_STR_NULLTERM;
+	ndr.data = data;
+	ndr.data_size = 1;
+	err = ndr_pull_string(&ndr, flags, &s);
+	assert_int_equal(err, NDR_ERR_SUCCESS);
+	assert_non_null(s);
+	assert_int_equal(1, ndr.offset);
+
+	ndr.offset = 0;
+	ndr.flags = LIBNDR_FLAG_STR_NULLTERM;
+	err = ndr_pull_string(&ndr, flags, &s);
+	assert_int_equal(err, NDR_ERR_BUFSIZE);
+	assert_int_equal(0, ndr.offset);
+}
+
+/*
+ * Try and pull a null terminated string from a 2 byte buffer
+ * Should succeed for both 1 byte, and 2 byte character strings.
+ */
+static void test_pull_string_len_2_nul_term(void **state)
+{
+	struct ndr_pull ndr = {0};
+	enum ndr_err_code err;
+	int flags = NDR_SCALARS;
+	const char *s;
+	uint8_t data[] = {0x0, 0x0};
+
+	ndr.flags = LIBNDR_FLAG_STR_UTF8 | LIBNDR_FLAG_STR_NULLTERM;
+	ndr.data = data;
+	ndr.data_size = 2;
+	err = ndr_pull_string(&ndr, flags, &s);
+	assert_int_equal(err, NDR_ERR_SUCCESS);
+	assert_non_null(s);
+	assert_int_equal(1, ndr.offset);
+
+	ndr.offset = 0;
+	ndr.flags = LIBNDR_FLAG_STR_NULLTERM;
+	err = ndr_pull_string(&ndr, flags, &s);
+	assert_int_equal(err, NDR_ERR_SUCCESS);
+	assert_non_null(s);
+	assert_int_equal(2, ndr.offset);
+
+
+}
+
+int main(int argc, const char **argv)
+{
+	const struct CMUnitTest tests[] = {
+		cmocka_unit_test(test_pull_string_zero_len_nul_term),
+		cmocka_unit_test(test_pull_string_len_1_nul_term),
+		cmocka_unit_test(test_pull_string_len_2_nul_term)
+	};
+
+	cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+	return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/librpc/wscript_build b/librpc/wscript_build
index 2582a281139..88964ed2a9a 100644
--- a/librpc/wscript_build
+++ b/librpc/wscript_build
@@ -664,3 +664,14 @@ bld.SAMBA_SUBSYSTEM('NDR_FSRVP_STATE',
     source='gen_ndr/ndr_fsrvp_state.c',
     public_deps='ndr'
     )
+#
+# Cmocka tests
+#
+bld.SAMBA_BINARY('test_ndr_string',
+                 source='tests/test_ndr_string.c',
+                 deps='''
+                      cmocka
+                      talloc
+                      ndr
+                      ''',
+                 for_selftest=True)
diff --git a/pidl/lib/Parse/Pidl/Base.pm b/pidl/lib/Parse/Pidl/Base.pm
new file mode 100644
index 00000000000..056b7b37d48
--- /dev/null
+++ b/pidl/lib/Parse/Pidl/Base.pm
@@ -0,0 +1,99 @@
+# Superclass for IDL structure generators
+# GPL3
+
+package Parse::Pidl::Base;
+
+use strict;
+use warnings;
+
+use Parse::Pidl qw(fatal warning error);
+
+use vars qw($VERSION);
+$VERSION = '0.01';
+
+sub indent {
+	my $self = shift;
+	$self->{tabs} .= "\t";
+}
+
+sub deindent {
+	my $self = shift;
+	$self->{tabs} = substr($self->{tabs}, 1);
+}
+
+sub pidl {
+	my ($self, $txt) = @_;
+	if ($txt) {
+		if ($txt !~ /^#/) {
+			$self->{res} .= $self->{tabs};
+		}
+		$self->{res} .= $txt;
+	}
+	$self->{res} .= "\n";
+}
+
+
+sub pidl_hdr {
+	my ($self, $txt) = @_;
+	$self->{res_hdr} .= "$txt\n";
+}
+
+
+sub pidl_both {
+	my ($self, $txt) = @_;
+	$self->{res} .= "$txt\n";
+	$self->{res_hdr} .= "$txt\n";
+}
+
+
+# When the PIDL_DEVELOPER env flag is set, we overwrite $self->pidl()
+# and $self->pidl_hdr() to annotate the output with location
+# information.
+
+sub pidl_dev_msg {
+	my $self = shift;
+	my ($pkg, $file, $line, $sub) = caller(2);
+	# minimise the path
+	if ($file =~ m{/pidl/(lib/.+|pidl)$}) {
+		$file = $1;
+	}
+	my $state = $self->{dev_state} // ['uninitialised', 0, ''];
+	my ($ploc, $pline, $ptabs) = @$state;
+	my $loc = "$sub	 $file";
+
+	if ($loc ne $ploc or
+	    abs($line - $pline) > 20 or
+	    $self->{tabs} ne $ptabs) {
+		$self->{dev_state} = [$loc, $line, $self->{tabs}];
+		return "  //<PIDL> $loc:$line";
+	}
+	return '';
+}
+
+
+if ($ENV{PIDL_DEVELOPER}) {
+	undef &pidl;
+	undef &pidl_hdr;
+
+	*Parse::Pidl::Base::pidl = sub {
+		my ($self, $txt) = @_;
+
+		if ($txt) {
+			if ($txt !~ /^#/) {
+				$self->{res} .= $self->{tabs};
+			}
+			$self->{res} .= $txt;
+		}
+		$self->{res} .= $self->pidl_dev_msg;
+		$self->{res} .= "\n";
+	};
+
+	*Parse::Pidl::Base::pidl_hdr = sub {
+		my ($self, $txt) = @_;
+		$txt .= $self->pidl_dev_msg;
+		$self->{res_hdr} .= "$txt\n";
+	}
+}
+
+
+1;
diff --git a/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
index 6acf1c5af2c..c132b552f9a 100644
--- a/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
+++ b/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
@@ -6,10 +6,7 @@
 # released under the GNU GPL
 
 package Parse::Pidl::Samba3::ClientNDR;
-
-use Exporter;
- at ISA = qw(Exporter);
- at EXPORT_OK = qw(ParseFunction $res $res_hdr);
+use base Parse::Pidl::Base;
 
 use strict;
 use Parse::Pidl qw(fatal warning error);
@@ -19,13 +16,10 @@ use Parse::Pidl::Typelist qw(mapTypeName);
 use Parse::Pidl::Samba4 qw(DeclLong);
 use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
 
+
 use vars qw($VERSION);
 $VERSION = '0.01';
 
-sub indent($) { my ($self) = @_; $self->{tabs}.="\t"; }
-sub deindent($) { my ($self) = @_; $self->{tabs} = substr($self->{tabs}, 1); }
-sub pidl($$) { my ($self,$txt) = @_; $self->{res} .= $txt ? "$self->{tabs}$txt\n" : "\n"; }
-sub pidl_hdr($$) { my ($self, $txt) = @_; $self->{res_hdr} .= "$txt\n"; }
 sub fn_declare($$) { my ($self,$n) = @_; $self->pidl($n); $self->pidl_hdr("$n;"); }
 
 sub new($)
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
index 734e86dd183..ddd757c749b 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
@@ -5,10 +5,7 @@
 # released under the GNU GPL
 
 package Parse::Pidl::Samba4::NDR::Client;
-
-use Exporter;
- at ISA = qw(Exporter);
- at EXPORT_OK = qw(Parse);
+use parent Parse::Pidl::Base;
 
 use Parse::Pidl qw(fatal warning error);
 use Parse::Pidl::Util qw(has_property ParseExpr genpad);
@@ -17,18 +14,13 @@ use Parse::Pidl::Typelist qw(mapTypeName);
 use Parse::Pidl::Samba4 qw(choose_header is_intree DeclLong);
 use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
 
+
 use vars qw($VERSION);
 $VERSION = '0.01';
 
 use strict;
 
-sub indent($) { my ($self) = @_; $self->{tabs}.="\t"; }
-sub deindent($) { my ($self) = @_; $self->{tabs} = substr($self->{tabs}, 1); }
-sub pidl($$) { my ($self,$txt) = @_; $self->{res} .= $txt ? "$self->{tabs}$txt\n" : "\n"; }
-sub pidl_hdr($$) { my ($self, $txt) = @_; $self->{res_hdr} .= "$txt\n"; }
-sub pidl_both($$) { my ($self, $txt) = @_; $self->{hdr} .= "$txt\n"; $self->{res_hdr} .= "$txt\n"; }
 sub fn_declare($$) { my ($self,$n) = @_; $self->pidl($n); $self->pidl_hdr("$n;"); }
-
 sub new($)
 {
 	my ($class) = shift;
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index c1a2cc99cb7..3ae0db22f7a 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -6,9 +6,10 @@
 # released under the GNU GPL
 
 package Parse::Pidl::Samba4::NDR::Parser;
+use parent Parse::Pidl::Base;
 
 require Exporter;
- at ISA = qw(Exporter);
+push @ISA, qw(Exporter);
 @EXPORT_OK = qw(check_null_pointer NeededFunction NeededElement NeededType $res NeededInterface TypeFunctionName ParseElementPrint);
 
 use strict;
@@ -81,20 +82,6 @@ sub has_fast_array($$)
 }
 
 
-####################################
-# pidl() is our basic output routine
-sub pidl($$)
-{
-	my ($self, $d) = @_;
-	if ($d) {
-		$self->{res} .= $self->{tabs};
-		$self->{res} .= $d;
-	}
-	$self->{res} .="\n";
-}
-
-sub pidl_hdr($$) { my ($self, $d) = @_; $self->{res_hdr} .= "$d\n"; }
-
 ####################################
 # defer() is like pidl(), but adds to 
 # a deferred buffer which is then added to the 
@@ -123,18 +110,6 @@ sub add_deferred($)
 	$self->{defer_tabs} = "";
 }
 
-sub indent($)
-{
-	my ($self) = @_;
-	$self->{tabs} .= "\t";
-}
-
-sub deindent($)
-{
-	my ($self) = @_;
-	$self->{tabs} = substr($self->{tabs}, 0, -1);
-}
-
 #####################################################################
 # declare a function public or static, depending on its attributes
 sub fn_declare($$$$)
diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm
index 161521c6e3a..a50f0b54df6 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -4,9 +4,7 @@
 # released under the GNU GPL
 
 package Parse::Pidl::Samba4::Python;
-
-use Exporter;
- at ISA = qw(Exporter);
+use parent Parse::Pidl::Base;
 
 use strict;
 use Parse::Pidl qw(warning fatal error);
@@ -17,6 +15,7 @@ use Parse::Pidl::CUtil qw(get_value_of get_pointer_to);
 use Parse::Pidl::Samba4 qw(ArrayDynamicallyAllocated);
 use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
 
+
 use vars qw($VERSION);


-- 
Samba Shared Repository



More information about the samba-cvs mailing list