1 /*
2  * Copyright (c) 2018-2020, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *  * Redistributions of source code must retain the above copyright notice,
8  *    this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *  * Neither the name of Intel Corporation nor the names of its contributors
13  *    may be used to endorse or promote products derived from this software
14  *    without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #ifndef CH_COMMON_H_
30 #define CH_COMMON_H_
31 
32 #include "hs_common.h"
33 
34 #include <stdlib.h>
35 
36 /**
37  * @file
38  * @brief The Chimera common API definition.
39  *
40  * Chimera is a hybrid of Hyperscan and PCRE.
41  *
42  * This header contains functions available to both the Chimera compiler and
43  * runtime.
44  */
45 
46 #ifdef __cplusplus
47 extern "C"
48 {
49 #endif
50 
51 struct ch_database;
52 
53 /**
54  * A Chimera pattern database.
55  *
56  * Generated by one of the Chimera compiler functions:
57  *  - @ref ch_compile()
58  *  - @ref ch_compile_multi()
59  *  - @ref ch_compile_ext_multi()
60  */
61 typedef struct ch_database ch_database_t;
62 
63 /**
64  * A type for errors returned by Chimera functions.
65  */
66 typedef int ch_error_t;
67 
68 /**
69  * Free a compiled pattern database.
70  *
71  * The free callback set by @ref ch_set_allocator()) will be used by this
72  * function.
73  *
74  * @param db
75  *      A compiled pattern database. NULL may also be safely provided, in which
76  *      case the function does nothing.
77  *
78  * @return
79  *      @ref CH_SUCCESS on success, other values on failure.
80  */
81 ch_error_t HS_CDECL ch_free_database(ch_database_t *db);
82 
83 /**
84  * Utility function for identifying this release version.
85  *
86  * @return
87  *      A string containing the version number of this release build and the
88  *      date of the build. It is allocated statically, so it does not need to
89  *      be freed by the caller.
90  */
91 const char * HS_CDECL ch_version(void);
92 
93 /**
94  * Returns the size of the given database.
95  *
96  * @param database
97  *      Pointer to compiled expression database.
98  *
99  * @param database_size
100  *      On success, the size of the compiled database in bytes is placed in this
101  *      parameter.
102  *
103  * @return
104  *      @ref CH_SUCCESS on success, other values on failure.
105  */
106 ch_error_t HS_CDECL ch_database_size(const ch_database_t *database,
107                                      size_t *database_size);
108 
109 /**
110  * Utility function providing information about a database.
111  *
112  * @param database
113  *      Pointer to a compiled database.
114  *
115  * @param info
116  *      On success, a string containing the version and platform information for
117  *      the supplied database is placed in the parameter. The string is
118  *      allocated using the allocator supplied in @ref hs_set_allocator()
119  *      (or malloc() if no allocator was set) and should be freed by the caller.
120  *
121  * @return
122  *      @ref CH_SUCCESS on success, other values on failure.
123  */
124 ch_error_t HS_CDECL ch_database_info(const ch_database_t *database,
125                                      char **info);
126 
127 /**
128  * The type of the callback function that will be used by Chimera to allocate
129  * more memory at runtime as required.
130  *
131  * If Chimera is to be used in a multi-threaded, or similarly concurrent
132  * environment, the allocation function will need to be re-entrant, or
133  * similarly safe for concurrent use.
134  *
135  * @param size
136  *      The number of bytes to allocate.
137  * @return
138  *      A pointer to the region of memory allocated, or NULL on error.
139  */
140 typedef void *(HS_CDECL *ch_alloc_t)(size_t size);
141 
142 /**
143  * The type of the callback function that will be used by Chimera to free
144  * memory regions previously allocated using the @ref ch_alloc_t function.
145  *
146  * @param ptr
147  *      The region of memory to be freed.
148  */
149 typedef void (HS_CDECL *ch_free_t)(void *ptr);
150 
151 /**
152  * Set the allocate and free functions used by Chimera for allocating
153  * memory at runtime for stream state, scratch space, database bytecode,
154  * and various other data structure returned by the Chimera API.
155  *
156  * The function is equivalent to calling @ref ch_set_scratch_allocator(),
157  * @ref ch_set_database_allocator() and
158  * @ref ch_set_misc_allocator() with the provided parameters.
159  *
160  * This call will override any previous allocators that have been set.
161  *
162  * Note: there is no way to change the allocator used for temporary objects
163  * created during the various compile calls (@ref ch_compile() and @ref
164  * ch_compile_multi()).
165  *
166  * @param alloc_func
167  *      A callback function pointer that allocates memory. This function must
168  *      return memory suitably aligned for the largest representable data type
169  *      on this platform.
170  *
171  * @param free_func
172  *      A callback function pointer that frees allocated memory.
173  *
174  * @return
175  *      @ref CH_SUCCESS on success, other values on failure.
176  */
177 ch_error_t HS_CDECL ch_set_allocator(ch_alloc_t alloc_func,
178                                      ch_free_t free_func);
179 
180 /**
181  * Set the allocate and free functions used by Chimera for allocating memory
182  * for database bytecode produced by the compile calls (@ref ch_compile() and @ref
183  * ch_compile_multi()).
184  *
185  * If no database allocation functions are set, or if NULL is used in place of
186  * both parameters, then memory allocation will default to standard methods
187  * (such as the system malloc() and free() calls).
188  *
189  * This call will override any previous database allocators that have been set.
190  *
191  * Note: the database allocator may also be set by calling @ref
192  * ch_set_allocator().
193  *
194  * Note: there is no way to change how temporary objects created during the
195  * various compile calls (@ref ch_compile() and @ref ch_compile_multi()) are
196  * allocated.
197  *
198  * @param alloc_func
199  *      A callback function pointer that allocates memory. This function must
200  *      return memory suitably aligned for the largest representable data type
201  *      on this platform.
202  *
203  * @param free_func
204  *      A callback function pointer that frees allocated memory.
205  *
206  * @return
207  *      @ref HS_SUCCESS on success, other values on failure.
208  */
209 ch_error_t HS_CDECL ch_set_database_allocator(ch_alloc_t alloc_func,
210                                               ch_free_t free_func);
211 
212 /**
213  * Set the allocate and free functions used by Chimera for allocating memory
214  * for items returned by the Chimera API such as @ref ch_compile_error_t.
215  *
216  * If no misc allocation functions are set, or if NULL is used in place of both
217  * parameters, then memory allocation will default to standard methods (such as
218  * the system malloc() and free() calls).
219  *
220  * This call will override any previous misc allocators that have been set.
221  *
222  * Note: the misc allocator may also be set by calling @ref ch_set_allocator().
223  *
224  * @param alloc_func
225  *      A callback function pointer that allocates memory. This function must
226  *      return memory suitably aligned for the largest representable data type
227  *      on this platform.
228  *
229  * @param free_func
230  *      A callback function pointer that frees allocated memory.
231  *
232  * @return
233  *      @ref CH_SUCCESS on success, other values on failure.
234  */
235 ch_error_t HS_CDECL ch_set_misc_allocator(ch_alloc_t alloc_func,
236                                           ch_free_t free_func);
237 
238 /**
239  * Set the allocate and free functions used by Chimera for allocating memory
240  * for scratch space by @ref ch_alloc_scratch() and @ref ch_clone_scratch().
241  *
242  * If no scratch allocation functions are set, or if NULL is used in place of
243  * both parameters, then memory allocation will default to standard methods
244  * (such as the system malloc() and free() calls).
245  *
246  * This call will override any previous scratch allocators that have been set.
247  *
248  * Note: the scratch allocator may also be set by calling @ref
249  * ch_set_allocator().
250  *
251  * @param alloc_func
252  *      A callback function pointer that allocates memory. This function must
253  *      return memory suitably aligned for the largest representable data type
254  *      on this platform.
255  *
256  * @param free_func
257  *      A callback function pointer that frees allocated memory.
258  *
259  * @return
260  *      @ref CH_SUCCESS on success, other values on failure.
261  */
262 ch_error_t HS_CDECL ch_set_scratch_allocator(ch_alloc_t alloc_func,
263                                              ch_free_t free_func);
264 
265 /**
266  * @defgroup CH_ERROR ch_error_t values
267  *
268  * @{
269  */
270 
271 /**
272  * The engine completed normally.
273  */
274 #define CH_SUCCESS              0
275 
276 /**
277  * A parameter passed to this function was invalid.
278  */
279 #define CH_INVALID              (-1)
280 
281 /**
282  * A memory allocation failed.
283  */
284 #define CH_NOMEM                (-2)
285 
286 /**
287  * The engine was terminated by callback.
288  *
289  * This return value indicates that the target buffer was partially scanned,
290  * but that the callback function requested that scanning cease after a match
291  * was located.
292  */
293 #define CH_SCAN_TERMINATED      (-3)
294 
295 /**
296  * The pattern compiler failed, and the @ref ch_compile_error_t should be
297  * inspected for more detail.
298  */
299 #define CH_COMPILER_ERROR       (-4)
300 
301 /**
302  * The given database was built for a different version of the Chimera matcher.
303  */
304 #define CH_DB_VERSION_ERROR     (-5)
305 
306 /**
307  * The given database was built for a different platform (i.e., CPU type).
308  */
309 #define CH_DB_PLATFORM_ERROR    (-6)
310 
311 /**
312  * The given database was built for a different mode of operation.  This error
313  * is returned when streaming calls are used with a non-streaming database and
314  * vice versa.
315  */
316 #define CH_DB_MODE_ERROR        (-7)
317 
318 /**
319  * A parameter passed to this function was not correctly aligned.
320  */
321 #define CH_BAD_ALIGN            (-8)
322 
323 /**
324  * The memory allocator did not correctly return memory suitably aligned for
325  * the largest representable data type on this platform.
326  */
327 #define CH_BAD_ALLOC            (-9)
328 
329 /**
330  * The scratch region was already in use.
331  *
332  * This error is returned when Chimera is able to detect that the scratch
333  * region given is already in use by another Chimera API call.
334  *
335  * A separate scratch region, allocated with @ref ch_alloc_scratch() or @ref
336  * ch_clone_scratch(), is required for every concurrent caller of the Chimera
337  * API.
338  *
339  * For example, this error might be returned when @ref ch_scan() has been
340  * called inside a callback delivered by a currently-executing @ref ch_scan()
341  * call using the same scratch region.
342  *
343  * Note: Not all concurrent uses of scratch regions may be detected. This error
344  * is intended as a best-effort debugging tool, not a guarantee.
345  */
346 #define CH_SCRATCH_IN_USE       (-10)
347 
348 /**
349  * Unexpected internal error from Hyperscan.
350  *
351  * This error indicates that there was unexpected matching behaviors from
352  * Hyperscan. This could be related to invalid usage of scratch space or
353  * invalid memory operations by users.
354  *
355  */
356 #define CH_UNKNOWN_HS_ERROR     (-13)
357 
358 /**
359  * Returned when pcre_exec (called for some expressions internally from @ref
360  * ch_scan) failed due to a fatal error.
361  */
362 #define CH_FAIL_INTERNAL        (-32)
363 
364 /** @} */
365 
366 #ifdef __cplusplus
367 } /* extern "C" */
368 #endif
369 
370 #endif /* CH_COMMON_H_ */
371