Skip to content

Commit a0f4244

Browse files
committed
Drop secondary (length) index
Drop secondary indexes to simplify tape operation and disallow placement of quotes around values other than domain names and text. Additionally, no attempt is made to parse symbols for which no symbolic constants have been specified and use of pretty TTL notation, e.g. 1m2s, is only allowed if the pretty_ttl option is enabled. Fixes NLnetLabs#30. Fixes NLnetLabs#31. Fixes NLnetLabs#38. Fixes NLnetLabs#50.
1 parent 4736daf commit a0f4244

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2871
-2495
lines changed

.github/workflows/build-test.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ jobs:
2626
generator: "Visual Studio 17 2022"
2727
build_type: Debug
2828
build_tool_options: "-nologo -verbosity:minimal -maxcpucount:4 -p:CL_MPCount=4"
29-
warnings_as_errors: off
3029
steps:
3130
- uses: actions/checkout@v3
3231
- uses: actions/setup-python@v4

CMakeLists.txt

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,22 +128,20 @@ generate_export_header(
128128
zone BASE_NAME ZONE EXPORT_FILE_NAME include/zone/export.h)
129129

130130
target_include_directories(
131-
zone PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
132-
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
133-
PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
134-
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
131+
zone PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
132+
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
133+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
134+
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
135135

136136
target_sources(zone PRIVATE
137137
src/zone.c
138138
src/types.c
139-
src/table.c
140139
src/log.c
141140
src/parser.c
142-
src/lexer.c
141+
src/fallback/parser.c
143142
src/generic/base16.c
144143
src/generic/base32.c
145-
src/generic/base64.c
146-
src/fallback/parser.c)
144+
src/generic/base64.c)
147145

