|
35 | 35 | #include "utils/snapmgr.h" |
36 | 36 | #include "utils/timeout.h" |
37 | 37 |
|
38 | | -static void |
39 | | -exec_simple_query(const char *query_string) |
40 | | -{ |
| 38 | +static void exec_simple_query(const char *query_string) { |
41 | 39 | MemoryContext oldcontext; |
42 | | - List *parsetree_list; |
43 | | - ListCell *parsetree_item; |
44 | | - bool use_implicit_block; |
| 40 | + List *parsetree_list; |
| 41 | + ListCell *parsetree_item; |
45 | 42 |
|
46 | | - StartTransactionCommand(); |
47 | 43 | oldcontext = MemoryContextSwitchTo(MessageContext); |
48 | | - |
49 | 44 | parsetree_list = raw_parser(query_string, RAW_PARSE_TYPE_NAME); |
50 | 45 | MemoryContextSwitchTo(oldcontext); |
51 | 46 |
|
52 | | - use_implicit_block = (list_length(parsetree_list) > 1); |
53 | | - |
54 | | - foreach(parsetree_item, parsetree_list) |
55 | | - { |
56 | | - RawStmt *parsetree = lfirst_node(RawStmt, parsetree_item); |
57 | | - bool snapshot_set = false; |
58 | | - MemoryContext per_parsetree_context = NULL; |
59 | | - List *querytree_list, |
60 | | - *plantree_list; |
61 | | - |
62 | | - if (use_implicit_block) |
63 | | - BeginImplicitTransactionBlock(); |
64 | | - |
65 | | - if (analyze_requires_snapshot(parsetree)) |
66 | | - { |
67 | | - PushActiveSnapshot(GetTransactionSnapshot()); |
68 | | - snapshot_set = true; |
69 | | - } |
70 | | - |
71 | | - if (lnext(parsetree_list, parsetree_item) != NULL) |
72 | | - { |
73 | | - per_parsetree_context = |
74 | | - AllocSetContextCreate(MessageContext, |
75 | | - "per-parsetree message context", |
76 | | - ALLOCSET_DEFAULT_SIZES); |
77 | | - oldcontext = MemoryContextSwitchTo(per_parsetree_context); |
78 | | - } |
79 | | - else |
80 | | - oldcontext = MemoryContextSwitchTo(MessageContext); |
81 | | - |
82 | | - querytree_list = pg_analyze_and_rewrite_fixedparams(parsetree, query_string, |
83 | | - NULL, 0, NULL); |
84 | | - |
85 | | - plantree_list = pg_plan_queries(querytree_list, query_string, |
86 | | - CURSOR_OPT_PARALLEL_OK, NULL); |
87 | | - |
88 | | - if (per_parsetree_context){ |
89 | | - MemoryContextDelete(per_parsetree_context); |
90 | | - } |
91 | | - CommitTransactionCommand(); |
| 47 | + foreach (parsetree_item, parsetree_list) { |
| 48 | + RawStmt *parsetree = lfirst_node(RawStmt, parsetree_item); |
| 49 | + MemoryContext per_parsetree_context = NULL; |
| 50 | + List *querytree_list; |
| 51 | + |
| 52 | + if (lnext(parsetree_list, parsetree_item) != NULL) { |
| 53 | + per_parsetree_context = |
| 54 | + AllocSetContextCreate(MessageContext, "per-parsetree message context", ALLOCSET_DEFAULT_SIZES); |
| 55 | + oldcontext = MemoryContextSwitchTo(per_parsetree_context); |
| 56 | + } else { |
| 57 | + oldcontext = MemoryContextSwitchTo(MessageContext); |
92 | 58 | } |
93 | | -} |
94 | 59 |
|
| 60 | + querytree_list = pg_analyze_and_rewrite_fixedparams(parsetree, query_string, NULL, 0, NULL); |
| 61 | + pg_plan_queries(querytree_list, query_string, CURSOR_OPT_PARALLEL_OK, NULL); |
| 62 | + |
| 63 | + if (per_parsetree_context) { |
| 64 | + MemoryContextDelete(per_parsetree_context); |
| 65 | + } else { |
| 66 | + MemoryContextSwitchTo(oldcontext); |
| 67 | + } |
| 68 | + } |
| 69 | +} |
95 | 70 |
|
96 | 71 | int LLVMFuzzerInitialize(int *argc, char ***argv) { |
97 | | - FuzzerInitialize("query_db", argv); |
98 | | - return 0; |
| 72 | + MemoryContextInit(); |
| 73 | + InitializeGUCOptions(); |
| 74 | + InitializeMaxBackends(); |
| 75 | + |
| 76 | + MessageContext = AllocSetContextCreate(TopMemoryContext, |
| 77 | + "MessageContext", |
| 78 | + ALLOCSET_DEFAULT_SIZES); |
| 79 | + return 0; |
99 | 80 | } |
100 | 81 |
|
| 82 | +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
| 83 | + if (size == 0) |
| 84 | + return 0; |
101 | 85 |
|
102 | | -/* |
103 | | -** Main entry point. The fuzzer invokes this function with each |
104 | | -** fuzzed input. |
105 | | -*/ |
106 | | -int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
107 | | - char* query_string; |
108 | 86 | sigjmp_buf local_sigjmp_buf; |
109 | | - |
110 | | - query_string = (char*) calloc( (size+1), sizeof(char) ); |
| 87 | + char *query_string = (char *) calloc(size + 1, sizeof(char)); |
111 | 88 | memcpy(query_string, data, size); |
112 | 89 |
|
113 | | - if (!sigsetjmp(local_sigjmp_buf, 0)) |
114 | | - { |
115 | | - PG_exception_stack = &local_sigjmp_buf; |
116 | | - error_context_stack = NULL; |
117 | | - set_stack_base(); |
118 | | - |
119 | | - disable_all_timeouts(false); |
120 | | - QueryCancelPending = false; |
121 | | - pq_comm_reset(); |
122 | | - EmitErrorReport(); |
123 | | - |
124 | | - AbortCurrentTransaction(); |
125 | | - |
126 | | - PortalErrorCleanup(); |
127 | | - |
128 | | - jit_reset_after_error(); |
129 | | - |
130 | | - MemoryContextSwitchTo(TopMemoryContext); |
131 | | - FlushErrorState(); |
132 | | - |
133 | | - MemoryContextSwitchTo(MessageContext); |
134 | | - MemoryContextReset(MessageContext); |
135 | | - |
136 | | - InvalidateCatalogSnapshotConditionally(); |
137 | | - |
138 | | - SetCurrentStatementStartTimestamp(); |
139 | | - |
140 | | - exec_simple_query(query_string); |
141 | | - } |
| 90 | + if (!sigsetjmp(local_sigjmp_buf, 0)) { |
| 91 | + PG_exception_stack = &local_sigjmp_buf; |
| 92 | + error_context_stack = NULL; |
| 93 | + set_stack_base(); |
| 94 | + |
| 95 | + disable_all_timeouts(false); |
| 96 | + QueryCancelPending = false; |
| 97 | + pq_comm_reset(); |
| 98 | + EmitErrorReport(); |
| 99 | + jit_reset_after_error(); |
| 100 | + |
| 101 | + MemoryContextSwitchTo(TopMemoryContext); |
| 102 | + FlushErrorState(); |
| 103 | + MemoryContextSwitchTo(MessageContext); |
| 104 | + MemoryContextReset(MessageContext); |
| 105 | + SetCurrentStatementStartTimestamp(); |
| 106 | + |
| 107 | + exec_simple_query(query_string); |
| 108 | + } |
142 | 109 |
|
143 | 110 | free(query_string); |
144 | 111 | return 0; |
|
0 commit comments