* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) Jeremy Harris 2019 */
+/* Copyright (c) The Exim Maintainers 2021 - 2022 */
+/* Copyright (c) Jeremy Harris 2019 - 2020 */
/* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "../exim.h"
#include "lf_functions.h"
+/* All use of allocations will be done against the POOL_SEARCH memory,
+which is freed once by search_tidyup(). Make the free call a dummy.
+This burns some 300kB in handling a 37kB JSON file, for the benefit of
+a fast free. The alternative of staying with malloc is nearly as bad,
+eyeballing the activity there are 20% the number of free vs. alloc
+calls (before the big bunch at the end).
+
+Assume that the file is trusted, so no tainting */
+
+static void *
+json_malloc(size_t nbytes)
+{
+void * p = store_get((int)nbytes, GET_UNTAINTED);
+/* debug_printf("%s %d: %p\n", __FUNCTION__, (int)nbytes, p); */
+return p;
+}
+static void
+json_free(void * p)
+{
+/* debug_printf("%s: %p\n", __FUNCTION__, p); */
+}
+
/*************************************************
* Open entry point *
*************************************************/
/* See local README for interface description */
static void *
-json_open(uschar *filename, uschar **errmsg)
+json_open(const uschar * filename, uschar ** errmsg)
{
-FILE *f = Ufopen(filename, "rb");
-if (f == NULL)
- {
- int save_errno = errno;
- *errmsg = string_open_failed(errno, "%s for json search", filename);
- errno = save_errno;
- return NULL;
- }
+FILE * f;
+
+json_set_alloc_funcs(json_malloc, json_free);
+
+if (!(f = Ufopen(filename, "rb")))
+ *errmsg = string_open_failed("%s for json search", filename);
return f;
}
*************************************************/
static BOOL
-json_check(void *handle, uschar *filename, int modemask, uid_t *owners,
+json_check(void *handle, const uschar *filename, int modemask, uid_t *owners,
gid_t *owngroups, uschar **errmsg)
{
return lf_check_file(fileno((FILE *)handle), filename, S_IFREG, modemask,
/* See local README for interface description */
static int
-json_find(void *handle, uschar *filename, const uschar *keystring, int length,
- uschar **result, uschar **errmsg, uint *do_cache)
+json_find(void * handle, const uschar * filename, const uschar * keystring,
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
FILE * f = handle;
json_t * j, * j0;
uschar * key;
int sep = 0;
-length = length; /* Keep picky compilers happy */
-do_cache = do_cache; /* Keep picky compilers happy */
-
rewind(f);
if (!(j = json_loadf(f, 0, &jerr)))
{
: json_object_get(j, CCS key)
) )
{
- DEBUG(D_lookup) debug_printf("%s, for key %d: '%s'\n",
+ DEBUG(D_lookup) debug_printf_indent("%s, for key %d: '%s'\n",
numeric
? US"bad index, or not json array"
: US"no such key, or not json object",
#include "../version.h"
-void
-json_version_report(FILE *f)
+gstring *
+json_version_report(gstring * g)
{
-fprintf(f, "Library version: json: Jansonn version %s\n", JANSSON_VERSION);
+return string_fmt_append(g, "Library version: json: Jansonn version %s\n", JANSSON_VERSION);
}
static lookup_info json_lookup_info = {
- US"json", /* lookup name */
- lookup_absfile, /* uses absolute file name */
- json_open, /* open function */
- json_check, /* check function */
- json_find, /* find function */
- json_close, /* close function */
- NULL, /* no tidy function */
- NULL, /* no quoting function */
- json_version_report /* version reporting */
+ .name = US"json", /* lookup name */
+ .type = lookup_absfile, /* uses absolute file name */
+ .open = json_open, /* open function */
+ .check = json_check, /* check function */
+ .find = json_find, /* find function */
+ .close = json_close, /* close function */
+ .tidy = NULL, /* no tidy function */
+ .quote = NULL, /* no quoting function */
+ .version_report = json_version_report /* version reporting */
};