148146
add_executable(zone-bench src/bench.c src/fallback/bench.c)
149147
target_include_directories(

include/zone.h

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -202,19 +202,6 @@ struct zone_table {
202202
const zone_symbol_t *symbols; // sorted for use with bsearch
203203
};
204204

205-
ZONE_EXPORT int
206-
zone_compare(const void *s1, const void *s2)
207-
zone_nonnull_all();
208-
209-
zone_always_inline()
210-
zone_nonnull_all()
211-
inline zone_symbol_t *zone_lookup(
212-
const zone_table_t *table, const zone_string_t *string)
213-
{
214-
const zone_symbol_t key = { *string, 0 };
215-
return bsearch(&key, table->symbols, table->length, sizeof(key), zone_compare);
216-
}
217-
218205
// @private
219206
//
220207
// bsearch is quite slow compared to a hash table, but a hash table is either
@@ -371,21 +358,6 @@ struct zone_type_info {
371358
#define ZONE_BLOCK_SIZE (64)
372359
#define ZONE_WINDOW_SIZE (256 * ZONE_BLOCK_SIZE) // 16KB
373360

374-
// @private
375-
// non-delimiting tokens may contain (escaped) newlines. tracking newlines
376-
// within tokens by taping them makes the lex operation more complex, resulting
377-
// in a significantly larger binary and slower operation, and may introduce an
378-
// infinite loop if the tape may not be sufficiently large enough. tokens
379-
// containing newlines is very much an edge case, therefore the scanner
380-
// implements an unlikely slow path that tracks the number of escaped newlines
381-
// during tokenization and registers them with each consecutive newline token.
382-
// this mode of operation nicely isolates location tracking in the scanner and
383-
// accommodates parallel processing should that ever be desired
384-
typedef struct zone_index zone_index_t;
385-
struct zone_index {
386-
const char *data;
387-
uint32_t newlines; // number of escaped newlines (stored per newline)
388-
};
389361

390362
// tape capacity must be large enough to hold every token from a single
391363
// worst-case read (e.g. 64 consecutive line feeds). in practice a single
@@ -405,6 +377,17 @@ struct zone_rdata_block {
405377
uint8_t octets[ 65535 + 4096 /* nsec padding */ ];
406378
};
407379

380+
// @private
381+
// non-delimiting tokens may contain (escaped) newlines. tracking newlines
382+
// within tokens by taping them makes the lex operation more complex, resulting
383+
// in a significantly larger binary and slower operation, and may introduce an
384+
// infinite loop if the tape may not be sufficiently large enough. tokens
385+
// containing newlines is very much an edge case, therefore the scanner
386+
// implements an unlikely slow path that tracks the number of escaped newlines
387+
// during tokenization and registers them with each consecutive newline token.
388+
// this mode of operation nicely isolates location tracking in the scanner and
389+
// accommodates parallel processing should that ever be desired
390+
408391
// @private
409392
typedef struct zone_file zone_file_t;
410393
struct zone_file {
@@ -413,9 +396,13 @@ struct zone_file {
413396
uint16_t last_type;
414397
uint32_t last_ttl, default_ttl;
415398
uint16_t last_class;
416-
size_t line;
417-
const char *name;
418-
const char *path;
399+
// non-terminating line feeds, i.e. escaped line feeds, line feeds in quoted
400+
// sections or within parentheses, are counted, but deferred for consistency
401+
// in error reports
402+
size_t span; /**< number of lines spanned by record */
403+
size_t line; /**< starting line of record */
404+
char *name;
405+
char *path;
419406
FILE *handle;
420407
bool grouped;
421408
bool start_of_line;
@@ -426,15 +413,15 @@ struct zone_file {
426413
} buffer;
427414
// indexer state is kept per-file
428415
struct {
429-
uint32_t newlines; // number of escaped newlines
430416
uint64_t in_comment;
431417
uint64_t in_quoted;
432418
uint64_t is_escaped;
433419
uint64_t follows_contiguous;
434-
// vector of tokens generated by the indexer. guaranteed to be large
435-
// enough to hold every token for a single read + terminators
436-
zone_index_t *head, *tail, tape[ZONE_TAPE_SIZE + 2];
437-
} indexer;
420+
} state;
421+
// vector of tokens generated by the indexer. guaranteed to be large
422+
// enough to hold every token for a single read + terminators
423+
struct { const char **head, **tail, *tape[ZONE_TAPE_SIZE + 2]; } fields;
424+
struct { uint16_t *head, *tail, tape[ZONE_TAPE_SIZE + 1]; } lines;
438425
};
439426

440427
typedef struct zone_parser zone_parser_t;

include/zone/attributes.h

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,38 +40,29 @@
4040
#endif
4141

4242
#define zone_nonnull(params) zone_attribute((__nonnull__ params))
43-
#define zone_nonnull_all() zone_attribute((__nonnull__))
43+
#define zone_nonnull_all zone_attribute((__nonnull__))
4444

4545
#if _MSC_VER
46-
# define zone_always_inline() __forceinline
47-
# define zone_never_inline() __declspec(noinline)
48-
# define zone_noreturn() __declspec(noreturn)
49-
# define zone_allocator(...)
46+
# define zone_really_inline __forceinline
47+
# define zone_never_inline __declspec(noinline)
48+
# define zone_warn_unused_result
5049

51-
# define zone_unlikely(x)
50+
# define zone_likely(params) (params)
51+
# define zone_unlikely(params) (params)
5252

5353
# define zone_format(params)
5454
# define zone_format_printf(string_index, first_to_check)
5555
#else // _MSC_VER
56-
# define zone_always_inline() zone_attribute((always_inline))
57-
# define zone_never_inline() zone_attribute((noinline))
58-
# if zone_has_attribute(noreturn)
59-
# define zone_noreturn() zone_attribute((noreturn))
56+
# define zone_really_inline inline zone_attribute((always_inline))
57+
# define zone_never_inline zone_attribute((noinline))
58+
# if zone_has_attribute(warn_unused_result)
59+
# define zone_warn_unused_result zone_attribute((warn_unused_result))
6060
# else
61-
# define zone_noreturn()
61+
# define zone_warn_unused_result
6262
# endif
6363

64-
# if zone_has_attribute(malloc)
65-
# if zone_gcc
66-
# define zone_allocator(...) zone_attribute((malloc(__VA_ARGS__)))
67-
# else
68-
# define zone_allocator(...) zone_attribute((malloc))
69-
# endif
70-
# else
71-
# define zone_allocator(...)
72-
# endif
73-
74-
# define zone_unlikely(params) __builtin_expect((params), 0)
64+
# define zone_likely(params) __builtin_expect(!!(params), 1)
65+
# define zone_unlikely(params) __builtin_expect(!!(params), 0)
7566

7667
# if zone_has_attribute(format)
7768
# define zone_format(params) zone_attribute((__format__ params))

src/bench.c

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*
88
*/
99
#include <assert.h>
10-
#include <setjmp.h>
1110
#include <stdio.h>
1211
#include <stdlib.h>
1312
#include <string.h>
@@ -21,31 +20,32 @@
2120
#include "zone.h"
2221
#include "config.h"
2322
#include "isadetection.h"
23+
#include "diagnostic.h"
2424

2525
#if _WIN32
2626
#define strcasecmp(s1, s2) _stricmp(s1, s2)
2727
#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
2828
#endif
2929

3030
#if HAVE_HASWELL
31-
extern zone_return_t zone_bench_haswell_lex(zone_parser_t *, size_t *);
32-
extern zone_return_t zone_haswell_parse(zone_parser_t *, void *);
31+
extern int32_t zone_bench_haswell_lex(zone_parser_t *, size_t *);
32+
extern int32_t zone_haswell_parse(zone_parser_t *);
3333
#endif
3434

3535
#if HAVE_WESTMERE
36-
extern zone_return_t zone_bench_westmere_lex(zone_parser_t *, size_t *);
37-
extern zone_return_t zone_westmere_parse(zone_parser_t *, void *);
36+
extern int32_t zone_bench_westmere_lex(zone_parser_t *, size_t *);
37+
extern int32_t zone_westmere_parse(zone_parser_t *);
3838
#endif
3939

40-
extern zone_return_t zone_bench_fallback_lex(zone_parser_t *, size_t *);
41-
extern zone_return_t zone_fallback_parse(zone_parser_t *, void *);
40+
extern int32_t zone_bench_fallback_lex(zone_parser_t *, size_t *);
41+
extern int32_t zone_fallback_parse(zone_parser_t *);
4242

4343
typedef struct target target_t;
4444
struct target {
4545
const char *name;
4646
uint32_t instruction_set;
47-
zone_return_t (*bench_lex)(zone_parser_t *, size_t *);
48-
zone_return_t (*parse)(zone_parser_t *, void *);
47+
int32_t (*bench_lex)(zone_parser_t *, size_t *);
48+
int32_t (*parse)(zone_parser_t *);
4949
};
5050

5151
static const target_t targets[] = {
@@ -58,7 +58,7 @@ static const target_t targets[] = {
5858
{ "fallback", 0, &zone_bench_fallback_lex, &zone_fallback_parse }
5959
};
6060

61-
extern zone_return_t zone_open(
61+
extern int32_t zone_open(
6262
zone_parser_t *,
6363
const zone_options_t *,
6464
zone_cache_t *,
@@ -68,29 +68,19 @@ extern zone_return_t zone_open(
6868
extern void zone_close(
6969
zone_parser_t *);
7070

71-
static zone_return_t bench_lex(zone_parser_t *parser, const target_t *target)
71+
static int32_t bench_lex(zone_parser_t *parser, const target_t *target)
7272
{
7373
size_t tokens = 0;
74-
zone_return_t result;
75-
volatile jmp_buf environment;
76-
77-
switch ((result = setjmp((void *)environment))) {
78-
case 0:
79-
parser->environment = environment;
80-
result = target->bench_lex(parser, &tokens);
81-
assert(result == ZONE_SUCCESS);
82-
break;
83-
default:
84-
assert(result < 0);
85-
assert(parser->environment == environment);
86-
break;
87-
}
74+
int32_t result;
75+
76+
if ((result = target->bench_lex(parser, &tokens)) < 0)
77+
return result;
8878

8979
printf("Lexed %zu tokens\n", tokens);
90-
return result;
80+
return 0;
9181
}
9282

93-
static zone_return_t bench_accept(
83+
static int32_t bench_accept(
9484
zone_parser_t *parser,
9585
const zone_name_t *owner,
9686
uint16_t type,
@@ -111,28 +101,21 @@ static zone_return_t bench_accept(
111101
return ZONE_SUCCESS;
112102
}
113103

114-
static zone_return_t bench_parse(zone_parser_t *parser, const target_t *target)
104+
static int32_t bench_parse(zone_parser_t *parser, const target_t *target)
115105
{
116106
size_t records = 0;
117-
zone_return_t result;
118-
volatile jmp_buf environment;
119-
120-
switch ((result = setjmp((void *)environment))) {
121-
case 0:
122-
parser->environment = environment;
123-
result = target->parse(parser, &records);
124-
assert(result == ZONE_SUCCESS);
125-
break;
126-
default:
127-
assert(result < 0);
128-
assert(parser->environment == environment);
129-
break;
130-
}
107+
int32_t result;
108+
109+
parser->user_data = &records;
110+
result = target->parse(parser);
131111

132112
printf("Parsed %zu records\n", records);
133113
return result;
134114
}
135115

116+
diagnostic_push()
117+
msvc_diagnostic_ignored(4996)
118+
136119
static const target_t *select_target(const char *name)
137120
{
138121
const size_t n = sizeof(targets)/sizeof(targets[0]);
@@ -160,6 +143,8 @@ static const target_t *select_target(const char *name)
160143
return target;
161144
}
162145

146+
diagnostic_pop()
147+
163148
static void help(const char *program)
164149
{
165150
const char *format =
@@ -207,7 +192,7 @@ int main(int argc, char *argv[])
207192
if (optind > argc || argc - optind < 2)
208193
usage(program);
209194

210-
zone_return_t (*bench)(zone_parser_t *, const target_t *) = 0;
195+
int32_t (*bench)(zone_parser_t *, const target_t *) = 0;
211196
if (strcasecmp(argv[optind], "lex") == 0)
212197
bench = &bench_lex;
213198
else if (strcasecmp(argv[optind], "parse") == 0)

src/diagnostic.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
#if _MSC_VER
1313
# define diagnostic_push() \
1414
__pragma(warning(push))
15-
# define msvc_diagnostic_ignored(warning) \
16-
__pragma(warning(disable: ## warning))
15+
# define msvc_diagnostic_ignored(warning_specifier) \
16+
__pragma(warning(disable:warning_specifier))
1717
# define diagnostic_pop() \
1818
__pragma(warning(pop))
1919
#elif __GNUC__

src/fallback/bench.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@
1515
diagnostic_push()
1616
clang_diagnostic_ignored(missing-prototypes)
1717

18-
zone_return_t zone_bench_fallback_lex(zone_parser_t *parser, size_t *tokens)
18+
int32_t zone_bench_fallback_lex(zone_parser_t *parser, size_t *tokens)
1919
{
20-
zone_token_t token;
21-
zone_return_t result;
20+
token_t token;
2221

2322
(*tokens) = 0;
24-
while ((result = lex(parser, &token)) >= 0 && token.data != zone_end_of_file)
23+
lex(parser, &token);
24+
while (token.code > 0) {
2525
(*tokens)++;
26+
lex(parser, &token);
27+
}
2628

27-
return result;
29+
return token.code ? -1 : 0;
2830
}
2931

3032
diagnostic_pop()

0 commit comments

Comments
 (0)