{"$schema": "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json",
 "version": "2.1.0",
 "runs": [{"tool": {"driver": {"name": "GNU C23",
                               "fullName": "GNU C23 (GCC) version 16.1.1 20260703 (Red Hat 16.1.1-4) (x86_64-redhat-linux)",
                               "version": "16.1.1 20260703 (Red Hat 16.1.1-4)",
                               "informationUri": "https://gcc.gnu.org/gcc-16/",
                               "rules": [{"id": "-Wdeprecated-declarations",
                                          "helpUri": "https://gcc.gnu.org/onlinedocs/gcc-16.1.0/gcc/Warning-Options.html#index-Wdeprecated-declarations"}]}},
           "invocations": [{"arguments": ["/usr/libexec/gcc/x86_64-redhat-linux/16/cc1",
                                          "-quiet",
                                          "-I",
                                          ".",
                                          "-I",
                                          "../..",
                                          "-I",
                                          ".",
                                          "-I",
                                          "../..",
                                          "-I",
                                          "lib/replace",
                                          "-I",
                                          "../../lib/replace",
                                          "-D",
                                          "_GNU_SOURCE=1",
                                          "-D",
                                          "_XOPEN_SOURCE_EXTENDED=1",
                                          "-D",
                                          "__STDC_WANT_LIB_EXT1__=1",
                                          "-D",
                                          "STATIC_talloc_testsuite_MODULES=NULL",
                                          "-D",
                                          "STATIC_talloc_testsuite_MODULES_PROTO=extern void __talloc_testsuite_dummy_module_proto(void)",
                                          "-D",
                                          "HAVE_PYEMBED=1",
                                          "-D",
                                          "HAVE_PYEXT=1",
                                          "-D",
                                          "HAVE_PYTHON_H=1",
                                          "../../testsuite.c",
                                          "-quiet",
                                          "-dumpbase",
                                          "testsuite.c",
                                          "-dumpbase-ext",
                                          ".c",
                                          "-m64",
                                          "-mtune=generic",
                                          "-march=x86-64",
                                          "-mtls-dialect=gnu2",
                                          "-O2",
                                          "-Wno-unknown-pragmas",
                                          "-flto=auto",
                                          "-ffat-lto-objects",
                                          "-fexceptions",
                                          "-fstack-protector-strong",
                                          "-fasynchronous-unwind-tables",
                                          "-fcf-protection=full",
                                          "-fno-omit-frame-pointer",
                                          "-fPIC",
                                          "-fstack-clash-protection",
                                          "-fanalyzer",
                                          "-fdiagnostics-path-format=separate-events",
                                          "-fno-diagnostics-show-caret",
                                          "-fno-lto",
                                          "-fanalyzer-assume-nothrow",
                                          "-fdiagnostics-text-art-charset=none",
                                          "-fdiagnostics-set-output=sarif:file=/builddir/gcc-results/6082-4lhp.sarif",
                                          "-o",
                                          "/tmp/ccuaQOPR.s"],
                            "workingDirectory": {"uri": "/builddir/build/BUILD/libtalloc-2.4.4-build/talloc-2.4.4/bin/default"},
                            "startTimeUtc": "2026-08-03T17:57:51Z",
                            "executionSuccessful": true,
                            "toolExecutionNotifications": [],
                            "endTimeUtc": "2026-08-03T17:57:53Z"}],
           "originalUriBaseIds": {"PWD": {"uri": "file:///builddir/build/BUILD/libtalloc-2.4.4-build/talloc-2.4.4/bin/default/"}},
           "artifacts": [{"location": {"uri": "../../testsuite.c",
                                       "uriBaseId": "PWD"},
                          "sourceLanguage": "c",
                          "contents": {"text": "/*\n   Unix SMB/CIFS implementation.\n\n   local testing of talloc routines.\n\n   Copyright (C) Andrew Tridgell 2004\n\n     ** NOTE! The following LGPL license applies to the talloc\n     ** library. This does NOT imply that all of Samba is released\n     ** under the LGPL\n\n   This library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 3 of the License, or (at your option) any later version.\n\n   This library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with this library; if not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include \"replace.h\"\n#include \"system/time.h\"\n#include <talloc.h>\n\n#ifdef HAVE_PTHREAD\n#include <pthread.h>\n#endif\n\n#include <unistd.h>\n#include <sys/wait.h>\n\n#ifdef NDEBUG\n#undef NDEBUG\n#endif\n\n#include <assert.h>\n\n#include \"talloc_testsuite.h\"\n\n#ifndef disable_optimization\n#if __has_attribute(optimize)\n#define disable_optimization __attribute__((optimize(\"O0\")))\n#else /* disable_optimization */\n#define disable_optimization\n#endif\n#endif /* disable_optimization */\n\nstatic struct timeval private_timeval_current(void)\n{\n\tstruct timeval tv;\n\tgettimeofday(&tv, NULL);\n\treturn tv;\n}\n\nstatic double private_timeval_elapsed(struct timeval *tv)\n{\n\tstruct timeval tv2 = private_timeval_current();\n\treturn (tv2.tv_sec - tv->tv_sec) +\n\t       (tv2.tv_usec - tv->tv_usec)*1.0e-6;\n}\n\n#define torture_assert(test, expr, str) if (!(expr)) { \\\n\tprintf(\"failure: %s [\\n%s: Expression %s failed: %s\\n]\\n\", \\\n\t\ttest, __location__, #expr, str); \\\n\treturn false; \\\n}\n\n#define torture_assert_str_equal(test, arg1, arg2, desc) \\\n\tif (arg1 == NULL && arg2 == NULL) { /* OK, both NULL == equal */ \\\n\t} else if (arg1 == NULL || arg2 == NULL) {\t\t\t\\\n\t\treturn false;\t\t\t\t\t\t\\\n\t} else if (strcmp(arg1, arg2)) {\t\t\t\\\n\t\tprintf(\"failure: %s [\\n%s: Expected %s, got %s: %s\\n]\\n\", \\\n\t\t   test, __location__, arg1, arg2, desc); \\\n\t\treturn false; \\\n\t}\n\n#define CHECK_SIZE(test, ptr, tsize) do { \\\n\tif (talloc_total_size(ptr) != (tsize)) { \\\n\t\tprintf(\"failed: %s [\\n%s: wrong '%s' tree size: got %u  expected %u\\n]\\n\", \\\n\t\t       test, __location__, #ptr, \\\n\t\t       (unsigned)talloc_total_size(ptr), \\\n\t\t       (unsigned)tsize); \\\n\t\ttalloc_report_full(ptr, stdout); \\\n\t\treturn false; \\\n\t} \\\n} while (0)\n\n#define CHECK_BLOCKS(test, ptr, tblocks) do { \\\n\tif (talloc_total_blocks(ptr) != (tblocks)) { \\\n\t\tprintf(\"failed: %s [\\n%s: wrong '%s' tree blocks: got %u  expected %u\\n]\\n\", \\\n\t\t       test, __location__, #ptr, \\\n\t\t       (unsigned)talloc_total_blocks(ptr), \\\n\t\t       (unsigned)tblocks); \\\n\t\ttalloc_report_full(ptr, stdout); \\\n\t\treturn false; \\\n\t} \\\n} while (0)\n\n#define CHECK_PARENT(test, ptr, parent) do { \\\n\tif (talloc_parent(ptr) != (parent)) { \\\n\t\tprintf(\"failed: %s [\\n%s: '%s' has wrong parent: got %p  expected %p\\n]\\n\", \\\n\t\t       test, __location__, #ptr, \\\n\t\t       talloc_parent(ptr), \\\n\t\t       (parent)); \\\n\t\ttalloc_report_full(ptr, stdout); \\\n\t\ttalloc_report_full(parent, stdout); \\\n\t\ttalloc_report_full(NULL, stdout); \\\n\t\treturn false; \\\n\t} \\\n} while (0)\n\nstatic unsigned int test_abort_count;\n\n#if 0\nstatic void test_abort_fn(const char *reason)\n{\n\tprintf(\"# test_abort_fn(%s)\\n\", reason);\n\ttest_abort_count++;\n}\n\nstatic void test_abort_start(void)\n{\n\ttest_abort_count = 0;\n\ttalloc_set_abort_fn(test_abort_fn);\n}\n#endif\n\nstatic void test_abort_stop(void)\n{\n\ttest_abort_count = 0;\n\ttalloc_set_abort_fn(NULL);\n}\n\nstatic void test_log_stdout(const char *message)\n{\n\tfprintf(stdout, \"%s\", message);\n}\n\n/*\n  test references\n*/\nstatic bool test_ref1(void)\n{\n\tvoid *root, *p1, *p2, *ref, *r1;\n\n\tprintf(\"test: ref1\\n# SINGLE REFERENCE FREE\\n\");\n\n\troot = talloc_named_const(NULL, 0, \"root\");\n\tp1 = talloc_named_const(root, 1, \"p1\");\n\tp2 = talloc_named_const(p1, 1, \"p2\");\n\ttalloc_named_const(p1, 1, \"x1\");\n\ttalloc_named_const(p1, 2, \"x2\");\n\ttalloc_named_const(p1, 3, \"x3\");\n\n\tr1 = talloc_named_const(root, 1, \"r1\");\n\tref = talloc_reference(r1, p2);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"ref1\", p1, 5);\n\tCHECK_BLOCKS(\"ref1\", p2, 1);\n\tCHECK_BLOCKS(\"ref1\", ref, 1);\n\tCHECK_BLOCKS(\"ref1\", r1, 2);\n\n\tfprintf(stderr, \"Freeing p2\\n\");\n\ttalloc_unlink(r1, p2);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"ref1\", p1, 5);\n\tCHECK_BLOCKS(\"ref1\", p2, 1);\n\tCHECK_BLOCKS(\"ref1\", r1, 1);\n\n\tfprintf(stderr, \"Freeing p1\\n\");\n\ttalloc_free(p1);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"ref1\", r1, 1);\n\n\tfprintf(stderr, \"Freeing r1\\n\");\n\ttalloc_free(r1);\n\ttalloc_report_full(NULL, stderr);\n\n\tfprintf(stderr, \"Testing NULL\\n\");\n\tif (talloc_reference(root, NULL)) {\n\t\treturn false;\n\t}\n\n\tCHECK_BLOCKS(\"ref1\", root, 1);\n\n\tCHECK_SIZE(\"ref1\", root, 0);\n\n\ttalloc_free(root);\n\tprintf(\"success: ref1\\n\");\n\treturn true;\n}\n\n/*\n  test references\n*/\nstatic bool test_ref2(void)\n{\n\tvoid *root, *p1, *p2, *ref, *r1;\n\n\tprintf(\"test: ref2\\n# DOUBLE REFERENCE FREE\\n\");\n\troot = talloc_named_const(NULL, 0, \"root\");\n\tp1 = talloc_named_const(root, 1, \"p1\");\n\ttalloc_named_const(p1, 1, \"x1\");\n\ttalloc_named_const(p1, 1, \"x2\");\n\ttalloc_named_const(p1, 1, \"x3\");\n\tp2 = talloc_named_const(p1, 1, \"p2\");\n\n\tr1 = talloc_named_const(root, 1, \"r1\");\n\tref = talloc_reference(r1, p2);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"ref2\", p1, 5);\n\tCHECK_BLOCKS(\"ref2\", p2, 1);\n\tCHECK_BLOCKS(\"ref2\", r1, 2);\n\n\tfprintf(stderr, \"Freeing ref\\n\");\n\ttalloc_unlink(r1, ref);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"ref2\", p1, 5);\n\tCHECK_BLOCKS(\"ref2\", p2, 1);\n\tCHECK_BLOCKS(\"ref2\", r1, 1);\n\n\tfprintf(stderr, \"Freeing p2\\n\");\n\ttalloc_free(p2);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"ref2\", p1, 4);\n\tCHECK_BLOCKS(\"ref2\", r1, 1);\n\n\tfprintf(stderr, \"Freeing p1\\n\");\n\ttalloc_free(p1);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"ref2\", r1, 1);\n\n\tfprintf(stderr, \"Freeing r1\\n\");\n\ttalloc_free(r1);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_SIZE(\"ref2\", root, 0);\n\n\ttalloc_free(root);\n\tprintf(\"success: ref2\\n\");\n\treturn true;\n}\n\n/*\n  test references\n*/\nstatic bool test_ref3(void)\n{\n\tvoid *root, *p1, *p2, *ref, *r1;\n\n\tprintf(\"test: ref3\\n# PARENT REFERENCE FREE\\n\");\n\n\troot = talloc_named_const(NULL, 0, \"root\");\n\tp1 = talloc_named_const(root, 1, \"p1\");\n\tp2 = talloc_named_const(root, 1, \"p2\");\n\tr1 = talloc_named_const(p1, 1, \"r1\");\n\tref = talloc_reference(p2, r1);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"ref3\", p1, 2);\n\tCHECK_BLOCKS(\"ref3\", p2, 2);\n\tCHECK_BLOCKS(\"ref3\", r1, 1);\n\tCHECK_BLOCKS(\"ref3\", ref, 1);\n\n\tfprintf(stderr, \"Freeing p1\\n\");\n\ttalloc_free(p1);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"ref3\", p2, 2);\n\tCHECK_BLOCKS(\"ref3\", r1, 1);\n\n\tfprintf(stderr, \"Freeing p2\\n\");\n\ttalloc_free(p2);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_SIZE(\"ref3\", root, 0);\n\n\ttalloc_free(root);\n\n\tprintf(\"success: ref3\\n\");\n\treturn true;\n}\n\n/*\n  test references\n*/\nstatic bool test_ref4(void)\n{\n\tvoid *root, *p1, *p2, *ref, *r1;\n\n\tprintf(\"test: ref4\\n# REFERRER REFERENCE FREE\\n\");\n\n\troot = talloc_named_const(NULL, 0, \"root\");\n\tp1 = talloc_named_const(root, 1, \"p1\");\n\ttalloc_named_const(p1, 1, \"x1\");\n\ttalloc_named_const(p1, 1, \"x2\");\n\ttalloc_named_const(p1, 1, \"x3\");\n\tp2 = talloc_named_const(p1, 1, \"p2\");\n\n\tr1 = talloc_named_const(root, 1, \"r1\");\n\tref = talloc_reference(r1, p2);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"ref4\", p1, 5);\n\tCHECK_BLOCKS(\"ref4\", p2, 1);\n\tCHECK_BLOCKS(\"ref4\", ref, 1);\n\tCHECK_BLOCKS(\"ref4\", r1, 2);\n\n\tfprintf(stderr, \"Freeing r1\\n\");\n\ttalloc_free(r1);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"ref4\", p1, 5);\n\tCHECK_BLOCKS(\"ref4\", p2, 1);\n\n\tfprintf(stderr, \"Freeing p2\\n\");\n\ttalloc_free(p2);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"ref4\", p1, 4);\n\n\tfprintf(stderr, \"Freeing p1\\n\");\n\ttalloc_free(p1);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_SIZE(\"ref4\", root, 0);\n\n\ttalloc_free(root);\n\n\tprintf(\"success: ref4\\n\");\n\treturn true;\n}\n\n\n/*\n  test references\n*/\nstatic bool test_unlink1(void)\n{\n\tvoid *root, *p1, *p2, *ref, *r1;\n\n\tprintf(\"test: unlink\\n# UNLINK\\n\");\n\n\troot = talloc_named_const(NULL, 0, \"root\");\n\tp1 = talloc_named_const(root, 1, \"p1\");\n\ttalloc_named_const(p1, 1, \"x1\");\n\ttalloc_named_const(p1, 1, \"x2\");\n\ttalloc_named_const(p1, 1, \"x3\");\n\tp2 = talloc_named_const(p1, 1, \"p2\");\n\n\tr1 = talloc_named_const(p1, 1, \"r1\");\n\tref = talloc_reference(r1, p2);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"unlink\", p1, 7);\n\tCHECK_BLOCKS(\"unlink\", p2, 1);\n\tCHECK_BLOCKS(\"unlink\", ref, 1);\n\tCHECK_BLOCKS(\"unlink\", r1, 2);\n\n\tfprintf(stderr, \"Unreferencing r1\\n\");\n\ttalloc_unlink(r1, p2);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_BLOCKS(\"unlink\", p1, 6);\n\tCHECK_BLOCKS(\"unlink\", p2, 1);\n\tCHECK_BLOCKS(\"unlink\", r1, 1);\n\n\tfprintf(stderr, \"Freeing p1\\n\");\n\ttalloc_free(p1);\n\ttalloc_report_full(root, stderr);\n\n\tCHECK_SIZE(\"unlink\", root, 0);\n\n\ttalloc_free(root);\n\n\tprintf(\"success: unlink\\n\");\n\treturn true;\n}\n\nstatic int fail_destructor(void *ptr)\n{\n\treturn -1;\n}\n\n/*\n  miscellaneous tests to try to get a higher test coverage percentage\n*/\nstatic bool test_misc(void)\n{\n\tvoid *root, *p1;\n\tchar *p2;\n\tdouble *d;\n\tconst char *name;\n\n\tprintf(\"test: misc\\n# MISCELLANEOUS\\n\");\n\n\troot = talloc_new(NULL);\n\n\tp1 = talloc_size(root, 0x7fffffff);\n\ttorture_assert(\"misc\", !p1, \"failed: large talloc allowed\\n\");\n\n\tp1 = talloc_strdup(root, \"foo\");\n\ttalloc_increase_ref_count(p1);\n\ttalloc_increase_ref_count(p1);\n\ttalloc_increase_ref_count(p1);\n\tCHECK_BLOCKS(\"misc\", p1, 1);\n\tCHECK_BLOCKS(\"misc\", root, 2);\n\ttalloc_unlink(NULL, p1);\n\tCHECK_BLOCKS(\"misc\", p1, 1);\n\tCHECK_BLOCKS(\"misc\", root, 2);\n\ttalloc_unlink(NULL, p1);\n\tCHECK_BLOCKS(\"misc\", p1, 1);\n\tCHECK_BLOCKS(\"misc\", root, 2);\n\tp2 = talloc_strdup(p1, \"foo\");\n\ttorture_assert(\"misc\", talloc_unlink(root, p2) == -1,\n\t\t\t\t   \"failed: talloc_unlink() of non-reference context should return -1\\n\");\n\ttorture_assert(\"misc\", talloc_unlink(p1, p2) == 0,\n\t\t\"failed: talloc_unlink() of parent should succeed\\n\");\n\ttalloc_unlink(NULL, p1);\n\tCHECK_BLOCKS(\"misc\", p1, 1);\n\tCHECK_BLOCKS(\"misc\", root, 2);\n\n\tname = talloc_set_name(p1, \"my name is %s\", \"foo\");\n\ttorture_assert_str_equal(\"misc\", talloc_get_name(p1), \"my name is foo\",\n\t\t\"failed: wrong name after talloc_set_name(my name is foo)\");\n\ttorture_assert_str_equal(\"misc\", talloc_get_name(p1), name,\n\t\t\"failed: wrong name after talloc_set_name(my name is foo)\");\n\tCHECK_BLOCKS(\"misc\", p1, 2);\n\tCHECK_BLOCKS(\"misc\", root, 3);\n\n\ttalloc_set_name_const(p1, NULL);\n\ttorture_assert_str_equal (\"misc\", talloc_get_name(p1), \"UNNAMED\",\n\t\t\"failed: wrong name after talloc_set_name(NULL)\");\n\tCHECK_BLOCKS(\"misc\", p1, 2);\n\tCHECK_BLOCKS(\"misc\", root, 3);\n\n\ttorture_assert(\"misc\", talloc_free(NULL) == -1,\n\t\t\t\t   \"talloc_free(NULL) should give -1\\n\");\n\n\ttalloc_set_destructor(p1, fail_destructor);\n\ttorture_assert(\"misc\", talloc_free(p1) == -1,\n\t\t\"Failed destructor should cause talloc_free to fail\\n\");\n\ttalloc_set_destructor(p1, NULL);\n\n\ttalloc_report(root, stderr);\n\n\n\tp2 = (char *)talloc_zero_size(p1, 20);\n\ttorture_assert(\"misc\", p2[19] == 0, \"Failed to give zero memory\\n\");\n\ttalloc_free(p2);\n\n\ttorture_assert(\"misc\", talloc_strdup(root, NULL) == NULL,\n\t\t\"failed: strdup on NULL should give NULL\\n\");\n\n\tp2 = talloc_strndup(p1, \"foo\", 2);\n\ttorture_assert(\"misc\", strcmp(\"fo\", p2) == 0,\n\t\t\t\t   \"strndup doesn't work\\n\");\n\tp2 = talloc_asprintf_append_buffer(p2, \"o%c\", 'd');\n\ttorture_assert(\"misc\", strcmp(\"food\", p2) == 0,\n\t\t\t\t   \"talloc_asprintf_append_buffer doesn't work\\n\");\n\tCHECK_BLOCKS(\"misc\", p2, 1);\n\tCHECK_BLOCKS(\"misc\", p1, 3);\n\n\tp2 = talloc_asprintf_append_buffer(NULL, \"hello %s\", \"world\");\n\ttorture_assert(\"misc\", strcmp(\"hello world\", p2) == 0,\n\t\t\"talloc_asprintf_append_buffer doesn't work\\n\");\n\tCHECK_BLOCKS(\"misc\", p2, 1);\n\tCHECK_BLOCKS(\"misc\", p1, 3);\n\ttalloc_free(p2);\n\n\td = talloc_array(p1, double, 0x20000000);\n\ttorture_assert(\"misc\", !d, \"failed: integer overflow not detected\\n\");\n\n\td = talloc_realloc(p1, d, double, 0x20000000);\n\ttorture_assert(\"misc\", !d, \"failed: integer overflow not detected\\n\");\n\n\ttalloc_free(p1);\n\tCHECK_BLOCKS(\"misc\", root, 1);\n\n\tp1 = talloc_named(root, 100, \"%d bytes\", 100);\n\tCHECK_BLOCKS(\"misc\", p1, 2);\n\tCHECK_BLOCKS(\"misc\", root, 3);\n\ttalloc_unlink(root, p1);\n\n\tp1 = talloc_init(\"%d bytes\", 200);\n\tp2 = talloc_asprintf(p1, \"my test '%s'\", \"string\");\n\ttorture_assert_str_equal(\"misc\", p2, \"my test 'string'\",\n\t\t\"failed: talloc_asprintf(\\\"my test '%%s'\\\", \\\"string\\\") gave: \\\"%s\\\"\");\n\tCHECK_BLOCKS(\"misc\", p1, 3);\n\tCHECK_SIZE(\"misc\", p2, 17);\n\tCHECK_BLOCKS(\"misc\", root, 1);\n\ttalloc_unlink(NULL, p1);\n\n\tp1 = talloc_named_const(root, 10, \"p1\");\n\tp2 = (char *)talloc_named_const(root, 20, \"p2\");\n\t(void)talloc_reference(p1, p2);\n\ttalloc_report_full(root, stderr);\n\ttalloc_unlink(root, p2);\n\ttalloc_report_full(root, stderr);\n\tCHECK_BLOCKS(\"misc\", p2, 1);\n\tCHECK_BLOCKS(\"misc\", p1, 2);\n\tCHECK_BLOCKS(\"misc\", root, 3);\n\ttalloc_unlink(p1, p2);\n\ttalloc_unlink(root, p1);\n\n\tp1 = talloc_named_const(root, 10, \"p1\");\n\tp2 = (char *)talloc_named_const(root, 20, \"p2\");\n\t(void)talloc_reference(NULL, p2);\n\ttalloc_report_full(root, stderr);\n\ttalloc_unlink(root, p2);\n\ttalloc_report_full(root, stderr);\n\tCHECK_BLOCKS(\"misc\", p2, 1);\n\tCHECK_BLOCKS(\"misc\", p1, 1);\n\tCHECK_BLOCKS(\"misc\", root, 2);\n\ttalloc_unlink(NULL, p2);\n\ttalloc_unlink(root, p1);\n\n\t/* Test that talloc_unlink is a no-op */\n\n\ttorture_assert(\"misc\", talloc_unlink(root, NULL) == -1,\n\t\t\"failed: talloc_unlink(root, NULL) == -1\\n\");\n\n\ttalloc_report(root, stderr);\n\ttalloc_report(NULL, stderr);\n\n\tCHECK_SIZE(\"misc\", root, 0);\n\n\ttalloc_free(root);\n\n\tCHECK_SIZE(\"misc\", NULL, 0);\n\n\ttalloc_enable_null_tracking_no_autofree();\n\ttalloc_enable_leak_report();\n\ttalloc_enable_leak_report_full();\n\n\tprintf(\"success: misc\\n\");\n\n\treturn true;\n}\n\n\n/*\n  test realloc\n*/\nstatic bool test_realloc(void)\n{\n\tvoid *root, *p1, *p2;\n\n\tprintf(\"test: realloc\\n# REALLOC\\n\");\n\n\troot = talloc_new(NULL);\n\n\tp1 = talloc_size(root, 10);\n\tCHECK_SIZE(\"realloc\", p1, 10);\n\n\tp1 = talloc_realloc_size(NULL, p1, 20);\n\tCHECK_SIZE(\"realloc\", p1, 20);\n\n\ttalloc_new(p1);\n\n\tp2 = talloc_realloc_size(p1, NULL, 30);\n\n\ttalloc_new(p1);\n\n\tp2 = talloc_realloc_size(p1, p2, 40);\n\n\tCHECK_SIZE(\"realloc\", p2, 40);\n\tCHECK_SIZE(\"realloc\", root, 60);\n\tCHECK_BLOCKS(\"realloc\", p1, 4);\n\n\tp1 = talloc_realloc_size(NULL, p1, 20);\n\tCHECK_SIZE(\"realloc\", p1, 60);\n\n\ttalloc_increase_ref_count(p2);\n\ttorture_assert(\"realloc\", talloc_realloc_size(NULL, p2, 5) == NULL,\n\t\t\"failed: talloc_realloc() on a referenced pointer should fail\\n\");\n\tCHECK_BLOCKS(\"realloc\", p1, 4);\n\n\ttalloc_realloc_size(NULL, p2, 0);\n\ttalloc_realloc_size(NULL, p2, 0);\n\tCHECK_BLOCKS(\"realloc\", p1, 4);\n\ttalloc_realloc_size(p1, p2, 0);\n\tCHECK_BLOCKS(\"realloc\", p1, 3);\n\n\ttorture_assert(\"realloc\", talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL,\n\t\t\"failed: oversize talloc should fail\\n\");\n\n\ttalloc_realloc_size(NULL, p1, 0);\n\tCHECK_BLOCKS(\"realloc\", root, 4);\n\ttalloc_realloc_size(root, p1, 0);\n\tCHECK_BLOCKS(\"realloc\", root, 1);\n\n\tCHECK_SIZE(\"realloc\", root, 0);\n\n\ttalloc_free(root);\n\n\tprintf(\"success: realloc\\n\");\n\n\treturn true;\n}\n\n/*\n  test realloc with a child\n*/\nstatic bool test_realloc_child(void)\n{\n\tvoid *root;\n\tstruct el2 {\n\t\tconst char *name;\n\t} *el2, *el2_2, *el2_3, **el_list_save;\n\tstruct el1 {\n\t\tint count;\n\t\tstruct el2 **list, **list2, **list3;\n\t} *el1;\n\n\tprintf(\"test: REALLOC WITH CHILD\\n\");\n\n\troot = talloc_new(NULL);\n\n\tel1 = talloc(root, struct el1);\n\tel1->list = talloc(el1, struct el2 *);\n\tel1->list[0] = talloc(el1->list, struct el2);\n\tel1->list[0]->name = talloc_strdup(el1->list[0], \"testing\");\n\n\tel1->list2 = talloc(el1, struct el2 *);\n\tel1->list2[0] = talloc(el1->list2, struct el2);\n\tel1->list2[0]->name = talloc_strdup(el1->list2[0], \"testing2\");\n\n\tel1->list3 = talloc(el1, struct el2 *);\n\tel1->list3[0] = talloc(el1->list3, struct el2);\n\tel1->list3[0]->name = talloc_strdup(el1->list3[0], \"testing2\");\n\n\tel2 = talloc(el1->list, struct el2);\n\tCHECK_PARENT(\"el2\", el2, el1->list);\n\tel2_2 = talloc(el1->list2, struct el2);\n\tCHECK_PARENT(\"el2\", el2_2, el1->list2);\n\tel2_3 = talloc(el1->list3, struct el2);\n\tCHECK_PARENT(\"el2\", el2_3, el1->list3);\n\n\tel_list_save = el1->list;\n\tel1->list = talloc_realloc(el1, el1->list, struct el2 *, 100);\n\tif (el1->list == el_list_save) {\n\t\tprintf(\"failure: talloc_realloc didn't move pointer\");\n\t\treturn false;\n\t}\n\n\tCHECK_PARENT(\"el1_after_realloc\", el1->list, el1);\n\tel1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200);\n\tCHECK_PARENT(\"el1_after_realloc\", el1->list2, el1);\n\tel1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300);\n\tCHECK_PARENT(\"el1_after_realloc\", el1->list3, el1);\n\n\tCHECK_PARENT(\"el2\", el2, el1->list);\n\tCHECK_PARENT(\"el2\", el2_2, el1->list2);\n\tCHECK_PARENT(\"el2\", el2_3, el1->list3);\n\n\t/* Finally check realloc with multiple children */\n\tel1 = talloc_realloc(root, el1, struct el1, 100);\n\tCHECK_PARENT(\"el1->list\", el1->list, el1);\n\tCHECK_PARENT(\"el1->list2\", el1->list2, el1);\n\tCHECK_PARENT(\"el1->list3\", el1->list3, el1);\n\n\ttalloc_free(root);\n\n\tprintf(\"success: REALLOC WITH CHILD\\n\");\n\treturn true;\n}\n\n/*\n  test type checking\n*/\nstatic bool test_type(void)\n{\n\tvoid *root;\n\tstruct el1 {\n\t\tint count;\n\t};\n\tstruct el2 {\n\t\tint count;\n\t};\n\tstruct el1 *el1;\n\n\tprintf(\"test: type\\n# talloc type checking\\n\");\n\n\troot = talloc_new(NULL);\n\n\tel1 = talloc(root, struct el1);\n\n\tel1->count = 1;\n\n\ttorture_assert(\"type\", talloc_get_type(el1, struct el1) == el1,\n\t\t\"type check failed on el1\\n\");\n\ttorture_assert(\"type\", talloc_get_type(el1, struct el2) == NULL,\n\t\t\"type check failed on el1 with el2\\n\");\n\ttalloc_set_type(el1, struct el2);\n\ttorture_assert(\"type\", talloc_get_type(el1, struct el2) == (struct el2 *)el1,\n\t\t\"type set failed on el1 with el2\\n\");\n\n\ttalloc_free(root);\n\n\tprintf(\"success: type\\n\");\n\treturn true;\n}\n\n/*\n  test steal\n*/\nstatic bool test_steal(void)\n{\n\tvoid *root, *p1, *p2;\n\n\tprintf(\"test: steal\\n# STEAL\\n\");\n\n\troot = talloc_new(NULL);\n\n\tp1 = talloc_array(root, char, 10);\n\tCHECK_SIZE(\"steal\", p1, 10);\n\n\tp2 = talloc_realloc(root, NULL, char, 20);\n\tCHECK_SIZE(\"steal\", p1, 10);\n\tCHECK_SIZE(\"steal\", root, 30);\n\n\ttorture_assert(\"steal\", talloc_steal(p1, NULL) == NULL,\n\t\t\"failed: stealing NULL should give NULL\\n\");\n\n\ttorture_assert(\"steal\", talloc_steal(p1, p1) == p1,\n\t\t\"failed: stealing to ourselves is a nop\\n\");\n\tCHECK_BLOCKS(\"steal\", root, 3);\n\tCHECK_SIZE(\"steal\", root, 30);\n\n\ttalloc_steal(NULL, p1);\n\ttalloc_steal(NULL, p2);\n\tCHECK_BLOCKS(\"steal\", root, 1);\n\tCHECK_SIZE(\"steal\", root, 0);\n\n\ttalloc_free(p1);\n\ttalloc_steal(root, p2);\n\tCHECK_BLOCKS(\"steal\", root, 2);\n\tCHECK_SIZE(\"steal\", root, 20);\n\n\ttalloc_free(p2);\n\n\tCHECK_BLOCKS(\"steal\", root, 1);\n\tCHECK_SIZE(\"steal\", root, 0);\n\n\ttalloc_free(root);\n\n\tp1 = talloc_size(NULL, 3);\n\ttalloc_report_full(NULL, stderr);\n\tCHECK_SIZE(\"steal\", NULL, 3);\n\ttalloc_free(p1);\n\n\tprintf(\"success: steal\\n\");\n\treturn true;\n}\n\n/*\n  test move\n*/\nstatic bool test_move(void)\n{\n\tvoid *root;\n\tstruct t_move {\n\t\tchar *p;\n\t\tint *x;\n\t} *t1, *t2;\n\n\tprintf(\"test: move\\n# MOVE\\n\");\n\n\troot = talloc_new(NULL);\n\n\tt1 = talloc(root, struct t_move);\n\tt2 = talloc(root, struct t_move);\n\tt1->p = talloc_strdup(t1, \"foo\");\n\tt1->x = talloc(t1, int);\n\t*t1->x = 42;\n\n\tt2->p = talloc_move(t2, &t1->p);\n\tt2->x = talloc_move(t2, &t1->x);\n\ttorture_assert(\"move\", t1->p == NULL && t1->x == NULL &&\n\t    strcmp(t2->p, \"foo\") == 0 && *t2->x == 42,\n\t\t\"talloc move failed\");\n\n\ttalloc_free(root);\n\n\tprintf(\"success: move\\n\");\n\n\treturn true;\n}\n\n/*\n  test talloc_realloc_fn\n*/\nstatic bool test_realloc_fn(void)\n{\n\tvoid *root, *p1;\n\n\tprintf(\"test: realloc_fn\\n# talloc_realloc_fn\\n\");\n\n\troot = talloc_new(NULL);\n\n\tp1 = talloc_realloc_fn(root, NULL, 10);\n\tCHECK_BLOCKS(\"realloc_fn\", root, 2);\n\tCHECK_SIZE(\"realloc_fn\", root, 10);\n\tp1 = talloc_realloc_fn(root, p1, 20);\n\tCHECK_BLOCKS(\"realloc_fn\", root, 2);\n\tCHECK_SIZE(\"realloc_fn\", root, 20);\n\tp1 = talloc_realloc_fn(root, p1, 0);\n\tCHECK_BLOCKS(\"realloc_fn\", root, 1);\n\tCHECK_SIZE(\"realloc_fn\", root, 0);\n\n\ttalloc_free(root);\n\n\tprintf(\"success: realloc_fn\\n\");\n\treturn true;\n}\n\n\nstatic bool test_unref_reparent(void)\n{\n\tvoid *root, *p1, *p2, *c1;\n\n\tprintf(\"test: unref_reparent\\n# UNREFERENCE AFTER PARENT FREED\\n\");\n\n\troot = talloc_named_const(NULL, 0, \"root\");\n\tp1 = talloc_named_const(root, 1, \"orig parent\");\n\tp2 = talloc_named_const(root, 1, \"parent by reference\");\n\n\tc1 = talloc_named_const(p1, 1, \"child\");\n\ttalloc_reference(p2, c1);\n\n\tCHECK_PARENT(\"unref_reparent\", c1, p1);\n\n\ttalloc_free(p1);\n\n\tCHECK_PARENT(\"unref_reparent\", c1, p2);\n\n\ttalloc_unlink(p2, c1);\n\n\tCHECK_SIZE(\"unref_reparent\", root, 1);\n\n\ttalloc_free(p2);\n\ttalloc_free(root);\n\n\tprintf(\"success: unref_reparent\\n\");\n\treturn true;\n}\n\n/* Make the size big enough to not fit into the stack */\n#define ALLOC_SIZE (128 * 1024)\n#define ALLOC_DUP_STRING \"talloc talloc talloc talloc talloc talloc talloc\"\n\n/*\n  measure the speed of talloc versus malloc\n*/\nstatic bool test_speed(void) disable_optimization;\nstatic bool test_speed(void)\n{\n\tvoid *ctx = talloc_new(NULL);\n\tunsigned count;\n\tconst int loop = 1000;\n\tint i;\n\tstruct timeval tv;\n\n\tprintf(\"test: speed\\n# TALLOC VS MALLOC SPEED\\n\");\n\n\ttv = private_timeval_current();\n\tcount = 0;\n\tdo {\n\t\tvoid *p1, *p2, *p3;\n\t\tfor (i=0;i<loop;i++) {\n\t\t\tp1 = talloc_size(ctx, loop % ALLOC_SIZE);\n\t\t\tp2 = talloc_strdup(p1, ALLOC_DUP_STRING);\n\t\t\tp3 = talloc_size(p1, ALLOC_SIZE);\n\t\t\t(void)p2;\n\t\t\t(void)p3;\n\t\t\ttalloc_free(p1);\n\t\t}\n\t\tcount += 3 * loop;\n\t} while (private_timeval_elapsed(&tv) < 5.0);\n\n\tfprintf(stderr, \"talloc:\\t\\t%.0f ops/sec\\n\", count/private_timeval_elapsed(&tv));\n\n\ttalloc_free(ctx);\n\n\tctx = talloc_pool(NULL, ALLOC_SIZE * 2);\n\n\ttv = private_timeval_current();\n\tcount = 0;\n\tdo {\n\t\tvoid *p1, *p2, *p3;\n\t\tfor (i=0;i<loop;i++) {\n\t\t\tp1 = talloc_size(ctx, loop % ALLOC_SIZE);\n\t\t\tp2 = talloc_strdup(p1, ALLOC_DUP_STRING);\n\t\t\tp3 = talloc_size(p1, ALLOC_SIZE);\n\t\t\t(void)p2;\n\t\t\t(void)p3;\n\t\t\ttalloc_free(p1);\n\t\t}\n\t\tcount += 3 * loop;\n\t} while (private_timeval_elapsed(&tv) < 5.0);\n\n\ttalloc_free(ctx);\n\n\tfprintf(stderr, \"talloc_pool:\\t%.0f ops/sec\\n\", count/private_timeval_elapsed(&tv));\n\n\ttv = private_timeval_current();\n\tcount = 0;\n\tdo {\n\t\tvoid *p1, *p2, *p3;\n\t\tfor (i=0;i<loop;i++) {\n\t\t\tp1 = malloc(loop % ALLOC_SIZE);\n\t\t\tp2 = strdup(ALLOC_DUP_STRING);\n\t\t\tp3 = malloc(ALLOC_SIZE);\n\t\t\tfree(p1);\n\t\t\tfree(p2);\n\t\t\tfree(p3);\n\t\t}\n\t\tcount += 3 * loop;\n\t} while (private_timeval_elapsed(&tv) < 5.0);\n\tfprintf(stderr, \"malloc:\\t\\t%.0f ops/sec\\n\", count/private_timeval_elapsed(&tv));\n\n\tprintf(\"\\n# TALLOC_ZERO VS CALLOC SPEED\\n\");\n\n\tctx = talloc_new(NULL);\n\n\ttv = private_timeval_current();\n\tcount = 0;\n\tdo {\n\t\tvoid *p1, *p2, *p3;\n\t\tfor (i=0;i<loop;i++) {\n\t\t\tp1 = talloc_zero_size(ctx, loop % ALLOC_SIZE);\n\t\t\tp2 = talloc_strdup(p1, ALLOC_DUP_STRING);\n\t\t\tp3 = talloc_zero_size(p1, ALLOC_SIZE);\n\t\t\t(void)p2;\n\t\t\t(void)p3;\n\t\t\ttalloc_free(p1);\n\t\t}\n\t\tcount += 3 * loop;\n\t} while (private_timeval_elapsed(&tv) < 5.0);\n\n\tfprintf(stderr, \"talloc_zero:\\t%.0f ops/sec\\n\", count/private_timeval_elapsed(&tv));\n\n\ttalloc_free(ctx);\n\n\ttv = private_timeval_current();\n\tcount = 0;\n\tdo {\n\t\tvoid *p1, *p2, *p3;\n\t\tfor (i=0;i<loop;i++) {\n\t\t\tp1 = calloc(1, loop % ALLOC_SIZE);\n\t\t\tp2 = strdup(ALLOC_DUP_STRING);\n\t\t\tp3 = calloc(1, ALLOC_SIZE);\n\t\t\tfree(p1);\n\t\t\tfree(p2);\n\t\t\tfree(p3);\n\t\t}\n\t\tcount += 3 * loop;\n\t} while (private_timeval_elapsed(&tv) < 5.0);\n\tfprintf(stderr, \"calloc:\\t\\t%.0f ops/sec\\n\", count/private_timeval_elapsed(&tv));\n\n\tprintf(\"success: speed\\n\");\n\n\treturn true;\n}\n\nstatic bool test_lifeless(void)\n{\n\tvoid *top = talloc_new(NULL);\n\tchar *parent, *child;\n\tvoid *child_owner = talloc_new(NULL);\n\n\tprintf(\"test: lifeless\\n# TALLOC_UNLINK LOOP\\n\");\n\n\tparent = talloc_strdup(top, \"parent\");\n\tchild = talloc_strdup(parent, \"child\");\n\t(void)talloc_reference(child, parent);\n\t(void)talloc_reference(child_owner, child);\n\ttalloc_report_full(top, stderr);\n\ttalloc_unlink(top, parent);\n\ttalloc_unlink(top, child);\n\ttalloc_report_full(top, stderr);\n\ttalloc_free(top);\n\ttalloc_free(child_owner);\n\ttalloc_free(child);\n\n\tprintf(\"success: lifeless\\n\");\n\treturn true;\n}\n\nstatic int loop_destructor_count;\n\nstatic int test_loop_destructor(char *ptr)\n{\n\tloop_destructor_count++;\n\treturn 0;\n}\n\nstatic bool test_loop(void)\n{\n\tvoid *top = talloc_new(NULL);\n\tchar *parent;\n\tstruct req1 {\n\t\tchar *req2, *req3;\n\t} *req1;\n\n\tprintf(\"test: loop\\n# TALLOC LOOP DESTRUCTION\\n\");\n\n\tparent = talloc_strdup(top, \"parent\");\n\treq1 = talloc(parent, struct req1);\n\treq1->req2 = talloc_strdup(req1, \"req2\");\n\ttalloc_set_destructor(req1->req2, test_loop_destructor);\n\treq1->req3 = talloc_strdup(req1, \"req3\");\n\t(void)talloc_reference(req1->req3, req1);\n\ttalloc_report_full(top, stderr);\n\ttalloc_free(parent);\n\ttalloc_report_full(top, stderr);\n\ttalloc_report_full(NULL, stderr);\n\ttalloc_free(top);\n\n\ttorture_assert(\"loop\", loop_destructor_count == 1,\n\t\t\t\t   \"FAILED TO FIRE LOOP DESTRUCTOR\\n\");\n\tloop_destructor_count = 0;\n\n\tprintf(\"success: loop\\n\");\n\treturn true;\n}\n\nstatic int realloc_parent_destructor_count;\n\nstatic int test_realloc_parent_destructor(char *ptr)\n{\n\trealloc_parent_destructor_count++;\n\treturn 0;\n}\n\nstatic bool test_realloc_on_destructor_parent(void)\n{\n\tvoid *top = talloc_new(NULL);\n\tchar *parent;\n\tchar *a, *b, *C, *D;\n\trealloc_parent_destructor_count = 0;\n\n\tprintf(\"test: free_for_exit\\n# TALLOC FREE FOR EXIT\\n\");\n\n\tparent = talloc_strdup(top, \"parent\");\n\ta = talloc_strdup(parent, \"a\");\n\tb = talloc_strdup(a, \"b\");\n\tC = talloc_strdup(a, \"C\");\n\tD = talloc_strdup(b, \"D\");\n\ttalloc_set_destructor(D, test_realloc_parent_destructor);\n\t/* Capitalised ones have destructors.\n\t *\n\t * parent --> a -> b -> D\n\t *              -> c\n\t */\n\n\ta = talloc_realloc(parent, a, char, 2048);\n\n\ttorture_assert(\"check talloc_realloc\", a != NULL, \"talloc_realloc failed\");\n\n\ttalloc_set_destructor(C, test_realloc_parent_destructor);\n\t/*\n\t * parent --> a[2048] -> b -> D\n\t *                    -> C\n\t *\n\t */\n\n\ttalloc_free(parent);\n\n\ttorture_assert(\"check destructor realloc_parent_destructor\",\n\t\t       realloc_parent_destructor_count == 2,\n\t\t       \"FAILED TO FIRE free_for_exit_destructor\\n\");\n\n\n\tprintf(\"success: free_for_exit\\n\");\n\ttalloc_free(top); /* make ASAN happy */\n\n\treturn true;\n}\n\nstatic int fail_destructor_str(char *ptr)\n{\n\treturn -1;\n}\n\nstatic bool test_free_parent_deny_child(void)\n{\n\tvoid *top = talloc_new(NULL);\n\tchar *level1;\n\tchar *level2;\n\tchar *level3;\n\n\tprintf(\"test: free_parent_deny_child\\n# TALLOC FREE PARENT DENY CHILD\\n\");\n\n\tlevel1 = talloc_strdup(top, \"level1\");\n\tlevel2 = talloc_strdup(level1, \"level2\");\n\tlevel3 = talloc_strdup(level2, \"level3\");\n\n\ttalloc_set_destructor(level3, fail_destructor_str);\n\ttalloc_free(level1);\n\ttalloc_set_destructor(level3, NULL);\n\n\tCHECK_PARENT(\"free_parent_deny_child\", level3, top);\n\n\ttalloc_free(top);\n\n\tprintf(\"success: free_parent_deny_child\\n\");\n\treturn true;\n}\n\nstruct new_parent {\n\tvoid *new_parent;\n\tchar val[20];\n};\n\nstatic int reparenting_destructor(struct new_parent *np)\n{\n\ttalloc_set_destructor(np, NULL);\n\t(void)talloc_move(np->new_parent, &np);\n\treturn -1;\n}\n\nstatic bool test_free_parent_reparent_child(void)\n{\n\tvoid *top = talloc_new(NULL);\n\tchar *level1;\n\tchar *alternate_level1;\n\tchar *level2;\n\tstruct new_parent *level3;\n\n\tprintf(\"test: free_parent_reparent_child\\n# \"\n\t\t\"TALLOC FREE PARENT REPARENT CHILD\\n\");\n\n\tlevel1 = talloc_strdup(top, \"level1\");\n\talternate_level1 = talloc_strdup(top, \"alternate_level1\");\n\tlevel2 = talloc_strdup(level1, \"level2\");\n\tlevel3 = talloc(level2, struct new_parent);\n\tlevel3->new_parent = alternate_level1;\n\tmemset(level3->val, 'x', sizeof(level3->val));\n\n\ttalloc_set_destructor(level3, reparenting_destructor);\n\ttalloc_free(level1);\n\n\tCHECK_PARENT(\"free_parent_reparent_child\",\n\t\tlevel3, alternate_level1);\n\n\ttalloc_free(top);\n\n\tprintf(\"success: free_parent_reparent_child\\n\");\n\treturn true;\n}\n\nstatic bool test_free_parent_reparent_child_in_pool(void)\n{\n\tvoid *top = talloc_new(NULL);\n\tchar *level1;\n\tchar *alternate_level1;\n\tchar *level2;\n\tvoid *pool;\n\tstruct new_parent *level3;\n\n\tprintf(\"test: free_parent_reparent_child_in_pool\\n# \"\n\t\t\"TALLOC FREE PARENT REPARENT CHILD IN POOL\\n\");\n\n\tpool = talloc_pool(top, 1024);\n\tlevel1 = talloc_strdup(pool, \"level1\");\n\talternate_level1 = talloc_strdup(top, \"alternate_level1\");\n\tlevel2 = talloc_strdup(level1, \"level2\");\n\tlevel3 = talloc(level2, struct new_parent);\n\tlevel3->new_parent = alternate_level1;\n\tmemset(level3->val, 'x', sizeof(level3->val));\n\n\ttalloc_set_destructor(level3, reparenting_destructor);\n\ttalloc_free(level1);\n\ttalloc_set_destructor(level3, NULL);\n\n\tCHECK_PARENT(\"free_parent_reparent_child_in_pool\",\n\t\tlevel3, alternate_level1);\n\n\t/* Even freeing alternate_level1 should leave pool alone. */\n\ttalloc_free(alternate_level1);\n\ttalloc_free(top);\n\n\tprintf(\"success: free_parent_reparent_child_in_pool\\n\");\n\treturn true;\n}\n\n\nstatic bool test_talloc_ptrtype(void)\n{\n\tvoid *top = talloc_new(NULL);\n\tstruct struct1 {\n\t\tint foo;\n\t\tint bar;\n\t} *s1, *s2, **s3, ***s4;\n\tconst char *location1;\n\tconst char *location2;\n\tconst char *location3;\n\tconst char *location4;\n\n\tprintf(\"test: ptrtype\\n# TALLOC PTRTYPE\\n\");\n\n\ts1 = talloc_ptrtype(top, s1);location1 = __location__;\n\n\tif (talloc_get_size(s1) != sizeof(struct struct1)) {\n\t\tprintf(\"failure: ptrtype [\\n\"\n\t\t  \"talloc_ptrtype() allocated the wrong size %lu (should be %lu)\\n\"\n\t\t  \"]\\n\", (unsigned long)talloc_get_size(s1),\n\t\t           (unsigned long)sizeof(struct struct1));\n\t\treturn false;\n\t}\n\n\tif (strcmp(location1, talloc_get_name(s1)) != 0) {\n\t\tprintf(\"failure: ptrtype [\\n\"\n\t\t  \"talloc_ptrtype() sets the wrong name '%s' (should be '%s')\\n]\\n\",\n\t\t\ttalloc_get_name(s1), location1);\n\t\treturn false;\n\t}\n\n\ts2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__;\n\n\tif (talloc_get_size(s2) != (sizeof(struct struct1) * 10)) {\n\t\tprintf(\"failure: ptrtype [\\n\"\n\t\t\t   \"talloc_array_ptrtype() allocated the wrong size \"\n\t\t       \"%lu (should be %lu)\\n]\\n\",\n\t\t\t(unsigned long)talloc_get_size(s2),\n\t\t    (unsigned long)(sizeof(struct struct1)*10));\n\t\treturn false;\n\t}\n\n\tif (strcmp(location2, talloc_get_name(s2)) != 0) {\n\t\tprintf(\"failure: ptrtype [\\n\"\n\t\t\"talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\\n]\\n\",\n\t\t\ttalloc_get_name(s2), location2);\n\t\treturn false;\n\t}\n\n\ts3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__;\n\n\tif (talloc_get_size(s3) != (sizeof(struct struct1 *) * 10)) {\n\t\tprintf(\"failure: ptrtype [\\n\"\n\t\t\t   \"talloc_array_ptrtype() allocated the wrong size \"\n\t\t       \"%lu (should be %lu)\\n]\\n\",\n\t\t\t   (unsigned long)talloc_get_size(s3),\n\t\t       (unsigned long)(sizeof(struct struct1 *)*10));\n\t\treturn false;\n\t}\n\n\ttorture_assert_str_equal(\"ptrtype\", location3, talloc_get_name(s3),\n\t\t\"talloc_array_ptrtype() sets the wrong name\");\n\n\ts4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__;\n\n\tif (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) {\n\t\tprintf(\"failure: ptrtype [\\n\"\n\t\t      \"talloc_array_ptrtype() allocated the wrong size \"\n\t\t       \"%lu (should be %lu)\\n]\\n\",\n\t\t\t   (unsigned long)talloc_get_size(s4),\n\t\t       (unsigned long)(sizeof(struct struct1 **)*10));\n\t\treturn false;\n\t}\n\n\ttorture_assert_str_equal(\"ptrtype\", location4, talloc_get_name(s4),\n\t\t\"talloc_array_ptrtype() sets the wrong name\");\n\n\ttalloc_free(top);\n\n\tprintf(\"success: ptrtype\\n\");\n\treturn true;\n}\n\nstatic int _test_talloc_free_in_destructor(void **ptr)\n{\n\ttalloc_free(*ptr);\n\treturn 0;\n}\n\nstatic bool test_talloc_free_in_destructor(void)\n{\n\tvoid *level0;\n\tvoid *level1;\n\tvoid *level2;\n\tvoid *level3;\n\tvoid *level4;\n\tvoid **level5;\n\n\tprintf(\"test: free_in_destructor\\n# TALLOC FREE IN DESTRUCTOR\\n\");\n\n\tlevel0 = talloc_new(NULL);\n\tlevel1 = talloc_new(level0);\n\tlevel2 = talloc_new(level1);\n\tlevel3 = talloc_new(level2);\n\tlevel4 = talloc_new(level3);\n\tlevel5 = talloc(level4, void *);\n\n\t*level5 = level3;\n\t(void)talloc_reference(level0, level3);\n\t(void)talloc_reference(level3, level3);\n\t(void)talloc_reference(level5, level3);\n\n\ttalloc_set_destructor(level5, _test_talloc_free_in_destructor);\n\n\ttalloc_free(level1);\n\n\ttalloc_free(level0);\n\n\ttalloc_free(level3); /* make ASAN happy */\n\n\tprintf(\"success: free_in_destructor\\n\");\n\treturn true;\n}\n\nstatic bool test_autofree(void)\n{\n#if _SAMBA_BUILD_ < 4\n\t/* autofree test would kill smbtorture */\n\tvoid *p;\n\tprintf(\"test: autofree\\n# TALLOC AUTOFREE CONTEXT\\n\");\n\n\tp = talloc_autofree_context();\n\ttalloc_free(p);\n\n\tp = talloc_autofree_context();\n\ttalloc_free(p);\n\n\tprintf(\"success: autofree\\n\");\n#endif\n\treturn true;\n}\n\nstatic bool test_pool(void)\n{\n\tvoid *pool;\n\tvoid *p1, *p2, *p3, *p4;\n\tvoid *p2_2;\n\n\tpool = talloc_pool(NULL, 1024);\n\n\tp1 = talloc_size(pool, 80);\n\tmemset(p1, 0x11, talloc_get_size(p1));\n\tp2 = talloc_size(pool, 20);\n\tmemset(p2, 0x11, talloc_get_size(p2));\n\tp3 = talloc_size(p1, 50);\n\tmemset(p3, 0x11, talloc_get_size(p3));\n\tp4 = talloc_size(p3, 1000);\n\tmemset(p4, 0x11, talloc_get_size(p4));\n\n\tp2_2 = talloc_realloc_size(pool, p2, 20+1);\n\ttorture_assert(\"pool realloc 20+1\", p2_2 == p2, \"failed: pointer changed\");\n\tmemset(p2, 0x11, talloc_get_size(p2));\n\tp2_2 = talloc_realloc_size(pool, p2, 20-1);\n\ttorture_assert(\"pool realloc 20-1\", p2_2 == p2, \"failed: pointer changed\");\n\tmemset(p2, 0x11, talloc_get_size(p2));\n\tp2_2 = talloc_realloc_size(pool, p2, 20-1);\n\ttorture_assert(\"pool realloc 20-1\", p2_2 == p2, \"failed: pointer changed\");\n\tmemset(p2, 0x11, talloc_get_size(p2));\n\n\ttalloc_free(p3);\n\n\t/* this should reclaim the memory of p4 and p3 */\n\tp2_2 = talloc_realloc_size(pool, p2, 400);\n\ttorture_assert(\"pool realloc 400\", p2_2 == p2, \"failed: pointer changed\");\n\tmemset(p2, 0x11, talloc_get_size(p2));\n\n\ttalloc_free(p1);\n\n\t/* this should reclaim the memory of p1 */\n\tp2_2 = talloc_realloc_size(pool, p2, 800);\n\ttorture_assert(\"pool realloc 800\", p2_2 == p1, \"failed: pointer not changed\");\n\tp2 = p2_2;\n\tmemset(p2, 0x11, talloc_get_size(p2));\n\n\t/* this should do a malloc */\n\tp2_2 = talloc_realloc_size(pool, p2, 1800);\n\ttorture_assert(\"pool realloc 1800\", p2_2 != p2, \"failed: pointer not changed\");\n\tp2 = p2_2;\n\tmemset(p2, 0x11, talloc_get_size(p2));\n\n\t/* this should reclaim the memory from the pool */\n\tp3 = talloc_size(pool, 80);\n\ttorture_assert(\"pool alloc 80\", p3 == p1, \"failed: pointer changed\");\n\tmemset(p3, 0x11, talloc_get_size(p3));\n\n\ttalloc_free(p2);\n\ttalloc_free(p3);\n\n\tp1 = talloc_size(pool, 80);\n\tmemset(p1, 0x11, talloc_get_size(p1));\n\tp2 = talloc_size(pool, 20);\n\tmemset(p2, 0x11, talloc_get_size(p2));\n\n\ttalloc_free(p1);\n\n\tp2_2 = talloc_realloc_size(pool, p2, 20-1);\n\ttorture_assert(\"pool realloc 20-1\", p2_2 == p2, \"failed: pointer changed\");\n\tmemset(p2, 0x11, talloc_get_size(p2));\n\tp2_2 = talloc_realloc_size(pool, p2, 20-1);\n\ttorture_assert(\"pool realloc 20-1\", p2_2 == p2, \"failed: pointer changed\");\n\tmemset(p2, 0x11, talloc_get_size(p2));\n\n\t/* this should do a malloc */\n\tp2_2 = talloc_realloc_size(pool, p2, 1800);\n\ttorture_assert(\"pool realloc 1800\", p2_2 != p2, \"failed: pointer not changed\");\n\tp2 = p2_2;\n\tmemset(p2, 0x11, talloc_get_size(p2));\n\n\t/* this should reclaim the memory from the pool */\n\tp3 = talloc_size(pool, 800);\n\ttorture_assert(\"pool alloc 800\", p3 == p1, \"failed: pointer changed\");\n\tmemset(p3, 0x11, talloc_get_size(p3));\n\n\ttalloc_free(pool);\n\n\treturn true;\n}\n\nstatic bool test_pool_steal(void)\n{\n\tvoid *root;\n\tvoid *pool;\n\tvoid *p1, *p2;\n\tvoid *p1_2, *p2_2;\n\tsize_t hdr;\n\tsize_t ofs1, ofs2;\n\n\troot = talloc_new(NULL);\n\tpool = talloc_pool(root, 1024);\n\n\tp1 = talloc_size(pool, 4 * 16);\n\ttorture_assert(\"pool allocate 4 * 16\", p1 != NULL, \"failed \");\n\tmemset(p1, 0x11, talloc_get_size(p1));\n\tp2 = talloc_size(pool, 4 * 16);\n\ttorture_assert(\"pool allocate 4 * 16\", p2 > p1, \"failed: !(p2 > p1) \");\n\tmemset(p2, 0x11, talloc_get_size(p2));\n\n\tofs1 = PTR_DIFF(p2, p1);\n\thdr = ofs1 - talloc_get_size(p1);\n\n\ttalloc_steal(root, p1);\n\ttalloc_steal(root, p2);\n\n\ttalloc_free(pool);\n\n\tp1_2 = p1;\n\n\tp1_2 = talloc_realloc_size(root, p1, 5 * 16);\n\ttorture_assert(\"pool realloc 5 * 16\", p1_2 > p2, \"failed: pointer not changed\");\n\tmemset(p1_2, 0x11, talloc_get_size(p1_2));\n\tofs1 = PTR_DIFF(p1_2, p2);\n\tofs2 = talloc_get_size(p2) + hdr;\n\n\ttorture_assert(\"pool realloc \", ofs1 == ofs2, \"failed: pointer offset unexpected\");\n\n\tp2_2 = talloc_realloc_size(root, p2, 3 * 16);\n\ttorture_assert(\"pool realloc 5 * 16\", p2_2 == p2, \"failed: pointer changed\");\n\tmemset(p2_2, 0x11, talloc_get_size(p2_2));\n\n\ttalloc_free(p1_2);\n\n\tp2_2 = p2;\n\n\t/* now we should reclaim the full pool */\n\tp2_2 = talloc_realloc_size(root, p2, 8 * 16);\n\ttorture_assert(\"pool realloc 8 * 16\", p2_2 == p1, \"failed: pointer not expected\");\n\tp2 = p2_2;\n\tmemset(p2_2, 0x11, talloc_get_size(p2_2));\n\n\t/* now we malloc and free the full pool space */\n\tp2_2 = talloc_realloc_size(root, p2, 2 * 1024);\n\ttorture_assert(\"pool realloc 2 * 1024\", p2_2 != p1, \"failed: pointer not expected\");\n\tmemset(p2_2, 0x11, talloc_get_size(p2_2));\n\n\ttalloc_free(p2_2);\n\n\ttalloc_free(root);\n\n\treturn true;\n}\n\nstatic bool test_pool_nest(void)\n{\n\tvoid *p1, *p2, *p3;\n\tvoid *e = talloc_new(NULL);\n\n\tp1 = talloc_pool(NULL, 1024);\n\ttorture_assert(\"talloc_pool\", p1 != NULL, \"failed\");\n\n\tp2 = talloc_pool(p1, 500);\n\ttorture_assert(\"talloc_pool\", p2 != NULL, \"failed\");\n\n\tp3 = talloc_size(p2, 10);\n\n\ttalloc_steal(e, p3);\n\n\ttalloc_free(p2);\n\n\ttalloc_free(p3);\n\n\ttalloc_free(p1);\n\n\ttalloc_free(e); /* make ASAN happy */\n\n\treturn true;\n}\n\nstruct pooled {\n\tchar *s1;\n\tchar *s2;\n\tchar *s3;\n};\n\nstatic bool test_pooled_object(void)\n{\n\tstruct pooled *p;\n\tconst char *s1 = \"hello\";\n\tconst char *s2 = \"world\";\n\tconst char *s3 = \"\";\n\n\tp = talloc_pooled_object(NULL, struct pooled, 3,\n\t\t\tstrlen(s1)+strlen(s2)+strlen(s3)+3);\n\n\tif (talloc_get_size(p) != sizeof(struct pooled)) {\n\t\treturn false;\n\t}\n\n\tp->s1 = talloc_strdup(p, s1);\n\n\tTALLOC_FREE(p->s1);\n\tp->s1 = talloc_strdup(p, s2);\n\tTALLOC_FREE(p->s1);\n\n\tp->s1 = talloc_strdup(p, s1);\n\tp->s2 = talloc_strdup(p, s2);\n\tp->s3 = talloc_strdup(p, s3);\n\n\tTALLOC_FREE(p);\n\treturn true;\n}\n\nstatic bool test_free_ref_null_context(void)\n{\n\tvoid *p1, *p2, *p3;\n\tint ret;\n\n\ttalloc_disable_null_tracking();\n\tp1 = talloc_new(NULL);\n\tp2 = talloc_new(NULL);\n\n\tp3 = talloc_reference(p2, p1);\n\ttorture_assert(\"reference\", p3 == p1, \"failed: reference on null\");\n\n\tret = talloc_free(p1);\n\ttorture_assert(\"ref free with null parent\", ret == 0, \"failed: free with null parent\");\n\ttalloc_free(p2);\n\n\ttalloc_enable_null_tracking_no_autofree();\n\tp1 = talloc_new(NULL);\n\tp2 = talloc_new(NULL);\n\n\tp3 = talloc_reference(p2, p1);\n\ttorture_assert(\"reference\", p3 == p1, \"failed: reference on null\");\n\n\tret = talloc_free(p1);\n\ttorture_assert(\"ref free with null tracked parent\", ret == 0, \"failed: free with null parent\");\n\ttalloc_free(p2);\n\n\treturn true;\n}\n\nstatic bool test_rusty(void)\n{\n\tvoid *root;\n\tchar *p1;\n\n\ttalloc_enable_null_tracking();\n\troot = talloc_new(NULL);\n\tp1 = talloc_strdup(root, \"foo\");\n\ttalloc_increase_ref_count(p1);\n\ttalloc_report_full(root, stdout);\n\ttalloc_free(root);\n\tCHECK_BLOCKS(\"null_context\", NULL, 2);\n\ttalloc_free(p1); /* make ASAN happy */\n\n\treturn true;\n}\n\nstatic bool test_free_children(void)\n{\n\tvoid *root;\n\tchar *p1, *p2;\n\tconst char *name, *name2;\n\n\ttalloc_enable_null_tracking();\n\troot = talloc_new(NULL);\n\tp1 = talloc_strdup(root, \"foo1\");\n\tp2 = talloc_strdup(p1, \"foo2\");\n\t(void)p2;\n\n\ttalloc_set_name(p1, \"%s\", \"testname\");\n\ttalloc_free_children(p1);\n\t/* check its still a valid talloc ptr */\n\ttalloc_get_size(talloc_get_name(p1));\n\tif (strcmp(talloc_get_name(p1), \"testname\") != 0) {\n\t\treturn false;\n\t}\n\n\ttalloc_set_name(p1, \"%s\", \"testname\");\n\tname = talloc_get_name(p1);\n\ttalloc_free_children(p1);\n\t/* check its still a valid talloc ptr */\n\ttalloc_get_size(talloc_get_name(p1));\n\ttorture_assert(\"name\", name == talloc_get_name(p1), \"name ptr changed\");\n\ttorture_assert(\"namecheck\", strcmp(talloc_get_name(p1), \"testname\") == 0,\n\t\t       \"wrong name\");\n\tCHECK_BLOCKS(\"name1\", p1, 2);\n\n\t/* note that this does not free the old child name */\n\ttalloc_set_name_const(p1, \"testname2\");\n\tname2 = talloc_get_name(p1);\n\t/* but this does */\n\ttalloc_free_children(p1);\n\t(void)name2;\n\ttorture_assert(\"namecheck\", strcmp(talloc_get_name(p1), \"testname2\") == 0,\n\t\t       \"wrong name\");\n\tCHECK_BLOCKS(\"name1\", p1, 1);\n\n\ttalloc_report_full(root, stdout);\n\ttalloc_free(root);\n\treturn true;\n}\n\nstatic bool test_memlimit(void)\n{\n\tvoid *root;\n\tchar *l1, *l2, *l3, *l4, *l5, *t;\n\tchar *pool;\n\tint i;\n\n\tprintf(\"test: memlimit\\n# MEMORY LIMITS\\n\");\n\n\tprintf(\"==== talloc_new(NULL)\\n\");\n\troot = talloc_new(NULL);\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_size(root, 2048)\\n\");\n\tl1 = talloc_size(root, 2048);\n\ttorture_assert(\"memlimit\", l1 != NULL,\n\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_free(l1)\\n\");\n\ttalloc_free(l1);\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_strdup(root, level 1)\\n\");\n\tl1 = talloc_strdup(root, \"level 1\");\n\ttorture_assert(\"memlimit\", l1 != NULL,\n\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_set_memlimit(l1, 2048)\\n\");\n\ttorture_assert(\"memlimit\", talloc_set_memlimit(l1, 2048) == 0,\n\t\t\"failed: setting memlimit should never fail\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_size(root, 2048)\\n\");\n\tl2 = talloc_size(l1, 2048);\n\ttorture_assert(\"memlimit\", l2 == NULL,\n\t\t\"failed: alloc should fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_strdup(l1, level 2)\\n\");\n\tl2 = talloc_strdup(l1, \"level 2\");\n\ttorture_assert(\"memlimit\", l2 != NULL,\n\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_free(l2)\\n\");\n\ttalloc_free(l2);\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_size(NULL, 2048)\\n\");\n\tl2 = talloc_size(NULL, 2048);\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_steal(l1, l2)\\n\");\n\ttalloc_steal(l1, l2);\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_strdup(l2, level 3)\\n\");\n\tl3 = talloc_strdup(l2, \"level 3\");\n\ttorture_assert(\"memlimit\", l3 == NULL,\n\t\t\"failed: alloc should fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_free(l2)\\n\");\n\ttalloc_free(l2);\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_strdup(NULL, level 2)\\n\");\n\tl2 = talloc_strdup(NULL, \"level 2\");\n\ttalloc_steal(l1, l2);\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_strdup(l2, level 3)\\n\");\n\tl3 = talloc_strdup(l2, \"level 3\");\n\ttorture_assert(\"memlimit\", l3 != NULL,\n\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_set_memlimit(l3, 1024)\\n\");\n\ttorture_assert(\"memlimit\", talloc_set_memlimit(l3, 1024) == 0,\n\t\t\"failed: setting memlimit should never fail\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_strdup(l3, level 4)\\n\");\n\tl4 = talloc_strdup(l3, \"level 4\");\n\ttorture_assert(\"memlimit\", l4 != NULL,\n\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_set_memlimit(l4, 512)\\n\");\n\ttorture_assert(\"memlimit\", talloc_set_memlimit(l4, 512) == 0,\n\t\t\"failed: setting memlimit should never fail\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_strdup(l4, level 5)\\n\");\n\tl5 = talloc_strdup(l4, \"level 5\");\n\ttorture_assert(\"memlimit\", l5 != NULL,\n\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_realloc(NULL, l5, char, 600)\\n\");\n\tt = talloc_realloc(NULL, l5, char, 600);\n\ttorture_assert(\"memlimit\", t == NULL,\n\t\t\"failed: alloc should fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_realloc(NULL, l5, char, 5)\\n\");\n\tl5 = talloc_realloc(NULL, l5, char, 5);\n\ttorture_assert(\"memlimit\", l5 != NULL,\n\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_strdup(l3, level 4)\\n\");\n\tl4 = talloc_strdup(l3, \"level 4\");\n\ttorture_assert(\"memlimit\", l4 != NULL,\n\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_set_memlimit(l4, 512)\\n\");\n\ttorture_assert(\"memlimit\", talloc_set_memlimit(l4, 512) == 0,\n\t\t\"failed: setting memlimit should never fail\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_strdup(l4, level 5)\\n\");\n\tl5 = talloc_strdup(l4, \"level 5\");\n\ttorture_assert(\"memlimit\", l5 != NULL,\n\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== Make new temp context and steal l5\\n\");\n\tt = talloc_new(root);\n\ttalloc_steal(t, l5);\n\n\ttalloc_report_full(root, stdout);\n\n\tprintf(\"==== talloc_size(t, 2048)\\n\");\n\tl1 = talloc_size(t, 2048);\n\ttorture_assert(\"memlimit\", l1 != NULL,\n\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(root, stdout);\n\ttalloc_free(root);\n\n\t/* Test memlimits with pools. */\n\tprintf(\"==== talloc_pool(NULL, 10*1024)\\n\");\n\tpool = talloc_pool(NULL, 10*1024);\n\ttorture_assert(\"memlimit\", pool != NULL,\n\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\tprintf(\"==== talloc_set_memlimit(pool, 10*1024)\\n\");\n\ttalloc_set_memlimit(pool, 10*1024);\n\tfor (i = 0; i < 9; i++) {\n\t\tprintf(\"==== talloc_size(pool, 1024) %i/10\\n\", i + 1);\n\t\tl1 = talloc_size(pool, 1024);\n\t\ttorture_assert(\"memlimit\", l1 != NULL,\n\t\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\t\ttalloc_report_full(pool, stdout);\n\t}\n\t/* The next alloc should fail. */\n\tprintf(\"==== talloc_size(pool, 1024) 10/10\\n\");\n\tl2 = talloc_size(pool, 1024);\n\ttorture_assert(\"memlimit\", l2 == NULL,\n\t\t\t\"failed: alloc should fail due to memory limit\\n\");\n\n\ttalloc_report_full(pool, stdout);\n\n\t/* Moving one of the children shouldn't change the limit,\n\t   as it's still inside the pool. */\n\n\tprintf(\"==== talloc_new(NULL)\\n\");\n\troot = talloc_new(NULL);\n\n\tprintf(\"==== talloc_steal(root, l1)\\n\");\n\ttalloc_steal(root, l1);\n\n\tprintf(\"==== talloc_size(pool, 1024)\\n\");\n\tl2 = talloc_size(pool, 1024);\n\ttorture_assert(\"memlimit\", l2 == NULL,\n\t\t\t\"failed: alloc should fail due to memory limit\\n\");\n\n\tprintf(\"==== talloc_free_children(pool)\\n\");\n\ttalloc_free(l1);\n\ttalloc_free_children(pool);\n\n\tprintf(\"==== talloc_size(pool, 1024)\\n\");\n\tl1 = talloc_size(pool, 1024);\n\n\t/* try reallocs of increasing size */\n\tfor (i = 1; i < 9; i++) {\n\t\tprintf(\"==== talloc_realloc_size(NULL, l1, %i*1024) %i/10\\n\", i, i + 1);\n\t\tl1 = talloc_realloc_size(NULL, l1, i*1024);\n\t\ttorture_assert(\"memlimit\", l1 != NULL,\n\t\t\t\"failed: realloc should not fail due to memory limit\\n\");\n\t\ttalloc_report_full(pool, stdout);\n\t}\n\t/* The next alloc should fail. */\n\tprintf(\"==== talloc_realloc_size(NULL, l1, 10*1024) 10/10\\n\");\n\tl2 = talloc_realloc_size(NULL, l1, 10*1024);\n\ttorture_assert(\"memlimit\", l2 == NULL,\n\t\t\t\"failed: realloc should fail due to memory limit\\n\");\n\n\t/* Increase the memlimit */\n\tprintf(\"==== talloc_set_memlimit(pool, 11*1024)\\n\");\n\ttalloc_set_memlimit(pool, 11*1024);\n\n\t/* The final realloc should still fail\n\t   as the entire realloced chunk needs to be moved out of the pool */\n\tprintf(\"==== talloc_realloc_size(NULL, l1, 10*1024) 10/10\\n\");\n\tl2 = talloc_realloc_size(NULL, l1, 10*1024);\n\ttorture_assert(\"memlimit\", l2 == NULL,\n\t\t\t\"failed: realloc should fail due to memory limit\\n\");\n\n\ttalloc_report_full(pool, stdout);\n\n\tprintf(\"==== talloc_set_memlimit(pool, 21*1024)\\n\");\n\ttalloc_set_memlimit(pool, 21*1024);\n\n\t/* There's now sufficient space to move the chunk out of the pool */\n\tprintf(\"==== talloc_realloc_size(NULL, l1, 10*1024) 10/10\\n\");\n\tl2 = talloc_realloc_size(NULL, l1, 10*1024);\n\ttorture_assert(\"memlimit\", l2 != NULL,\n\t\t\t\"failed: realloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(pool, stdout);\n\n\t/* ...which should mean smaller allocations can now occur within the pool */\n\tprintf(\"==== talloc_size(pool, 9*1024)\\n\");\n\tl1 = talloc_size(pool, 9*1024);\n\ttorture_assert(\"memlimit\", l1 != NULL,\n\t\t\t\"failed: new allocations should be allowed in the pool\\n\");\n\n\ttalloc_report_full(pool, stdout);\n\n\t/* But reallocs bigger than the pool will still fail */\n\tprintf(\"==== talloc_realloc_size(NULL, l1, 10*1024)\\n\");\n\tl2 = talloc_realloc_size(NULL, l1, 10*1024);\n\ttorture_assert(\"memlimit\", l2 == NULL,\n\t\t\t\"failed: realloc should fail due to memory limit\\n\");\n\n\ttalloc_report_full(pool, stdout);\n\n\t/* ..as well as allocs */\n\tprintf(\"==== talloc_size(pool, 1024)\\n\");\n\tl1 = talloc_size(pool, 1024);\n\ttorture_assert(\"memlimit\", l1 == NULL,\n\t\t\t\"failed: alloc should fail due to memory limit\\n\");\n\n\ttalloc_report_full(pool, stdout);\n\n\tprintf(\"==== talloc_free_children(pool)\\n\");\n\ttalloc_free_children(pool);\n\n\tprintf(\"==== talloc_set_memlimit(pool, 1024)\\n\");\n\ttalloc_set_memlimit(pool, 1024);\n\n\t/* We should still be able to allocate up to the pool limit\n\t   because the memlimit only applies to new heap allocations */\n\tprintf(\"==== talloc_size(pool, 9*1024)\\n\");\n\tl1 = talloc_size(pool, 9*1024);\n\ttorture_assert(\"memlimit\", l1 != NULL,\n\t\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(pool, stdout);\n\n\tl1 = talloc_size(pool, 1024);\n\ttorture_assert(\"memlimit\", l1 == NULL,\n\t\t\t\"failed: alloc should fail due to memory limit\\n\");\n\n\ttalloc_report_full(pool, stdout);\n\n\tprintf(\"==== talloc_free_children(pool)\\n\");\n\ttalloc_free_children(pool);\n\n\tprintf(\"==== talloc_set_memlimit(pool, 10*1024)\\n\");\n\ttalloc_set_memlimit(pool, 10*1024);\n\n\tprintf(\"==== talloc_size(pool, 1024)\\n\");\n\tl1 = talloc_size(pool, 1024);\n\ttorture_assert(\"memlimit\", l1 != NULL,\n\t\t\t\"failed: alloc should not fail due to memory limit\\n\");\n\n\ttalloc_report_full(pool, stdout);\n\n\ttalloc_free(pool);\n\ttalloc_free(root);\n\tprintf(\"success: memlimit\\n\");\n\n\treturn true;\n}\n\n#ifdef HAVE_PTHREAD\n\n#define NUM_THREADS 100\n\n/* Sync variables. */\nstatic pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;\nstatic pthread_cond_t condvar = PTHREAD_COND_INITIALIZER;\nstatic void *intermediate_ptr;\n\n/* Subthread. */\nstatic void *thread_fn(void *arg)\n{\n\tint ret;\n\tconst char *ctx_name = (const char *)arg;\n\tvoid *sub_ctx = NULL;\n\t/*\n\t * Do stuff that creates a new talloc hierarchy in\n\t * this thread.\n\t */\n\tvoid *top_ctx = talloc_named_const(NULL, 0, \"top\");\n\tif (top_ctx == NULL) {\n\t\treturn NULL;\n\t}\n\tsub_ctx = talloc_named_const(top_ctx, 100, ctx_name);\n\tif (sub_ctx == NULL) {\n\t\treturn NULL;\n\t}\n\n\t/*\n\t * Now transfer a pointer from our hierarchy\n\t * onto the intermediate ptr.\n\t */\n\tret = pthread_mutex_lock(&mtx);\n\tif (ret != 0) {\n\t\ttalloc_free(top_ctx);\n\t\treturn NULL;\n\t}\n\t/* Wait for intermediate_ptr to be free. */\n\twhile (intermediate_ptr != NULL) {\n\t\tret = pthread_cond_wait(&condvar, &mtx);\n\t\tif (ret != 0) {\n\t\t\ttalloc_free(top_ctx);\n\t\t\tret = pthread_mutex_unlock(&mtx);\n\t\t\tassert(ret == 0);\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\t/* and move our memory onto it from our toplevel hierarchy. */\n\tintermediate_ptr = talloc_move(NULL, &sub_ctx);\n\n\t/* Tell the main thread it's ready for pickup. */\n\tpthread_cond_broadcast(&condvar);\n\tret = pthread_mutex_unlock(&mtx);\n\tassert(ret == 0);\n\n\ttalloc_free(top_ctx);\n\treturn NULL;\n}\n\n/* Main thread. */\nstatic bool test_pthread_talloc_passing(void)\n{\n\tint i;\n\tint ret;\n\tchar str_array[NUM_THREADS][20];\n\tpthread_t thread_id;\n\tvoid *mem_ctx;\n\n\t/*\n\t * Important ! Null tracking breaks threaded talloc.\n\t * It *must* be turned off.\n\t */\n\ttalloc_disable_null_tracking();\n\n\tprintf(\"test: pthread_talloc_passing\\n# PTHREAD TALLOC PASSING\\n\");\n\n\t/* Main thread toplevel context. */\n\tmem_ctx = talloc_named_const(NULL, 0, \"toplevel\");\n\tif (mem_ctx == NULL) {\n\t\tprintf(\"failed to create toplevel context\\n\");\n\t\treturn false;\n\t}\n\n\t/*\n\t * Spin off NUM_THREADS threads.\n\t * They will use their own toplevel contexts.\n\t */\n\tfor (i = 0; i < NUM_THREADS; i++) {\n\t\tret = snprintf(str_array[i],\n\t\t\t       20,\n\t\t\t       \"thread:%d\",\n\t\t\t       i);\n\t\tif (ret < 0) {\n\t\t\tprintf(\"snprintf %d failed\\n\", i);\n\t\t\treturn false;\n\t\t}\n\t\tret = pthread_create(&thread_id,\n\t\t\t\tNULL,\n\t\t\t\tthread_fn,\n\t\t\t\tstr_array[i]);\n\t\tif (ret != 0) {\n\t\t\tprintf(\"failed to create thread %d (%d)\\n\", i, ret);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprintf(\"Created %d threads\\n\", NUM_THREADS);\n\n\t/* Now wait for NUM_THREADS transfers of the talloc'ed memory. */\n\tfor (i = 0; i < NUM_THREADS; i++) {\n\t\tret = pthread_mutex_lock(&mtx);\n\t\tif (ret != 0) {\n\t\t\tprintf(\"pthread_mutex_lock %d failed (%d)\\n\", i, ret);\n\t\t\ttalloc_free(mem_ctx);\n\t\t\treturn false;\n\t\t}\n\n\t\t/* Wait for intermediate_ptr to have our data. */\n\t\twhile (intermediate_ptr == NULL) {\n\t\t\tret = pthread_cond_wait(&condvar, &mtx);\n\t\t\tif (ret != 0) {\n\t\t\t\tprintf(\"pthread_cond_wait %d failed (%d)\\n\", i,\n\t\t\t\t\tret);\n\t\t\t\ttalloc_free(mem_ctx);\n\t\t\t\tret = pthread_mutex_unlock(&mtx);\n\t\t\t\tassert(ret == 0);\n\t\t\t}\n\t\t}\n\n\t\t/* and move it onto our toplevel hierarchy. */\n\t\t(void)talloc_move(mem_ctx, &intermediate_ptr);\n\n\t\t/* Tell the sub-threads we're ready for another. */\n\t\tpthread_cond_broadcast(&condvar);\n\t\tret = pthread_mutex_unlock(&mtx);\n\t\tassert(ret == 0);\n\t}\n\n\tCHECK_SIZE(\"pthread_talloc_passing\", mem_ctx, NUM_THREADS * 100);\n#if 1\n\t/* Dump the hierarchy. */\n\ttalloc_report(mem_ctx, stdout);\n#endif\n\ttalloc_free(mem_ctx);\n\tprintf(\"success: pthread_talloc_passing\\n\");\n\treturn true;\n}\n#endif\n\nstatic void test_magic_protection_abort(const char *reason)\n{\n\t/* exit with errcode 42 to communicate successful test to the parent process */\n\tif (strcmp(reason, \"Bad talloc magic value - unknown value\") == 0) {\n\t\t_exit(42);\n\t} else {\n\t\tprintf(\"talloc aborted for an unexpected reason\\n\");\n\t}\n}\n\nstatic int test_magic_protection_destructor(int *ptr)\n{\n\t_exit(404); /* Not 42 */\n}\n\nstatic bool test_magic_protection(void)\n{\n\tvoid *pool = talloc_pool(NULL, 1024);\n\tint *p1, *p2;\n\tpid_t pid;\n\tint exit_status;\n\n\tprintf(\"test: magic_protection\\n\");\n\tp1 = talloc(pool, int);\n\tp2 = talloc(pool, int);\n\n\t/* To avoid complaints from the compiler assign values to the p1 & p2. */\n\t*p1 = 6;\n\t*p2 = 9;\n\n\tpid = fork();\n\tif (pid == 0) {\n\t\ttalloc_set_abort_fn(test_magic_protection_abort);\n\t\ttalloc_set_destructor(p2, test_magic_protection_destructor);\n\n\t\t/*\n\t\t * Simulate a security attack\n\t\t * by triggering a buffer overflow in memset to overwrite the\n\t\t * constructor in the next pool chunk.\n\t\t *\n\t\t * Real attacks would attempt to set a real destructor.\n\t\t */\n\t\tBURN_PTR_SIZE(p1, 32);\n\n\t\t/* Then the attack takes effect when the memory's freed. */\n\t\ttalloc_free(pool);\n\n\t\t/* Never reached. Make compilers happy */\n\t\treturn true;\n\t}\n\n\twhile (wait(&exit_status) != pid);\n\n\ttalloc_free(pool); /* make ASAN happy */\n\n\tif (!WIFEXITED(exit_status)) {\n\t\tprintf(\"Child exited through unexpected abnormal means\\n\");\n\t\treturn false;\n\t}\n\tif (WEXITSTATUS(exit_status) != 42) {\n\t\tprintf(\"Child exited with wrong exit status\\n\");\n\t\treturn false;\n\t}\n\tif (WIFSIGNALED(exit_status)) {\n\t\tprintf(\"Child received unexpected signal\\n\");\n\t\treturn false;\n\t}\n\n\tprintf(\"success: magic_protection\\n\");\n\treturn true;\n}\n\nstatic void test_magic_free_protection_abort(const char *reason)\n{\n\t/* exit with errcode 42 to communicate successful test to the parent process */\n\tif (strcmp(reason, \"Bad talloc magic value - access after free\") == 0) {\n\t\t_exit(42);\n\t}\n\t/* not 42 */\n\t_exit(404);\n}\n\nstatic bool test_magic_free_protection(void)\n{\n\tvoid *pool = talloc_pool(NULL, 1024);\n\tint *p1, *p2, *p3;\n\tpid_t pid;\n\tint exit_status;\n\n\tprintf(\"test: magic_free_protection\\n\");\n\tp1 = talloc(pool, int);\n\tp2 = talloc(pool, int);\n\n\t/* To avoid complaints from the compiler assign values to the p1 & p2. */\n\t*p1 = 6;\n\t*p2 = 9;\n\n\tp3 = talloc_realloc(pool, p2, int, 2048);\n\ttorture_assert(\"pool realloc 2048\",\n\t\t       p3 != p2,\n\t\t       \"failed: pointer not changed\");\n\n\t/*\n\t * Now access the memory in the pool after the realloc().  It\n\t * should be marked as free, so use of the old pointer should\n\t * trigger the abort function\n\t */\n\tpid = fork();\n\tif (pid == 0) {\n\t\ttalloc_set_abort_fn(test_magic_free_protection_abort);\n\n\t\ttalloc_get_name(p2);\n\n\t\t/* Never reached. Make compilers happy */\n\t\treturn true;\n\t}\n\n\twhile (wait(&exit_status) != pid);\n\n\tif (!WIFEXITED(exit_status)) {\n\t\tprintf(\"Child exited through unexpected abnormal means\\n\");\n\t\treturn false;\n\t}\n\tif (WEXITSTATUS(exit_status) != 42) {\n\t\tprintf(\"Child exited with wrong exit status\\n\");\n\t\treturn false;\n\t}\n\tif (WIFSIGNALED(exit_status)) {\n\t\tprintf(\"Child received unexpected signal\\n\");\n\t\treturn false;\n\t}\n\n\ttalloc_free(pool);\n\n\tprintf(\"success: magic_free_protection\\n\");\n\treturn true;\n}\n\nstatic void test_reset(void)\n{\n\ttalloc_set_log_fn(test_log_stdout);\n\ttest_abort_stop();\n\ttalloc_disable_null_tracking();\n\ttalloc_enable_null_tracking_no_autofree();\n}\n\nbool torture_local_talloc(struct torture_context *tctx)\n{\n\tbool ret = true;\n\n\tsetlinebuf(stdout);\n\n\ttest_reset();\n\tret &= test_pooled_object();\n\ttest_reset();\n\tret &= test_pool_nest();\n\ttest_reset();\n\tret &= test_ref1();\n\ttest_reset();\n\tret &= test_ref2();\n\ttest_reset();\n\tret &= test_ref3();\n\ttest_reset();\n\tret &= test_ref4();\n\ttest_reset();\n\tret &= test_unlink1();\n\ttest_reset();\n\tret &= test_misc();\n\ttest_reset();\n\tret &= test_realloc();\n\ttest_reset();\n\tret &= test_realloc_child();\n\ttest_reset();\n\tret &= test_steal();\n\ttest_reset();\n\tret &= test_move();\n\ttest_reset();\n\tret &= test_unref_reparent();\n\ttest_reset();\n\tret &= test_realloc_fn();\n\ttest_reset();\n\tret &= test_type();\n\ttest_reset();\n\tret &= test_lifeless();\n\ttest_reset();\n\tret &= test_loop();\n\ttest_reset();\n\tret &= test_free_parent_deny_child();\n\ttest_reset();\n\tret &= test_realloc_on_destructor_parent();\n\ttest_reset();\n\tret &= test_free_parent_reparent_child();\n\ttest_reset();\n\tret &= test_free_parent_reparent_child_in_pool();\n\ttest_reset();\n\tret &= test_talloc_ptrtype();\n\ttest_reset();\n\tret &= test_talloc_free_in_destructor();\n\ttest_reset();\n\tret &= test_pool();\n\ttest_reset();\n\tret &= test_pool_steal();\n\ttest_reset();\n\tret &= test_free_ref_null_context();\n\ttest_reset();\n\tret &= test_rusty();\n\ttest_reset();\n\tret &= test_free_children();\n\ttest_reset();\n\tret &= test_memlimit();\n#ifdef HAVE_PTHREAD\n\ttest_reset();\n\tret &= test_pthread_talloc_passing();\n#endif\n\n\n\tif (ret) {\n\t\ttest_reset();\n\t\tret &= test_speed();\n\t}\n\ttest_reset();\n\tret &= test_autofree();\n\ttest_reset();\n\tret &= test_magic_protection();\n\ttest_reset();\n\tret &= test_magic_free_protection();\n\n\ttest_reset();\n\ttalloc_disable_null_tracking();\n\treturn ret;\n}\n"},
                          "roles": ["analysisTarget"]},
                         {"location": {"uri": "../../talloc.h",
                                       "uriBaseId": "PWD"},
                          "sourceLanguage": "c",
                          "contents": {"text": "#ifndef _TALLOC_H_\n#define _TALLOC_H_\n/*\n   Unix SMB/CIFS implementation.\n   Samba temporary memory allocation functions\n\n   Copyright (C) Andrew Tridgell 2004-2005\n   Copyright (C) Stefan Metzmacher 2006\n\n     ** NOTE! The following LGPL license applies to the talloc\n     ** library. This does NOT imply that all of Samba is released\n     ** under the LGPL\n\n   This library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 3 of the License, or (at your option) any later version.\n\n   This library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with this library; if not, see <http://www.gnu.org/licenses/>.\n*/\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <stdarg.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* for old gcc releases that don't have the feature test macro __has_attribute */\n#ifndef __has_attribute\n#define __has_attribute(x) 0\n#endif\n\n#ifndef _PUBLIC_\n#if __has_attribute(visibility)\n#define _PUBLIC_ __attribute__((visibility(\"default\")))\n#else\n#define _PUBLIC_\n#endif\n#endif\n\n/**\n * @defgroup talloc The talloc API\n *\n * talloc is a hierarchical, reference counted memory pool system with\n * destructors. It is the core memory allocator used in Samba.\n *\n * @{\n */\n\n#define TALLOC_VERSION_MAJOR 2\n#define TALLOC_VERSION_MINOR 4\n\n_PUBLIC_ int talloc_version_major(void);\n_PUBLIC_ int talloc_version_minor(void);\n/* This is mostly useful only for testing */\n_PUBLIC_ int talloc_test_get_magic(void);\n\n/**\n * @brief Define a talloc parent type\n *\n * As talloc is a hierarchial memory allocator, every talloc chunk is a\n * potential parent to other talloc chunks. So defining a separate type for a\n * talloc chunk is not strictly necessary. TALLOC_CTX is defined nevertheless,\n * as it provides an indicator for function arguments. You will frequently\n * write code like\n *\n * @code\n *      struct foo *foo_create(TALLOC_CTX *mem_ctx)\n *      {\n *              struct foo *result;\n *              result = talloc(mem_ctx, struct foo);\n *              if (result == NULL) return NULL;\n *                      ... initialize foo ...\n *              return result;\n *      }\n * @endcode\n *\n * In this type of allocating functions it is handy to have a general\n * TALLOC_CTX type to indicate which parent to put allocated structures on.\n */\ntypedef void TALLOC_CTX;\n\n/*\n  this uses a little trick to allow __LINE__ to be stringified\n*/\n#ifndef __location__\n#define __TALLOC_STRING_LINE1__(s)    #s\n#define __TALLOC_STRING_LINE2__(s)   __TALLOC_STRING_LINE1__(s)\n#define __TALLOC_STRING_LINE3__  __TALLOC_STRING_LINE2__(__LINE__)\n#define __location__ __FILE__ \":\" __TALLOC_STRING_LINE3__\n#endif\n\n#ifndef TALLOC_DEPRECATED\n#define TALLOC_DEPRECATED 0\n#endif\n\n#ifndef PRINTF_ATTRIBUTE\n#if __has_attribute(format) || (__GNUC__ >= 3)\n/** Use gcc attribute to check printf fns.  a1 is the 1-based index of\n * the parameter containing the format, and a2 the index of the first\n * argument. Note that some gcc 2.x versions don't handle this\n * properly **/\n#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))\n#else\n#define PRINTF_ATTRIBUTE(a1, a2)\n#endif\n#endif\n\n#ifndef _DEPRECATED_\n#if __has_attribute(deprecated) || (__GNUC__ >= 3)\n#define _DEPRECATED_ __attribute__ ((deprecated))\n#else\n#define _DEPRECATED_\n#endif\n#endif\n#ifdef DOXYGEN\n\n/**\n * @brief Create a new talloc context.\n *\n * The talloc() macro is the core of the talloc library. It takes a memory\n * context and a type, and returns a pointer to a new area of memory of the\n * given type.\n *\n * The returned pointer is itself a talloc context, so you can use it as the\n * context argument to more calls to talloc if you wish.\n *\n * The returned pointer is a \"child\" of the supplied context. This means that if\n * you talloc_free() the context then the new child disappears as well.\n * Alternatively you can free just the child.\n *\n * @param[in]  ctx      A talloc context to create a new reference on or NULL to\n *                      create a new top level context.\n *\n * @param[in]  type     The type of memory to allocate.\n *\n * @return              A type casted talloc context or NULL on error.\n *\n * @code\n *      unsigned int *a, *b;\n *\n *      a = talloc(NULL, unsigned int);\n *      b = talloc(a, unsigned int);\n * @endcode\n *\n * @see talloc_zero\n * @see talloc_array\n * @see talloc_steal\n * @see talloc_free\n */\n_PUBLIC_ void *talloc(const void *ctx, #type);\n#else\n#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)\n_PUBLIC_ void *_talloc(const void *context, size_t size);\n#endif\n\n/**\n * @brief Create a new top level talloc context.\n *\n * This function creates a zero length named talloc context as a top level\n * context. It is equivalent to:\n *\n * @code\n *      talloc_named(NULL, 0, fmt, ...);\n * @endcode\n * @param[in]  fmt      Format string for the name.\n *\n * @param[in]  ...      Additional printf-style arguments.\n *\n * @return              The allocated memory chunk, NULL on error.\n *\n * @see talloc_named()\n */\n_PUBLIC_ void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);\n\n#ifdef DOXYGEN\n/**\n * @brief Free a chunk of talloc memory.\n *\n * The talloc_free() function frees a piece of talloc memory, and all its\n * children. You can call talloc_free() on any pointer returned by\n * talloc().\n *\n * The return value of talloc_free() indicates success or failure, with 0\n * returned for success and -1 for failure. A possible failure condition\n * is if the pointer had a destructor attached to it and the destructor\n * returned -1. See talloc_set_destructor() for details on\n * destructors. Likewise, if \"ptr\" is NULL, then the function will make\n * no modifications and return -1.\n *\n * From version 2.0 and onwards, as a special case, talloc_free() is\n * refused on pointers that have more than one parent associated, as talloc\n * would have no way of knowing which parent should be removed. This is\n * different from older versions in the sense that always the reference to\n * the most recently established parent has been destroyed. Hence to free a\n * pointer that has more than one parent please use talloc_unlink().\n *\n * To help you find problems in your code caused by this behaviour, if\n * you do try and free a pointer with more than one parent then the\n * talloc logging function will be called to give output like this:\n *\n * @code\n *   ERROR: talloc_free with references at some_dir/source/foo.c:123\n *     reference at some_dir/source/other.c:325\n *     reference at some_dir/source/third.c:121\n * @endcode\n *\n * Please see the documentation for talloc_set_log_fn() and\n * talloc_set_log_stderr() for more information on talloc logging\n * functions.\n *\n * If <code>TALLOC_FREE_FILL</code> environment variable is set,\n * the memory occupied by the context is filled with the value of this variable.\n * The value should be a numeric representation of the character you want to\n * use.\n *\n * talloc_free() operates recursively on its children.\n *\n * @param[in]  ptr      The chunk to be freed.\n *\n * @return              Returns 0 on success and -1 on error. A possible\n *                      failure condition is if the pointer had a destructor\n *                      attached to it and the destructor returned -1. Likewise,\n *                      if \"ptr\" is NULL, then the function will make no\n *                      modifications and returns -1.\n *\n * Example:\n * @code\n *      unsigned int *a, *b;\n *      a = talloc(NULL, unsigned int);\n *      b = talloc(a, unsigned int);\n *\n *      talloc_free(a); // Frees a and b\n * @endcode\n *\n * @see talloc_set_destructor()\n * @see talloc_unlink()\n */\n_PUBLIC_ int talloc_free(void *ptr);\n#else\n#define talloc_free(ctx) _talloc_free(ctx, __location__)\n_PUBLIC_ int _talloc_free(void *ptr, const char *location);\n#endif\n\n/**\n * @brief Free a talloc chunk's children.\n *\n * The function walks along the list of all children of a talloc context and\n * talloc_free()s only the children, not the context itself.\n *\n * A NULL argument is handled as no-op.\n *\n * @param[in]  ptr      The chunk that you want to free the children of\n *                      (NULL is allowed too)\n */\n_PUBLIC_ void talloc_free_children(void *ptr);\n\n#ifdef DOXYGEN\n/**\n * @brief Assign a destructor function to be called when a chunk is freed.\n *\n * The function talloc_set_destructor() sets the \"destructor\" for the pointer\n * \"ptr\". A destructor is a function that is called when the memory used by a\n * pointer is about to be released. The destructor receives the pointer as an\n * argument, and should return 0 for success and -1 for failure.\n *\n * The destructor can do anything it wants to, including freeing other pieces\n * of memory. A common use for destructors is to clean up operating system\n * resources (such as open file descriptors) contained in the structure the\n * destructor is placed on.\n *\n * You can only place one destructor on a pointer. If you need more than one\n * destructor then you can create a zero-length child of the pointer and place\n * an additional destructor on that.\n *\n * To remove a destructor call talloc_set_destructor() with NULL for the\n * destructor.\n *\n * If your destructor attempts to talloc_free() the pointer that it is the\n * destructor for then talloc_free() will return -1 and the free will be\n * ignored. This would be a pointless operation anyway, as the destructor is\n * only called when the memory is just about to go away.\n *\n * @param[in]  ptr      The talloc chunk to add a destructor to.\n *\n * @param[in]  destructor  The destructor function to be called. NULL to remove\n *                         it.\n *\n * Example:\n * @code\n *      static int destroy_fd(int *fd) {\n *              close(*fd);\n *              return 0;\n *      }\n *\n *      int *open_file(const char *filename) {\n *              int *fd = talloc(NULL, int);\n *              *fd = open(filename, O_RDONLY);\n *              if (*fd < 0) {\n *                      talloc_free(fd);\n *                      return NULL;\n *              }\n *              // Whenever they free this, we close the file.\n *              talloc_set_destructor(fd, destroy_fd);\n *              return fd;\n *      }\n * @endcode\n *\n * @see talloc()\n * @see talloc_free()\n */\n_PUBLIC_ void talloc_set_destructor(const void *ptr, int (*destructor)(void *));\n\n/**\n * @brief Change a talloc chunk's parent.\n *\n * The talloc_steal() function changes the parent context of a talloc\n * pointer. It is typically used when the context that the pointer is\n * currently a child of is going to be freed and you wish to keep the\n * memory for a longer time.\n *\n * To make the changed hierarchy less error-prone, you might consider to use\n * talloc_move().\n *\n * If you try and call talloc_steal() on a pointer that has more than one\n * parent then the result is ambiguous. Talloc will choose to remove the\n * parent that is currently indicated by talloc_parent() and replace it with\n * the chosen parent. You will also get a message like this via the talloc\n * logging functions:\n *\n * @code\n *   WARNING: talloc_steal with references at some_dir/source/foo.c:123\n *     reference at some_dir/source/other.c:325\n *     reference at some_dir/source/third.c:121\n * @endcode\n *\n * To unambiguously change the parent of a pointer please see the function\n * talloc_reparent(). See the talloc_set_log_fn() documentation for more\n * information on talloc logging.\n *\n * @param[in]  new_ctx  The new parent context.\n *\n * @param[in]  ptr      The talloc chunk to move.\n *\n * @return              Returns the pointer that you pass it. It does not have\n *                      any failure modes.\n *\n * @note It is possible to produce loops in the parent/child relationship\n * if you are not careful with talloc_steal(). No guarantees are provided\n * as to your sanity or the safety of your data if you do this.\n */\n_PUBLIC_ void *talloc_steal(const void *new_ctx, const void *ptr);\n#else /* DOXYGEN */\n/* try to make talloc_set_destructor() and talloc_steal() type safe,\n   if we have a recent gcc */\n#if (__GNUC__ >= 3)\n#define _TALLOC_TYPEOF(ptr) __typeof__(ptr)\n#define talloc_set_destructor(ptr, function)\t\t\t\t      \\\n\tdo {\t\t\t\t\t\t\t\t      \\\n\t\tint (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function);\t      \\\n\t\t_talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \\\n\t} while(0)\n/* this extremely strange macro is to avoid some braindamaged warning\n   stupidity in gcc 4.1.x */\n#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal_loc((ctx),(ptr), __location__); __talloc_steal_ret; })\n#else /* __GNUC__ >= 3 */\n#define talloc_set_destructor(ptr, function) \\\n\t_talloc_set_destructor((ptr), (int (*)(void *))(function))\n#define _TALLOC_TYPEOF(ptr) void *\n#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal_loc((ctx),(ptr), __location__)\n#endif /* __GNUC__ >= 3 */\n_PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*_destructor)(void *));\n_PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location);\n#endif /* DOXYGEN */\n\n/**\n * @brief Assign a name to a talloc chunk.\n *\n * Each talloc pointer has a \"name\". The name is used principally for\n * debugging purposes, although it is also possible to set and get the name on\n * a pointer in as a way of \"marking\" pointers in your code.\n *\n * The main use for names on pointer is for \"talloc reports\". See\n * talloc_report() and talloc_report_full() for details. Also see\n * talloc_enable_leak_report() and talloc_enable_leak_report_full().\n *\n * The talloc_set_name() function allocates memory as a child of the\n * pointer. It is logically equivalent to:\n *\n * @code\n *      talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...));\n * @endcode\n *\n * @param[in]  ptr      The talloc chunk to assign a name to.\n *\n * @param[in]  fmt      Format string for the name.\n *\n * @param[in]  ...      Add printf-style additional arguments.\n *\n * @return              The assigned name, NULL on error.\n *\n * @note Multiple calls to talloc_set_name() will allocate more memory without\n * releasing the name. All of the memory is released when the ptr is freed\n * using talloc_free().\n */\n_PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);\n\n#ifdef DOXYGEN\n/**\n * @brief Change a talloc chunk's parent.\n *\n * This function has the same effect as talloc_steal(), and additionally sets\n * the source pointer to NULL. You would use it like this:\n *\n * @code\n *      struct foo *X = talloc(tmp_ctx, struct foo);\n *      struct foo *Y;\n *      Y = talloc_move(new_ctx, &X);\n * @endcode\n *\n * @param[in]  new_ctx  The new parent context.\n *\n * @param[in]  pptr     Pointer to a pointer to the talloc chunk to move.\n *\n * @return              The pointer to the talloc chunk that moved.\n *                      It does not have any failure modes.\n *\n */\n_PUBLIC_ void *talloc_move(const void *new_ctx, void **pptr);\n#else\n#define talloc_move(ctx, pptr) (_TALLOC_TYPEOF(*(pptr)))_talloc_move((ctx),(void *)(pptr))\n_PUBLIC_ void *_talloc_move(const void *new_ctx, const void *pptr);\n#endif\n\n/**\n * @brief Assign a name to a talloc chunk.\n *\n * The function is just like talloc_set_name(), but it takes a string constant,\n * and is much faster. It is extensively used by the \"auto naming\" macros, such\n * as talloc_p().\n *\n * This function does not allocate any memory. It just copies the supplied\n * pointer into the internal representation of the talloc ptr. This means you\n * must not pass a name pointer to memory that will disappear before the ptr\n * is freed with talloc_free().\n *\n * @param[in]  ptr      The talloc chunk to assign a name to.\n *\n * @param[in]  name     Format string for the name.\n */\n_PUBLIC_ void talloc_set_name_const(const void *ptr, const char *name);\n\n/**\n * @brief Create a named talloc chunk.\n *\n * The talloc_named() function creates a named talloc pointer. It is\n * equivalent to:\n *\n * @code\n *      ptr = talloc_size(context, size);\n *      talloc_set_name(ptr, fmt, ....);\n * @endcode\n *\n * @param[in]  context  The talloc context to hang the result off.\n *\n * @param[in]  size     Number of char's that you want to allocate.\n *\n * @param[in]  fmt      Format string for the name.\n *\n * @param[in]  ...      Additional printf-style arguments.\n *\n * @return              The allocated memory chunk, NULL on error.\n *\n * @see talloc_set_name()\n */\n_PUBLIC_ void *talloc_named(const void *context, size_t size,\n\t\t   const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);\n\n/**\n * @brief Basic routine to allocate a chunk of memory.\n *\n * This is equivalent to:\n *\n * @code\n *      ptr = talloc_size(context, size);\n *      talloc_set_name_const(ptr, name);\n * @endcode\n *\n * @param[in]  context  The parent context.\n *\n * @param[in]  size     The number of char's that we want to allocate.\n *\n * @param[in]  name     The name the talloc block has.\n *\n * @return             The allocated memory chunk, NULL on error.\n */\n_PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char *name);\n\n#ifdef DOXYGEN\n/**\n * @brief Untyped allocation.\n *\n * The function should be used when you don't have a convenient type to pass to\n * talloc(). Unlike talloc(), it is not type safe (as it returns a void *), so\n * you are on your own for type checking.\n *\n * Best to use talloc() or talloc_array() instead.\n *\n * @param[in]  ctx     The talloc context to hang the result off.\n *\n * @param[in]  size    Number of char's that you want to allocate.\n *\n * @return             The allocated memory chunk, NULL on error.\n *\n * Example:\n * @code\n *      void *mem = talloc_size(NULL, 100);\n * @endcode\n */\n_PUBLIC_ void *talloc_size(const void *ctx, size_t size);\n#else\n#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__)\n#endif\n\n#ifdef DOXYGEN\n/**\n * @brief Allocate into a typed pointer.\n *\n * The talloc_ptrtype() macro should be used when you have a pointer and want\n * to allocate memory to point at with this pointer. When compiling with\n * gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() and\n * talloc_get_name() will return the current location in the source file and\n * not the type.\n *\n * @param[in]  ctx      The talloc context to hang the result off.\n *\n * @param[in]  type     The pointer you want to assign the result to.\n *\n * @return              The properly casted allocated memory chunk, NULL on\n *                      error.\n *\n * Example:\n * @code\n *       unsigned int *a = talloc_ptrtype(NULL, a);\n * @endcode\n */\n_PUBLIC_ void *talloc_ptrtype(const void *ctx, #type);\n#else\n#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr)))\n#endif\n\n#ifdef DOXYGEN\n/**\n * @brief Allocate a new 0-sized talloc chunk.\n *\n * This is a utility macro that creates a new memory context hanging off an\n * existing context, automatically naming it \"talloc_new: __location__\" where\n * __location__ is the source line it is called from. It is particularly\n * useful for creating a new temporary working context.\n *\n * @param[in]  ctx      The talloc parent context.\n *\n * @return              A new talloc chunk, NULL on error.\n */\n_PUBLIC_ void *talloc_new(const void *ctx);\n#else\n#define talloc_new(ctx) talloc_named_const(ctx, 0, \"talloc_new: \" __location__)\n#endif\n\n#ifdef DOXYGEN\n/**\n * @brief Allocate a 0-initizialized structure.\n *\n * The macro is equivalent to:\n *\n * @code\n *      ptr = talloc(ctx, type);\n *      if (ptr) memset(ptr, 0, sizeof(type));\n * @endcode\n *\n * @param[in]  ctx      The talloc context to hang the result off.\n *\n * @param[in]  type     The type that we want to allocate.\n *\n * @return              Pointer to a piece of memory, properly cast to 'type *',\n *                      NULL on error.\n *\n * Example:\n * @code\n *      unsigned int *a, *b;\n *      a = talloc_zero(NULL, unsigned int);\n *      b = talloc_zero(a, unsigned int);\n * @endcode\n *\n * @see talloc()\n * @see talloc_zero_size()\n * @see talloc_zero_array()\n */\n_PUBLIC_ void *talloc_zero(const void *ctx, #type);\n\n/**\n * @brief Allocate untyped, 0-initialized memory.\n *\n * @param[in]  ctx      The talloc context to hang the result off.\n *\n * @param[in]  size     Number of char's that you want to allocate.\n *\n * @return              The allocated memory chunk.\n */\n_PUBLIC_ void *talloc_zero_size(const void *ctx, size_t size);\n#else\n#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)\n#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__)\n_PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name);\n#endif\n\n/**\n * @brief Return the name of a talloc chunk.\n *\n * @param[in]  ptr      The talloc chunk.\n *\n * @return              The current name for the given talloc pointer.\n *\n * @see talloc_set_name()\n */\n_PUBLIC_ const char *talloc_get_name(const void *ptr);\n\n/**\n * @brief Verify that a talloc chunk carries a specified name.\n *\n * This function checks if a pointer has the specified name. If it does\n * then the pointer is returned.\n *\n * @param[in]  ptr       The talloc chunk to check.\n *\n * @param[in]  name      The name to check against.\n *\n * @return               The pointer if the name matches, NULL if it doesn't.\n */\n_PUBLIC_ void *talloc_check_name(const void *ptr, const char *name);\n\n/**\n * @brief Get the parent chunk of a pointer.\n *\n * @param[in]  ptr      The talloc pointer to inspect.\n *\n * @return              The talloc parent of ptr, NULL on error.\n */\n_PUBLIC_ void *talloc_parent(const void *ptr);\n\n/**\n * @brief Get a talloc chunk's parent name.\n *\n * @param[in]  ptr      The talloc pointer to inspect.\n *\n * @return              The name of ptr's parent chunk.\n */\n_PUBLIC_ const char *talloc_parent_name(const void *ptr);\n\n/**\n * @brief Get the size of a talloc chunk.\n *\n * This function lets you know the amount of memory allocated so far by\n * this context. It does NOT account for subcontext memory.\n * This can be used to calculate the size of an array.\n *\n * @param[in]  ctx      The talloc chunk.\n *\n * @return              The size of the talloc chunk.\n */\n_PUBLIC_ size_t talloc_get_size(const void *ctx);\n\n/**\n * @brief Get the total size of a talloc chunk including its children.\n *\n * The function returns the total size in bytes used by this pointer and all\n * child pointers. Mostly useful for debugging.\n *\n * Passing NULL is allowed, but it will only give a meaningful result if\n * talloc_enable_leak_report() or talloc_enable_leak_report_full() has\n * been called.\n *\n * @param[in]  ptr      The talloc chunk.\n *\n * @return              The total size.\n */\n_PUBLIC_ size_t talloc_total_size(const void *ptr);\n\n/**\n * @brief Get the number of talloc chunks hanging off a chunk.\n *\n * The talloc_total_blocks() function returns the total memory block\n * count used by this pointer and all child pointers. Mostly useful for\n * debugging.\n *\n * Passing NULL is allowed, but it will only give a meaningful result if\n * talloc_enable_leak_report() or talloc_enable_leak_report_full() has\n * been called.\n *\n * @param[in]  ptr      The talloc chunk.\n *\n * @return              The total size.\n */\n_PUBLIC_ size_t talloc_total_blocks(const void *ptr);\n\n#ifdef DOXYGEN\n/**\n * @brief Duplicate a memory area into a talloc chunk.\n *\n * The function is equivalent to:\n *\n * @code\n *      ptr = talloc_size(ctx, size);\n *      if (ptr) memcpy(ptr, p, size);\n * @endcode\n *\n * @param[in]  t        The talloc context to hang the result off.\n *\n * @param[in]  p        The memory chunk you want to duplicate.\n *\n * @param[in]  size     Number of chars that you want to copy.\n *\n * @return              The allocated memory chunk.\n *\n * @see talloc_size()\n */\n_PUBLIC_ void *talloc_memdup(const void *t, const void *p, size_t size);\n#else\n#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__)\n_PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);\n#endif\n\n#ifdef DOXYGEN\n/**\n * @brief Assign a type to a talloc chunk.\n *\n * This macro allows you to force the name of a pointer to be of a particular\n * type. This can be used in conjunction with talloc_get_type() to do type\n * checking on void* pointers.\n *\n * It is equivalent to this:\n *\n * @code\n *      talloc_set_name_const(ptr, #type)\n * @endcode\n *\n * @param[in]  ptr      The talloc chunk to assign the type to.\n *\n * @param[in]  type     The type to assign.\n */\n_PUBLIC_ void talloc_set_type(const char *ptr, #type);\n\n/**\n * @brief Get a typed pointer out of a talloc pointer.\n *\n * This macro allows you to do type checking on talloc pointers. It is\n * particularly useful for void* private pointers. It is equivalent to\n * this:\n *\n * @code\n *      (type *)talloc_check_name(ptr, #type)\n * @endcode\n *\n * @param[in]  ptr      The talloc pointer to check.\n *\n * @param[in]  type     The type to check against.\n *\n * @return              The properly casted pointer given by ptr, NULL on error.\n */\ntype *talloc_get_type(const void *ptr, #type);\n#else\n#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)\n#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)\n#endif\n\n#ifdef DOXYGEN\n/**\n * @brief Safely turn a void pointer into a typed pointer.\n *\n * This macro is used together with talloc(mem_ctx, struct foo). If you had to\n * assign the talloc chunk pointer to some void pointer variable,\n * talloc_get_type_abort() is the recommended way to convert the void\n * pointer back to a typed pointer.\n *\n * @param[in]  ptr      The void pointer to convert.\n *\n * @param[in]  type     The type that this chunk contains\n *\n * @return              The same value as ptr, type-checked and properly cast.\n */\n_PUBLIC_ void *talloc_get_type_abort(const void *ptr, #type);\n#else\n#ifdef TALLOC_GET_TYPE_ABORT_NOOP\n#define talloc_get_type_abort(ptr, type) (type *)(ptr)\n#else\n#define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__)\n#endif\n_PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location);\n#endif\n\n/**\n * @brief Find a parent context by name.\n *\n * Find a parent memory context of the current context that has the given\n * name. This can be very useful in complex programs where it may be\n * difficult to pass all information down to the level you need, but you\n * know the structure you want is a parent of another context.\n *\n * @param[in]  ctx      The talloc chunk to start from.\n *\n * @param[in]  name     The name of the parent we look for.\n *\n * @return              The memory context we are looking for, NULL if not\n *                      found.\n */\n_PUBLIC_ void *talloc_find_parent_byname(const void *ctx, const char *name);\n\n#ifdef DOXYGEN\n/**\n * @brief Find a parent context by type.\n *\n * Find a parent memory context of the current context that has the given\n * name. This can be very useful in complex programs where it may be\n * difficult to pass all information down to the level you need, but you\n * know the structure you want is a parent of another context.\n *\n * Like talloc_find_parent_byname() but takes a type, making it typesafe.\n *\n * @param[in]  ptr      The talloc chunk to start from.\n *\n * @param[in]  type     The type of the parent to look for.\n *\n * @return              The memory context we are looking for, NULL if not\n *                      found.\n */\n_PUBLIC_ void *talloc_find_parent_bytype(const void *ptr, #type);\n#else\n#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type)\n#endif\n\n/**\n * @brief Allocate a talloc pool.\n *\n * A talloc pool is a pure optimization for specific situations. In the\n * release process for Samba 3.2 we found out that we had become considerably\n * slower than Samba 3.0 was. Profiling showed that malloc(3) was a large CPU\n * consumer in benchmarks. For Samba 3.2 we have internally converted many\n * static buffers to dynamically allocated ones, so malloc(3) being beaten\n * more was no surprise. But it made us slower.\n *\n * talloc_pool() is an optimization to call malloc(3) a lot less for the use\n * pattern Samba has: The SMB protocol is mainly a request/response protocol\n * where we have to allocate a certain amount of memory per request and free\n * that after the SMB reply is sent to the client.\n *\n * talloc_pool() creates a talloc chunk that you can use as a talloc parent\n * exactly as you would use any other ::TALLOC_CTX. The difference is that\n * when you talloc a child of this pool, no malloc(3) is done. Instead, talloc\n * just increments a pointer inside the talloc_pool. This also works\n * recursively. If you use the child of the talloc pool as a parent for\n * grand-children, their memory is also taken from the talloc pool.\n *\n * If there is not enough memory in the pool to allocate the new child,\n * it will create a new talloc chunk as if the parent was a normal talloc\n * context.\n *\n * If you talloc_free() children of a talloc pool, the memory is not given\n * back to the system. Instead, free(3) is only called if the talloc_pool()\n * itself is released with talloc_free().\n *\n * The downside of a talloc pool is that if you talloc_move() a child of a\n * talloc pool to a talloc parent outside the pool, the whole pool memory is\n * not free(3)'ed until that moved chunk is also talloc_free()ed.\n *\n * @param[in]  context  The talloc context to hang the result off.\n *\n * @param[in]  size     Size of the talloc pool.\n *\n * @return              The allocated talloc pool, NULL on error.\n */\n_PUBLIC_ void *talloc_pool(const void *context, size_t size);\n\n#ifdef DOXYGEN\n/**\n * @brief Allocate a talloc object as/with an additional pool.\n *\n * This is like talloc_pool(), but's it's more flexible\n * and allows an object to be a pool for its children.\n *\n * @param[in] ctx                   The talloc context to hang the result off.\n *\n * @param[in] type                  The type that we want to allocate.\n *\n * @param[in] num_subobjects        The expected number of subobjects, which will\n *                                  be allocated within the pool. This allocates\n *                                  space for talloc_chunk headers.\n *\n * @param[in] total_subobjects_size The size that all subobjects can use in total.\n *\n *\n * @return              The allocated talloc object, NULL on error.\n */\n_PUBLIC_ void *talloc_pooled_object(const void *ctx, #type,\n\t\t\t   unsigned num_subobjects,\n\t\t\t   size_t total_subobjects_size);\n#else\n#define talloc_pooled_object(_ctx, _type, \\\n\t\t\t     _num_subobjects, \\\n\t\t\t     _total_subobjects_size) \\\n\t(_type *)_talloc_pooled_object((_ctx), sizeof(_type), #_type, \\\n\t\t\t\t\t(_num_subobjects), \\\n\t\t\t\t\t(_total_subobjects_size))\n_PUBLIC_ void *_talloc_pooled_object(const void *ctx,\n\t\t\t    size_t type_size,\n\t\t\t    const char *type_name,\n\t\t\t    unsigned num_subobjects,\n\t\t\t    size_t total_subobjects_size);\n#endif\n\n/**\n * @brief Free a talloc chunk and NULL out the pointer.\n *\n * TALLOC_FREE() frees a pointer and sets it to NULL. Use this if you want\n * immediate feedback (i.e. crash) if you use a pointer after having free'ed\n * it.\n *\n * @param[in]  ctx      The chunk to be freed.\n */\n#define TALLOC_FREE(ctx) do { if (ctx != NULL) { talloc_free(ctx); ctx=NULL; } } while(0)\n\n/* @} ******************************************************************/\n\n/**\n * \\defgroup talloc_ref The talloc reference function.\n * @ingroup talloc\n *\n * This module contains the definitions around talloc references\n *\n * @{\n */\n\n/**\n * @brief Increase the reference count of a talloc chunk.\n *\n * The talloc_increase_ref_count(ptr) function is exactly equivalent to:\n *\n * @code\n *      talloc_reference(NULL, ptr);\n * @endcode\n *\n * You can use either syntax, depending on which you think is clearer in\n * your code.\n *\n * @param[in]  ptr      The pointer to increase the reference count.\n *\n * @return              0 on success, -1 on error.\n */\n_PUBLIC_ int talloc_increase_ref_count(const void *ptr);\n\n/**\n * @brief Get the number of references to a talloc chunk.\n *\n * @param[in]  ptr      The pointer to retrieve the reference count from.\n *\n * @return              The number of references.\n */\n_PUBLIC_ size_t talloc_reference_count(const void *ptr);\n\n#ifdef DOXYGEN\n/**\n * @brief Create an additional talloc parent to a pointer.\n *\n * The talloc_reference() function makes \"context\" an additional parent of\n * ptr. Each additional reference consumes around 48 bytes of memory on intel\n * x86 platforms.\n *\n * If ptr is NULL, then the function is a no-op, and simply returns NULL.\n *\n * After creating a reference you can free it in one of the following ways:\n *\n * - you can talloc_free() any parent of the original pointer. That\n *   will reduce the number of parents of this pointer by 1, and will\n *   cause this pointer to be freed if it runs out of parents.\n *\n * - you can talloc_free() the pointer itself if it has at maximum one\n *   parent. This behaviour has been changed since the release of version\n *   2.0. Further information in the description of \"talloc_free\".\n *\n * For more control on which parent to remove, see talloc_unlink()\n * @param[in]  ctx      The additional parent.\n *\n * @param[in]  ptr      The pointer you want to create an additional parent for.\n *\n * @return              The original pointer 'ptr', NULL if talloc ran out of\n *                      memory in creating the reference.\n *\n * @warning You should try to avoid using this interface. It turns a beautiful\n *          talloc-tree into a graph. It is often really hard to debug if you\n *          screw something up by accident.\n *\n * Example:\n * @code\n *      unsigned int *a, *b, *c;\n *      a = talloc(NULL, unsigned int);\n *      b = talloc(NULL, unsigned int);\n *      c = talloc(a, unsigned int);\n *      // b also serves as a parent of c.\n *      talloc_reference(b, c);\n * @endcode\n *\n * @see talloc_unlink()\n */\n_PUBLIC_ void *talloc_reference(const void *ctx, const void *ptr);\n#else\n#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference_loc((ctx),(ptr), __location__)\n_PUBLIC_ void *_talloc_reference_loc(const void *context, const void *ptr, const char *location);\n#endif\n\n/**\n * @brief Remove a specific parent from a talloc chunk.\n *\n * The function removes a specific parent from ptr. The context passed must\n * either be a context used in talloc_reference() with this pointer, or must be\n * a direct parent of ptr.\n *\n * You can just use talloc_free() instead of talloc_unlink() if there\n * is at maximum one parent. This behaviour has been changed since the\n * release of version 2.0. Further information in the description of\n * \"talloc_free\".\n *\n * @param[in]  context  The talloc parent to remove.\n *\n * @param[in]  ptr      The talloc ptr you want to remove the parent from.\n *\n * @return              0 on success, -1 on error.\n *\n * @note If the parent has already been removed using talloc_free() then\n * this function will fail and will return -1.  Likewise, if ptr is NULL,\n * then the function will make no modifications and return -1.\n *\n * @warning You should try to avoid using this interface. It turns a beautiful\n *          talloc-tree into a graph. It is often really hard to debug if you\n *          screw something up by accident.\n *\n * Example:\n * @code\n *      unsigned int *a, *b, *c;\n *      a = talloc(NULL, unsigned int);\n *      b = talloc(NULL, unsigned int);\n *      c = talloc(a, unsigned int);\n *      // b also serves as a parent of c.\n *      talloc_reference(b, c);\n *      talloc_unlink(b, c);\n * @endcode\n */\n_PUBLIC_ int talloc_unlink(const void *context, void *ptr);\n\n/**\n * @brief Provide a talloc context that is freed at program exit.\n *\n * This is a handy utility function that returns a talloc context\n * which will be automatically freed on program exit. This can be used\n * to reduce the noise in memory leak reports.\n *\n * Never use this in code that might be used in objects loaded with\n * dlopen and unloaded with dlclose. talloc_autofree_context()\n * internally uses atexit(3). Some platforms like modern Linux handles\n * this fine, but for example FreeBSD does not deal well with dlopen()\n * and atexit() used simultaneously: dlclose() does not clean up the\n * list of atexit-handlers, so when the program exits the code that\n * was registered from within talloc_autofree_context() is gone, the\n * program crashes at exit.\n *\n * @return              A talloc context, NULL on error.\n */\n_PUBLIC_ void *talloc_autofree_context(void) _DEPRECATED_;\n\n/**\n * @brief Show the parentage of a context.\n *\n * @param[in]  context            The talloc context to look at.\n *\n * @param[in]  file               The output to use, a file, stdout or stderr.\n */\n_PUBLIC_ void talloc_show_parents(const void *context, FILE *file);\n\n/**\n * @brief Check if a context is parent of a talloc chunk.\n *\n * This checks if context is referenced in the talloc hierarchy above ptr.\n *\n * @param[in]  context  The assumed talloc context.\n *\n * @param[in]  ptr      The talloc chunk to check.\n *\n * @return              Return 1 if this is the case, 0 if not.\n */\n_PUBLIC_ int talloc_is_parent(const void *context, const void *ptr);\n\n/**\n * @brief Change the parent context of a talloc pointer.\n *\n * The function changes the parent context of a talloc pointer. It is typically\n * used when the context that the pointer is currently a child of is going to be\n * freed and you wish to keep the memory for a longer time.\n *\n * The difference between talloc_reparent() and talloc_steal() is that\n * talloc_reparent() can specify which parent you wish to change. This is\n * useful when a pointer has multiple parents via references.\n *\n * @param[in]  old_parent\n * @param[in]  new_parent\n * @param[in]  ptr\n *\n * @return              Return the pointer you passed. It does not have any\n *                      failure modes.\n */\n_PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr);\n\n/* @} ******************************************************************/\n\n/**\n * @defgroup talloc_array The talloc array functions\n * @ingroup talloc\n *\n * Talloc contains some handy helpers for handling Arrays conveniently\n *\n * @{\n */\n\n#ifdef DOXYGEN\n/**\n * @brief Allocate an array.\n *\n * The macro is equivalent to:\n *\n * @code\n *      (type *)talloc_size(ctx, sizeof(type) * count);\n * @endcode\n *\n * except that it provides integer overflow protection for the multiply,\n * returning NULL if the multiply overflows.\n *\n * @param[in]  ctx      The talloc context to hang the result off.\n *\n * @param[in]  type     The type that we want to allocate.\n *\n * @param[in]  count    The number of 'type' elements you want to allocate.\n *\n * @return              The allocated result, properly cast to 'type *', NULL on\n *                      error.\n *\n * Example:\n * @code\n *      unsigned int *a, *b;\n *      a = talloc_zero(NULL, unsigned int);\n *      b = talloc_array(a, unsigned int, 100);\n * @endcode\n *\n * @see talloc()\n * @see talloc_zero_array()\n */\n_PUBLIC_ void *talloc_array(const void *ctx, #type, unsigned count);\n#else\n#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)\n_PUBLIC_ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name);\n#endif\n\n#ifdef DOXYGEN\n/**\n * @brief Allocate an array.\n *\n * @param[in]  ctx      The talloc context to hang the result off.\n *\n * @param[in]  size     The size of an array element.\n *\n * @param[in]  count    The number of elements you want to allocate.\n *\n * @return              The allocated result, NULL on error.\n */\n_PUBLIC_ void *talloc_array_size(const void *ctx, size_t size, unsigned count);\n#else\n#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__)\n#endif\n\n#ifdef DOXYGEN\n/**\n * @brief Allocate an array into a typed pointer.\n *\n * The macro should be used when you have a pointer to an array and want to\n * allocate memory of an array to point at with this pointer. When compiling\n * with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size()\n * and talloc_get_name() will return the current location in the source file\n * and not the type.\n *\n * @param[in]  ctx      The talloc context to hang the result off.\n *\n * @param[in]  ptr      The pointer you want to assign the result to.\n *\n * @param[in]  count    The number of elements you want to allocate.\n *\n * @return              The allocated memory chunk, properly casted. NULL on\n *                      error.\n */\nvoid *talloc_array_ptrtype(const void *ctx, const void *ptr, unsigned count);\n#else\n#define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count)\n#endif\n\n#ifdef DOXYGEN\n/**\n * @brief Get the number of elements in a talloc'ed array.\n *\n * A talloc chunk carries its own size, so for talloc'ed arrays it is not\n * necessary to store the number of elements explicitly.\n *\n * @param[in]  ctx      The allocated array.\n *\n * @return              The number of elements in ctx.\n */\nsize_t talloc_array_length(const void *ctx);\n#else\n#define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx))\n#endif\n\n#ifdef DOXYGEN\n/**\n * @brief Allocate a zero-initialized array\n *\n * @param[in]  ctx      The talloc context to hang the result off.\n *\n * @param[in]  type     The type that we want to allocate.\n *\n * @param[in]  count    The number of \"type\" elements you want to allocate.\n *\n * @return              The allocated result casted to \"type *\", NULL on error.\n *\n * The talloc_zero_array() macro is equivalent to:\n *\n * @code\n *     ptr = talloc_array(ctx, type, count);\n *     if (ptr) memset(ptr, 0, sizeof(type) * count);\n * @endcode\n */\nvoid *talloc_zero_array(const void *ctx, #type, unsigned count);\n#else\n#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type)\n_PUBLIC_ void *_talloc_zero_array(const void *ctx,\n\t\t\t size_t el_size,\n\t\t\t unsigned count,\n\t\t\t const char *name);\n#endif\n\n#ifdef DOXYGEN\n/**\n * @brief Change the size of a talloc array.\n *\n * The macro changes the size of a talloc pointer. The 'count' argument is the\n * number of elements of type 'type' that you want the resulting pointer to\n * hold.\n *\n * talloc_realloc() has the following equivalences:\n *\n * @code\n *      talloc_realloc(ctx, NULL, type, 1) ==> talloc(ctx, type);\n *      talloc_realloc(ctx, NULL, type, N) ==> talloc_array(ctx, type, N);\n *      talloc_realloc(ctx, ptr, type, 0)  ==> talloc_free(ptr);\n * @endcode\n *\n * The \"context\" argument is only used if \"ptr\" is NULL, otherwise it is\n * ignored.\n *\n * @param[in]  ctx      The parent context used if ptr is NULL.\n *\n * @param[in]  ptr      The chunk to be resized.\n *\n * @param[in]  type     The type of the array element inside ptr.\n *\n * @param[in]  count    The intended number of array elements.\n *\n * @return              The new array, NULL on error. The call will fail either\n *                      due to a lack of memory, or because the pointer has more\n *                      than one parent (see talloc_reference()).\n */\n_PUBLIC_ void *talloc_realloc(const void *ctx, void *ptr, #type, size_t count);\n#else\n#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type)\n_PUBLIC_ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name);\n#endif\n\n#ifdef DOXYGEN\n/**\n * @brief Change the size of a talloc array, zero out additional space.\n *\n * Same as talloc_realloc() with the additional behavior to zero out\n * code in case the array is expanded.\n *\n * @param[in]  ctx      The parent context used if ptr is NULL.\n *\n * @param[in]  ptr      The chunk to be resized.\n *\n * @param[in]  type     The type of the array element inside ptr.\n *\n * @param[in]  count    The intended number of array elements.\n *\n * @return              The new array, NULL on error. The call will fail either\n *                      due to a lack of memory, or because the pointer has more\n *                      than one parent (see talloc_reference()).\n */\n_PUBLIC_ void *talloc_realloc_zero(const void *ctx,\n\t\t\t\t   void *ptr,\n\t\t\t\t   #type,\n\t\t\t\t   size_t count);\n#else\n#define talloc_realloc_zero(ctx, p, type, count) \\\n\t(type *)_talloc_realloc_array_zero(ctx, p, sizeof(type), count, #type)\n_PUBLIC_ void *_talloc_realloc_array_zero(const void *ctx,\n\t\t\t\t\t  void *ptr,\n\t\t\t\t\t  size_t el_size,\n\t\t\t\t\t  unsigned count,\n\t\t\t\t\t  const char *name);\n#endif\n\n#ifdef DOXYGEN\n/**\n * @brief Untyped realloc to change the size of a talloc array.\n *\n * The macro is useful when the type is not known so the typesafe\n * talloc_realloc() cannot be used.\n *\n * @param[in]  ctx      The parent context used if 'ptr' is NULL.\n *\n * @param[in]  ptr      The chunk to be resized.\n *\n * @param[in]  size     The new chunk size.\n *\n * @return              The new array, NULL on error.\n */\nvoid *talloc_realloc_size(const void *ctx, void *ptr, size_t size);\n#else\n#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__)\n_PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name);\n#endif\n\n/**\n * @brief Provide a function version of talloc_realloc_size.\n *\n * This is a non-macro version of talloc_realloc(), which is useful as\n * libraries sometimes want a ralloc function pointer. A realloc()\n * implementation encapsulates the functionality of malloc(), free() and\n * realloc() in one call, which is why it is useful to be able to pass around\n * a single function pointer.\n *\n * @param[in]  context  The parent context used if ptr is NULL.\n *\n * @param[in]  ptr      The chunk to be resized.\n *\n * @param[in]  size     The new chunk size.\n *\n * @return              The new chunk, NULL on error.\n */\n_PUBLIC_ void *talloc_realloc_fn(const void *context, void *ptr, size_t size);\n\n/* @} ******************************************************************/\n\n/**\n * @defgroup talloc_string The talloc string functions.\n * @ingroup talloc\n *\n * talloc string allocation and manipulation functions.\n * @{\n */\n\n/**\n * @brief Duplicate a string into a talloc chunk.\n *\n * This function is equivalent to:\n *\n * @code\n *      ptr = talloc_size(ctx, strlen(p)+1);\n *      if (ptr) memcpy(ptr, p, strlen(p)+1);\n * @endcode\n *\n * This functions sets the name of the new pointer to the passed\n * string. This is equivalent to:\n *\n * @code\n *      talloc_set_name_const(ptr, ptr)\n * @endcode\n *\n * @param[in]  t        The talloc context to hang the result off.\n *\n * @param[in]  p        The string you want to duplicate.\n *\n * @return              The duplicated string, NULL on error.\n */\n_PUBLIC_ char *talloc_strdup(const void *t, const char *p);\n\n/**\n * @brief Append a string to given string.\n *\n * The destination string is reallocated to take\n * <code>strlen(s) + strlen(a) + 1</code> characters.\n *\n * This functions sets the name of the new pointer to the new\n * string. This is equivalent to:\n *\n * @code\n *      talloc_set_name_const(ptr, ptr)\n * @endcode\n *\n * If <code>s == NULL</code> then new context is created.\n *\n * @param[in]  s        The destination to append to.\n *\n * @param[in]  a        The string you want to append.\n *\n * @return              The concatenated strings, NULL on error.\n *\n * @see talloc_strdup()\n * @see talloc_strdup_append_buffer()\n */\n_PUBLIC_ char *talloc_strdup_append(char *s, const char *a);\n\n/**\n * @brief Append a string to a given buffer.\n *\n * This is a more efficient version of talloc_strdup_append(). It determines the\n * length of the destination string by the size of the talloc context.\n *\n * Use this very carefully as it produces a different result than\n * talloc_strdup_append() when a zero character is in the middle of the\n * destination string.\n *\n * @code\n *      char *str_a = talloc_strdup(NULL, \"hello world\");\n *      char *str_b = talloc_strdup(NULL, \"hello world\");\n *      str_a[5] = str_b[5] = '\\0'\n *\n *      char *app = talloc_strdup_append(str_a, \", hello\");\n *      char *buf = talloc_strdup_append_buffer(str_b, \", hello\");\n *\n *      printf(\"%s\\n\", app); // hello, hello (app = \"hello, hello\")\n *      printf(\"%s\\n\", buf); // hello (buf = \"hello\\0world, hello\")\n * @endcode\n *\n * If <code>s == NULL</code> then new context is created.\n *\n * @param[in]  s        The destination buffer to append to.\n *\n * @param[in]  a        The string you want to append.\n *\n * @return              The concatenated strings, NULL on error.\n *\n * @see talloc_strdup()\n * @see talloc_strdup_append()\n * @see talloc_array_length()\n */\n_PUBLIC_ char *talloc_strdup_append_buffer(char *s, const char *a);\n\n/**\n * @brief Duplicate a length-limited string into a talloc chunk.\n *\n * This function is the talloc equivalent of the C library function strndup(3).\n *\n * This functions sets the name of the new pointer to the passed string. This is\n * equivalent to:\n *\n * @code\n *      talloc_set_name_const(ptr, ptr)\n * @endcode\n *\n * @param[in]  t        The talloc context to hang the result off.\n *\n * @param[in]  p        The string you want to duplicate.\n *\n * @param[in]  n        The maximum string length to duplicate.\n *\n * @return              The duplicated string, NULL on error.\n */\n_PUBLIC_ char *talloc_strndup(const void *t, const char *p, size_t n);\n\n/**\n * @brief Append at most n characters of a string to given string.\n *\n * The destination string is reallocated to take\n * <code>strlen(s) + strnlen(a, n) + 1</code> characters.\n *\n * This functions sets the name of the new pointer to the new\n * string. This is equivalent to:\n *\n * @code\n *      talloc_set_name_const(ptr, ptr)\n * @endcode\n *\n * If <code>s == NULL</code> then new context is created.\n *\n * @param[in]  s        The destination string to append to.\n *\n * @param[in]  a        The source string you want to append.\n *\n * @param[in]  n        The number of characters you want to append from the\n *                      string.\n *\n * @return              The concatenated strings, NULL on error.\n *\n * @see talloc_strndup()\n * @see talloc_strndup_append_buffer()\n */\n_PUBLIC_ char *talloc_strndup_append(char *s, const char *a, size_t n);\n\n/**\n * @brief Append at most n characters of a string to given buffer\n *\n * This is a more efficient version of talloc_strndup_append(). It determines\n * the length of the destination string by the size of the talloc context.\n *\n * Use this very carefully as it produces a different result than\n * talloc_strndup_append() when a zero character is in the middle of the\n * destination string.\n *\n * @code\n *      char *str_a = talloc_strdup(NULL, \"hello world\");\n *      char *str_b = talloc_strdup(NULL, \"hello world\");\n *      str_a[5] = str_b[5] = '\\0'\n *\n *      char *app = talloc_strndup_append(str_a, \", hello\", 7);\n *      char *buf = talloc_strndup_append_buffer(str_b, \", hello\", 7);\n *\n *      printf(\"%s\\n\", app); // hello, hello (app = \"hello, hello\")\n *      printf(\"%s\\n\", buf); // hello (buf = \"hello\\0world, hello\")\n * @endcode\n *\n * If <code>s == NULL</code> then new context is created.\n *\n * @param[in]  s        The destination buffer to append to.\n *\n * @param[in]  a        The source string you want to append.\n *\n * @param[in]  n        The number of characters you want to append from the\n *                      string.\n *\n * @return              The concatenated strings, NULL on error.\n *\n * @see talloc_strndup()\n * @see talloc_strndup_append()\n * @see talloc_array_length()\n */\n_PUBLIC_ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n);\n\n/**\n * @brief Format a string given a va_list.\n *\n * This function is the talloc equivalent of the C library function\n * vasprintf(3).\n *\n * This functions sets the name of the new pointer to the new string. This is\n * equivalent to:\n *\n * @code\n *      talloc_set_name_const(ptr, ptr)\n * @endcode\n *\n * @param[in]  t        The talloc context to hang the result off.\n *\n * @param[in]  fmt      The format string.\n *\n * @param[in]  ap       The parameters used to fill fmt.\n *\n * @return              The formatted string, NULL on error.\n */\n_PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);\n\n/**\n * @brief Format a string given a va_list and append it to the given destination\n *        string.\n *\n * @param[in]  s        The destination string to append to.\n *\n * @param[in]  fmt      The format string.\n *\n * @param[in]  ap       The parameters used to fill fmt.\n *\n * @return              The formatted string, NULL on error.\n *\n * @see talloc_vasprintf()\n */\n_PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);\n\n/**\n * @brief Format a string given a va_list and append it to the given destination\n *        buffer.\n *\n * @param[in]  s        The destination buffer to append to.\n *\n * @param[in]  fmt      The format string.\n *\n * @param[in]  ap       The parameters used to fill fmt.\n *\n * @return              The formatted string, NULL on error.\n *\n * @see talloc_vasprintf()\n */\n_PUBLIC_ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);\n\n/**\n * @brief Build up a string buffer, handle allocation failure\n *\n * @param[in] ps Pointer to the talloc'ed string to be extended\n * @param[in] fmt The format string\n * @param[in] ... The parameters used to fill fmt.\n *\n * This does nothing if *ps is NULL and sets *ps to NULL if the\n * intermediate reallocation fails. Useful when building up a string\n * step by step, no intermediate NULL checks are required.\n */\n_PUBLIC_ void talloc_asprintf_addbuf(char **ps, const char *fmt, ...) \\\n\tPRINTF_ATTRIBUTE(2,3);\n\n/**\n * @brief Format a string.\n *\n * This function is the talloc equivalent of the C library function asprintf(3).\n *\n * This functions sets the name of the new pointer to the new string. This is\n * equivalent to:\n *\n * @code\n *      talloc_set_name_const(ptr, ptr)\n * @endcode\n *\n * @param[in]  t        The talloc context to hang the result off.\n *\n * @param[in]  fmt      The format string.\n *\n * @param[in]  ...      The parameters used to fill fmt.\n *\n * @return              The formatted string, NULL on error.\n */\n_PUBLIC_ char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);\n\n/**\n * @brief Append a formatted string to another string.\n *\n * This function appends the given formatted string to the given string. Use\n * this variant when the string in the current talloc buffer may have been\n * truncated in length.\n *\n * This functions sets the name of the new pointer to the new\n * string. This is equivalent to:\n *\n * @code\n *      talloc_set_name_const(ptr, ptr)\n * @endcode\n *\n * If <code>s == NULL</code> then new context is created.\n *\n * @param[in]  s        The string to append to.\n *\n * @param[in]  fmt      The format string.\n *\n * @param[in]  ...      The parameters used to fill fmt.\n *\n * @return              The formatted string, NULL on error.\n */\n_PUBLIC_ char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);\n\n/**\n * @brief Append a formatted string to another string.\n *\n * This is a more efficient version of talloc_asprintf_append(). It determines\n * the length of the destination string by the size of the talloc context.\n *\n * Use this very carefully as it produces a different result than\n * talloc_asprintf_append() when a zero character is in the middle of the\n * destination string.\n *\n * @code\n *      char *str_a = talloc_strdup(NULL, \"hello world\");\n *      char *str_b = talloc_strdup(NULL, \"hello world\");\n *      str_a[5] = str_b[5] = '\\0'\n *\n *      char *app = talloc_asprintf_append(str_a, \"%s\", \", hello\");\n *      char *buf = talloc_strdup_append_buffer(str_b, \"%s\", \", hello\");\n *\n *      printf(\"%s\\n\", app); // hello, hello (app = \"hello, hello\")\n *      printf(\"%s\\n\", buf); // hello (buf = \"hello\\0world, hello\")\n * @endcode\n *\n * If <code>s == NULL</code> then new context is created.\n *\n * @param[in]  s        The string to append to\n *\n * @param[in]  fmt      The format string.\n *\n * @param[in]  ...      The parameters used to fill fmt.\n *\n * @return              The formatted string, NULL on error.\n *\n * @see talloc_asprintf()\n * @see talloc_asprintf_append()\n */\n_PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);\n\n/* @} ******************************************************************/\n\n/**\n * @defgroup talloc_debug The talloc debugging support functions\n * @ingroup talloc\n *\n * To aid memory debugging, talloc contains routines to inspect the currently\n * allocated memory hierarchy.\n *\n * @{\n */\n\n/**\n * @brief Walk a complete talloc hierarchy.\n *\n * This provides a more flexible reports than talloc_report(). It\n * will recursively call the callback for the entire tree of memory\n * referenced by the pointer. References in the tree are passed with\n * is_ref = 1 and the pointer that is referenced.\n *\n * You can pass NULL for the pointer, in which case a report is\n * printed for the top level memory context, but only if\n * talloc_enable_leak_report() or talloc_enable_leak_report_full()\n * has been called.\n *\n * The recursion is stopped when depth >= max_depth.\n * max_depth = -1 means only stop at leaf nodes.\n *\n * @param[in]  ptr      The talloc chunk.\n *\n * @param[in]  depth    Internal parameter to control recursion. Call with 0.\n *\n * @param[in]  max_depth  Maximum recursion level.\n *\n * @param[in]  callback  Function to be called on every chunk.\n *\n * @param[in]  private_data  Private pointer passed to callback.\n */\n_PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,\n\t\t\t    void (*callback)(const void *ptr,\n\t\t\t\t\t     int depth, int max_depth,\n\t\t\t\t\t     int is_ref,\n\t\t\t\t\t     void *private_data),\n\t\t\t    void *private_data);\n\n/**\n * @brief Print a talloc hierarchy.\n *\n * This provides a more flexible reports than talloc_report(). It\n * will let you specify the depth and max_depth.\n *\n * @param[in]  ptr      The talloc chunk.\n *\n * @param[in]  depth    Internal parameter to control recursion. Call with 0.\n *\n * @param[in]  max_depth  Maximum recursion level.\n *\n * @param[in]  f        The file handle to print to.\n */\n_PUBLIC_ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f);\n\n/**\n * @brief Print a summary report of all memory used by ptr.\n *\n * This provides a more detailed report than talloc_report(). It will\n * recursively print the entire tree of memory referenced by the\n * pointer. References in the tree are shown by giving the name of the\n * pointer that is referenced.\n *\n * You can pass NULL for the pointer, in which case a report is printed\n * for the top level memory context, but only if\n * talloc_enable_leak_report() or talloc_enable_leak_report_full() has\n * been called.\n *\n * @param[in]  ptr      The talloc chunk.\n *\n * @param[in]  f        The file handle to print to.\n *\n * Example:\n * @code\n *      unsigned int *a, *b;\n *      a = talloc(NULL, unsigned int);\n *      b = talloc(a, unsigned int);\n *      fprintf(stderr, \"Dumping memory tree for a:\\n\");\n *      talloc_report_full(a, stderr);\n * @endcode\n *\n * @see talloc_report()\n */\n_PUBLIC_ void talloc_report_full(const void *ptr, FILE *f);\n\n/**\n * @brief Print a summary report of all memory used by ptr.\n *\n * This function prints a summary report of all memory used by ptr. One line of\n * report is printed for each immediate child of ptr, showing the total memory\n * and number of blocks used by that child.\n *\n * You can pass NULL for the pointer, in which case a report is printed\n * for the top level memory context, but only if talloc_enable_leak_report()\n * or talloc_enable_leak_report_full() has been called.\n *\n * @param[in]  ptr      The talloc chunk.\n *\n * @param[in]  f        The file handle to print to.\n *\n * Example:\n * @code\n *      unsigned int *a, *b;\n *      a = talloc(NULL, unsigned int);\n *      b = talloc(a, unsigned int);\n *      fprintf(stderr, \"Summary of memory tree for a:\\n\");\n *      talloc_report(a, stderr);\n * @endcode\n *\n * @see talloc_report_full()\n */\n_PUBLIC_ void talloc_report(const void *ptr, FILE *f);\n\n/**\n * @brief Enable tracking the use of NULL memory contexts.\n *\n * This enables tracking of the NULL memory context without enabling leak\n * reporting on exit. Useful for when you want to do your own leak\n * reporting call via talloc_report_null_full();\n */\n_PUBLIC_ void talloc_enable_null_tracking(void);\n\n/**\n * @brief Enable tracking the use of NULL memory contexts.\n *\n * This enables tracking of the NULL memory context without enabling leak\n * reporting on exit. Useful for when you want to do your own leak\n * reporting call via talloc_report_null_full();\n */\n_PUBLIC_ void talloc_enable_null_tracking_no_autofree(void);\n\n/**\n * @brief Disable tracking of the NULL memory context.\n *\n * This disables tracking of the NULL memory context.\n */\n_PUBLIC_ void talloc_disable_null_tracking(void);\n\n/**\n * @brief Enable leak report when a program exits.\n *\n * This enables calling of talloc_report(NULL, stderr) when the program\n * exits. In Samba4 this is enabled by using the --leak-report command\n * line option.\n *\n * For it to be useful, this function must be called before any other\n * talloc function as it establishes a \"null context\" that acts as the\n * top of the tree. If you don't call this function first then passing\n * NULL to talloc_report() or talloc_report_full() won't give you the\n * full tree printout.\n *\n * Here is a typical talloc report:\n *\n * @code\n * talloc report on 'null_context' (total 267 bytes in 15 blocks)\n *      libcli/auth/spnego_parse.c:55  contains     31 bytes in   2 blocks\n *      libcli/auth/spnego_parse.c:55  contains     31 bytes in   2 blocks\n *      iconv(UTF8,CP850)              contains     42 bytes in   2 blocks\n *      libcli/auth/spnego_parse.c:55  contains     31 bytes in   2 blocks\n *      iconv(CP850,UTF8)              contains     42 bytes in   2 blocks\n *      iconv(UTF8,UTF-16LE)           contains     45 bytes in   2 blocks\n *      iconv(UTF-16LE,UTF8)           contains     45 bytes in   2 blocks\n * @endcode\n */\n_PUBLIC_ void talloc_enable_leak_report(void);\n\n/**\n * @brief Enable full leak report when a program exits.\n *\n * This enables calling of talloc_report_full(NULL, stderr) when the\n * program exits. In Samba4 this is enabled by using the\n * --leak-report-full command line option.\n *\n * For it to be useful, this function must be called before any other\n * talloc function as it establishes a \"null context\" that acts as the\n * top of the tree. If you don't call this function first then passing\n * NULL to talloc_report() or talloc_report_full() won't give you the\n * full tree printout.\n *\n * Here is a typical full report:\n *\n * @code\n * full talloc report on 'root' (total 18 bytes in 8 blocks)\n *      p1                             contains     18 bytes in   7 blocks (ref 0)\n *      r1                             contains     13 bytes in   2 blocks (ref 0)\n *      reference to: p2\n *      p2                             contains      1 bytes in   1 blocks (ref 1)\n *      x3                             contains      1 bytes in   1 blocks (ref 0)\n *      x2                             contains      1 bytes in   1 blocks (ref 0)\n *      x1                             contains      1 bytes in   1 blocks (ref 0)\n * @endcode\n */\n_PUBLIC_ void talloc_enable_leak_report_full(void);\n\n/**\n * @brief Set a custom \"abort\" function that is called on serious error.\n *\n * The default \"abort\" function is <code>abort()</code>.\n *\n * The \"abort\" function is called when:\n *\n * <ul>\n *  <li>talloc_get_type_abort() fails</li>\n *  <li>the provided pointer is not a valid talloc context</li>\n *  <li>when the context meta data are invalid</li>\n *  <li>when access after free is detected</li>\n * </ul>\n *\n * Example:\n *\n * @code\n * void my_abort(const char *reason)\n * {\n *      fprintf(stderr, \"talloc abort: %s\\n\", reason);\n *      abort();\n * }\n *\n *      talloc_set_abort_fn(my_abort);\n * @endcode\n *\n * @param[in]  abort_fn      The new \"abort\" function.\n *\n * @see talloc_set_log_fn()\n * @see talloc_get_type()\n */\n_PUBLIC_ void talloc_set_abort_fn(void (*abort_fn)(const char *reason));\n\n/**\n * @brief Set a logging function.\n *\n * @param[in]  log_fn      The logging function.\n *\n * @see talloc_set_log_stderr()\n * @see talloc_set_abort_fn()\n */\n_PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message));\n\n/**\n * @brief Set stderr as the output for logs.\n *\n * @see talloc_set_log_fn()\n * @see talloc_set_abort_fn()\n */\n_PUBLIC_ void talloc_set_log_stderr(void);\n\n/**\n * @brief Set a max memory limit for the current context hierarchy\n *\t  This affects all children of this context and constrain any\n *\t  allocation in the hierarchy to never exceed the limit set.\n *\t  The limit can be removed by setting 0 (unlimited) as the\n *\t  max_size by calling the function again on the same context.\n *\t  Memory limits can also be nested, meaning a child can have\n *\t  a stricter memory limit than a parent.\n *\t  Memory limits are enforced only at memory allocation time.\n *\t  Stealing a context into a 'limited' hierarchy properly\n *\t  updates memory usage but does *not* cause failure if the\n *\t  move causes the new parent to exceed its limits. However\n *\t  any further allocation on that hierarchy will then fail.\n *\n * @warning talloc memlimit functionality is deprecated. Please\n *\t    consider using cgroup memory limits instead.\n *\n * @param[in]\tctx\t\tThe talloc context to set the limit on\n * @param[in]\tmax_size\tThe (new) max_size\n */\n_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_;\n\n/* @} ******************************************************************/\n\n#if TALLOC_DEPRECATED\n#define talloc_zero_p(ctx, type) talloc_zero(ctx, type)\n#define talloc_p(ctx, type) talloc(ctx, type)\n#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count)\n#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count)\n#define talloc_destroy(ctx) talloc_free(ctx)\n#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a))\n#endif\n\n#ifndef TALLOC_MAX_DEPTH\n#define TALLOC_MAX_DEPTH 10000\n#endif\n\n#ifdef __cplusplus\n} /* end of extern \"C\" */\n#endif\n\n#endif\n"},
                          "roles": ["resultFile"]}],
           "results": [{"ruleId": "-Wdeprecated-declarations",
                        "level": "warning",
                        "message": {"text": "‘talloc_autofree_context’ is deprecated"},
                        "locations": [{"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                 "uriBaseId": "PWD"},
                                                            "region": {"startLine": 1334,
                                                                       "startColumn": 9,
                                                                       "endColumn": 10},
                                                            "contextRegion": {"startLine": 1334,
                                                                              "snippet": {"text": "\tp = talloc_autofree_context();\n"}}},
                                       "logicalLocations": [{"index": 0,
                                                             "fullyQualifiedName": "test_autofree"}]}],
                        "relatedLocations": [{"physicalLocation": {"artifactLocation": {"uri": "../../talloc.h",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 1084,
                                                                              "startColumn": 16,
                                                                              "endColumn": 39},
                                                                   "contextRegion": {"startLine": 1084,
                                                                                     "snippet": {"text": "_PUBLIC_ void *talloc_autofree_context(void) _DEPRECATED_;\n"}}},
                                              "message": {"text": "declared here"},
                                              "properties": {"nestingLevel": 0},
                                              "id": 0,
                                              "relationships": [{"target": 1,
                                                                 "kinds": ["isIncludedBy"]}]},
                                             {"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 28},
                                                                   "contextRegion": {"startLine": 28,
                                                                                     "snippet": {"text": "#include <talloc.h>\n"}}},
                                              "relationships": [{"target": 0,
                                                                 "kinds": ["includes"]}],
                                              "id": 1}]},
                       {"ruleId": "-Wdeprecated-declarations",
                        "level": "warning",
                        "message": {"text": "‘talloc_autofree_context’ is deprecated"},
                        "locations": [{"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                 "uriBaseId": "PWD"},
                                                            "region": {"startLine": 1337,
                                                                       "startColumn": 9,
                                                                       "endColumn": 10},
                                                            "contextRegion": {"startLine": 1337,
                                                                              "snippet": {"text": "\tp = talloc_autofree_context();\n"}}},
                                       "logicalLocations": [{"index": 0,
                                                             "fullyQualifiedName": "test_autofree"}]}],
                        "relatedLocations": [{"physicalLocation": {"artifactLocation": {"uri": "../../talloc.h",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 1084,
                                                                              "startColumn": 16,
                                                                              "endColumn": 39},
                                                                   "contextRegion": {"startLine": 1084,
                                                                                     "snippet": {"text": "_PUBLIC_ void *talloc_autofree_context(void) _DEPRECATED_;\n"}}},
                                              "message": {"text": "declared here"},
                                              "properties": {"nestingLevel": 0},
                                              "id": 0,
                                              "relationships": [{"target": 1,
                                                                 "kinds": ["isIncludedBy"]}]},
                                             {"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 28},
                                                                   "contextRegion": {"startLine": 28,
                                                                                     "snippet": {"text": "#include <talloc.h>\n"}}},
                                              "relationships": [{"target": 0,
                                                                 "kinds": ["includes"]}],
                                              "id": 1}]},
                       {"ruleId": "-Wdeprecated-declarations",
                        "level": "warning",
                        "message": {"text": "‘talloc_set_memlimit’ is deprecated"},
                        "locations": [{"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                 "uriBaseId": "PWD"},
                                                            "region": {"startLine": 1680,
                                                                       "startColumn": 9,
                                                                       "endColumn": 23},
                                                            "contextRegion": {"startLine": 1680,
                                                                              "snippet": {"text": "\ttorture_assert(\"memlimit\", talloc_set_memlimit(l1, 2048) == 0,\n"}}},
                                       "logicalLocations": [{"index": 1,
                                                             "fullyQualifiedName": "test_memlimit"}]}],
                        "relatedLocations": [{"physicalLocation": {"artifactLocation": {"uri": "../../talloc.h",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 1984,
                                                                              "startColumn": 14,
                                                                              "endColumn": 33},
                                                                   "contextRegion": {"startLine": 1984,
                                                                                     "snippet": {"text": "_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_;\n"}}},
                                              "message": {"text": "declared here"},
                                              "properties": {"nestingLevel": 0},
                                              "id": 0,
                                              "relationships": [{"target": 1,
                                                                 "kinds": ["isIncludedBy"]}]},
                                             {"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 28},
                                                                   "contextRegion": {"startLine": 28,
                                                                                     "snippet": {"text": "#include <talloc.h>\n"}}},
                                              "relationships": [{"target": 0,
                                                                 "kinds": ["includes"]}],
                                              "id": 1}]},
                       {"ruleId": "-Wdeprecated-declarations",
                        "level": "warning",
                        "message": {"text": "‘talloc_set_memlimit’ is deprecated"},
                        "locations": [{"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                 "uriBaseId": "PWD"},
                                                            "region": {"startLine": 1740,
                                                                       "startColumn": 9,
                                                                       "endColumn": 23},
                                                            "contextRegion": {"startLine": 1740,
                                                                              "snippet": {"text": "\ttorture_assert(\"memlimit\", talloc_set_memlimit(l3, 1024) == 0,\n"}}},
                                       "logicalLocations": [{"index": 1,
                                                             "fullyQualifiedName": "test_memlimit"}]}],
                        "relatedLocations": [{"physicalLocation": {"artifactLocation": {"uri": "../../talloc.h",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 1984,
                                                                              "startColumn": 14,
                                                                              "endColumn": 33},
                                                                   "contextRegion": {"startLine": 1984,
                                                                                     "snippet": {"text": "_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_;\n"}}},
                                              "message": {"text": "declared here"},
                                              "properties": {"nestingLevel": 0},
                                              "id": 0,
                                              "relationships": [{"target": 1,
                                                                 "kinds": ["isIncludedBy"]}]},
                                             {"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 28},
                                                                   "contextRegion": {"startLine": 28,
                                                                                     "snippet": {"text": "#include <talloc.h>\n"}}},
                                              "relationships": [{"target": 0,
                                                                 "kinds": ["includes"]}],
                                              "id": 1}]},
                       {"ruleId": "-Wdeprecated-declarations",
                        "level": "warning",
                        "message": {"text": "‘talloc_set_memlimit’ is deprecated"},
                        "locations": [{"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                 "uriBaseId": "PWD"},
                                                            "region": {"startLine": 1753,
                                                                       "startColumn": 9,
                                                                       "endColumn": 23},
                                                            "contextRegion": {"startLine": 1753,
                                                                              "snippet": {"text": "\ttorture_assert(\"memlimit\", talloc_set_memlimit(l4, 512) == 0,\n"}}},
                                       "logicalLocations": [{"index": 1,
                                                             "fullyQualifiedName": "test_memlimit"}]}],
                        "relatedLocations": [{"physicalLocation": {"artifactLocation": {"uri": "../../talloc.h",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 1984,
                                                                              "startColumn": 14,
                                                                              "endColumn": 33},
                                                                   "contextRegion": {"startLine": 1984,
                                                                                     "snippet": {"text": "_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_;\n"}}},
                                              "message": {"text": "declared here"},
                                              "properties": {"nestingLevel": 0},
                                              "id": 0,
                                              "relationships": [{"target": 1,
                                                                 "kinds": ["isIncludedBy"]}]},
                                             {"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 28},
                                                                   "contextRegion": {"startLine": 28,
                                                                                     "snippet": {"text": "#include <talloc.h>\n"}}},
                                              "relationships": [{"target": 0,
                                                                 "kinds": ["includes"]}],
                                              "id": 1}]},
                       {"ruleId": "-Wdeprecated-declarations",
                        "level": "warning",
                        "message": {"text": "‘talloc_set_memlimit’ is deprecated"},
                        "locations": [{"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                 "uriBaseId": "PWD"},
                                                            "region": {"startLine": 1787,
                                                                       "startColumn": 9,
                                                                       "endColumn": 23},
                                                            "contextRegion": {"startLine": 1787,
                                                                              "snippet": {"text": "\ttorture_assert(\"memlimit\", talloc_set_memlimit(l4, 512) == 0,\n"}}},
                                       "logicalLocations": [{"index": 1,
                                                             "fullyQualifiedName": "test_memlimit"}]}],
                        "relatedLocations": [{"physicalLocation": {"artifactLocation": {"uri": "../../talloc.h",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 1984,
                                                                              "startColumn": 14,
                                                                              "endColumn": 33},
                                                                   "contextRegion": {"startLine": 1984,
                                                                                     "snippet": {"text": "_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_;\n"}}},
                                              "message": {"text": "declared here"},
                                              "properties": {"nestingLevel": 0},
                                              "id": 0,
                                              "relationships": [{"target": 1,
                                                                 "kinds": ["isIncludedBy"]}]},
                                             {"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 28},
                                                                   "contextRegion": {"startLine": 28,
                                                                                     "snippet": {"text": "#include <talloc.h>\n"}}},
                                              "relationships": [{"target": 0,
                                                                 "kinds": ["includes"]}],
                                              "id": 1}]},
                       {"ruleId": "-Wdeprecated-declarations",
                        "level": "warning",
                        "message": {"text": "‘talloc_set_memlimit’ is deprecated"},
                        "locations": [{"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                 "uriBaseId": "PWD"},
                                                            "region": {"startLine": 1820,
                                                                       "startColumn": 9,
                                                                       "endColumn": 28},
                                                            "contextRegion": {"startLine": 1820,
                                                                              "snippet": {"text": "\ttalloc_set_memlimit(pool, 10*1024);\n"}}},
                                       "logicalLocations": [{"index": 1,
                                                             "fullyQualifiedName": "test_memlimit"}]}],
                        "relatedLocations": [{"physicalLocation": {"artifactLocation": {"uri": "../../talloc.h",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 1984,
                                                                              "startColumn": 14,
                                                                              "endColumn": 33},
                                                                   "contextRegion": {"startLine": 1984,
                                                                                     "snippet": {"text": "_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_;\n"}}},
                                              "message": {"text": "declared here"},
                                              "properties": {"nestingLevel": 0},
                                              "id": 0,
                                              "relationships": [{"target": 1,
                                                                 "kinds": ["isIncludedBy"]}]},
                                             {"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 28},
                                                                   "contextRegion": {"startLine": 28,
                                                                                     "snippet": {"text": "#include <talloc.h>\n"}}},
                                              "relationships": [{"target": 0,
                                                                 "kinds": ["includes"]}],
                                              "id": 1}]},
                       {"ruleId": "-Wdeprecated-declarations",
                        "level": "warning",
                        "message": {"text": "‘talloc_set_memlimit’ is deprecated"},
                        "locations": [{"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                 "uriBaseId": "PWD"},
                                                            "region": {"startLine": 1873,
                                                                       "startColumn": 9,
                                                                       "endColumn": 28},
                                                            "contextRegion": {"startLine": 1873,
                                                                              "snippet": {"text": "\ttalloc_set_memlimit(pool, 11*1024);\n"}}},
                                       "logicalLocations": [{"index": 1,
                                                             "fullyQualifiedName": "test_memlimit"}]}],
                        "relatedLocations": [{"physicalLocation": {"artifactLocation": {"uri": "../../talloc.h",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 1984,
                                                                              "startColumn": 14,
                                                                              "endColumn": 33},
                                                                   "contextRegion": {"startLine": 1984,
                                                                                     "snippet": {"text": "_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_;\n"}}},
                                              "message": {"text": "declared here"},
                                              "properties": {"nestingLevel": 0},
                                              "id": 0,
                                              "relationships": [{"target": 1,
                                                                 "kinds": ["isIncludedBy"]}]},
                                             {"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 28},
                                                                   "contextRegion": {"startLine": 28,
                                                                                     "snippet": {"text": "#include <talloc.h>\n"}}},
                                              "relationships": [{"target": 0,
                                                                 "kinds": ["includes"]}],
                                              "id": 1}]},
                       {"ruleId": "-Wdeprecated-declarations",
                        "level": "warning",
                        "message": {"text": "‘talloc_set_memlimit’ is deprecated"},
                        "locations": [{"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                 "uriBaseId": "PWD"},
                                                            "region": {"startLine": 1885,
                                                                       "startColumn": 9,
                                                                       "endColumn": 28},
                                                            "contextRegion": {"startLine": 1885,
                                                                              "snippet": {"text": "\ttalloc_set_memlimit(pool, 21*1024);\n"}}},
                                       "logicalLocations": [{"index": 1,
                                                             "fullyQualifiedName": "test_memlimit"}]}],
                        "relatedLocations": [{"physicalLocation": {"artifactLocation": {"uri": "../../talloc.h",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 1984,
                                                                              "startColumn": 14,
                                                                              "endColumn": 33},
                                                                   "contextRegion": {"startLine": 1984,
                                                                                     "snippet": {"text": "_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_;\n"}}},
                                              "message": {"text": "declared here"},
                                              "properties": {"nestingLevel": 0},
                                              "id": 0,
                                              "relationships": [{"target": 1,
                                                                 "kinds": ["isIncludedBy"]}]},
                                             {"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 28},
                                                                   "contextRegion": {"startLine": 28,
                                                                                     "snippet": {"text": "#include <talloc.h>\n"}}},
                                              "relationships": [{"target": 0,
                                                                 "kinds": ["includes"]}],
                                              "id": 1}]},
                       {"ruleId": "-Wdeprecated-declarations",
                        "level": "warning",
                        "message": {"text": "‘talloc_set_memlimit’ is deprecated"},
                        "locations": [{"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                 "uriBaseId": "PWD"},
                                                            "region": {"startLine": 1923,
                                                                       "startColumn": 9,
                                                                       "endColumn": 28},
                                                            "contextRegion": {"startLine": 1923,
                                                                              "snippet": {"text": "\ttalloc_set_memlimit(pool, 1024);\n"}}},
                                       "logicalLocations": [{"index": 1,
                                                             "fullyQualifiedName": "test_memlimit"}]}],
                        "relatedLocations": [{"physicalLocation": {"artifactLocation": {"uri": "../../talloc.h",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 1984,
                                                                              "startColumn": 14,
                                                                              "endColumn": 33},
                                                                   "contextRegion": {"startLine": 1984,
                                                                                     "snippet": {"text": "_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_;\n"}}},
                                              "message": {"text": "declared here"},
                                              "properties": {"nestingLevel": 0},
                                              "id": 0,
                                              "relationships": [{"target": 1,
                                                                 "kinds": ["isIncludedBy"]}]},
                                             {"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 28},
                                                                   "contextRegion": {"startLine": 28,
                                                                                     "snippet": {"text": "#include <talloc.h>\n"}}},
                                              "relationships": [{"target": 0,
                                                                 "kinds": ["includes"]}],
                                              "id": 1}]},
                       {"ruleId": "-Wdeprecated-declarations",
                        "level": "warning",
                        "message": {"text": "‘talloc_set_memlimit’ is deprecated"},
                        "locations": [{"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                 "uriBaseId": "PWD"},
                                                            "region": {"startLine": 1944,
                                                                       "startColumn": 9,
                                                                       "endColumn": 28},
                                                            "contextRegion": {"startLine": 1944,
                                                                              "snippet": {"text": "\ttalloc_set_memlimit(pool, 10*1024);\n"}}},
                                       "logicalLocations": [{"index": 1,
                                                             "fullyQualifiedName": "test_memlimit"}]}],
                        "relatedLocations": [{"physicalLocation": {"artifactLocation": {"uri": "../../talloc.h",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 1984,
                                                                              "startColumn": 14,
                                                                              "endColumn": 33},
                                                                   "contextRegion": {"startLine": 1984,
                                                                                     "snippet": {"text": "_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_;\n"}}},
                                              "message": {"text": "declared here"},
                                              "properties": {"nestingLevel": 0},
                                              "id": 0,
                                              "relationships": [{"target": 1,
                                                                 "kinds": ["isIncludedBy"]}]},
                                             {"physicalLocation": {"artifactLocation": {"uri": "../../testsuite.c",
                                                                                        "uriBaseId": "PWD"},
                                                                   "region": {"startLine": 28},
                                                                   "contextRegion": {"startLine": 28,
                                                                                     "snippet": {"text": "#include <talloc.h>\n"}}},
                                              "relationships": [{"target": 0,
                                                                 "kinds": ["includes"]}],
                                              "id": 1}]}],
           "logicalLocations": [{"name": "test_autofree",
                                 "fullyQualifiedName": "test_autofree",
                                 "decoratedName": "test_autofree",
                                 "kind": "function",
                                 "index": 0},
                                {"name": "test_memlimit",
                                 "fullyQualifiedName": "test_memlimit",
                                 "decoratedName": "test_memlimit",
                                 "kind": "function",
                                 "index": 1}]}]}
