1 /*
2  * Copyright (c) 2015-2016, 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 #include "config.h"
30 
31 #include "gtest/gtest.h"
32 #include "hs.h"
33 #include "test_util.h"
34 
35 #include <cstdlib>
36 #include <string>
37 
38 using std::string;
39 
null_malloc(size_t)40 static void *null_malloc(size_t) { return nullptr; }
41 
TEST(CustomAllocator,DatabaseInfoBadAlloc)42 TEST(CustomAllocator, DatabaseInfoBadAlloc) {
43     hs_database_t *db = buildDB("foobar", 0, 0, HS_MODE_BLOCK);
44     ASSERT_TRUE(db != nullptr);
45 
46     hs_set_allocator(null_malloc, nullptr);
47 
48     char *info = nullptr;
49     hs_error_t err = hs_database_info(db, &info);
50     ASSERT_EQ(HS_NOMEM, err);
51 
52     hs_set_allocator(nullptr, nullptr);
53     hs_free_database(db);
54 }
55 
56 static
two_aligned_malloc(size_t len)57 void * two_aligned_malloc(size_t len) {
58     void *mem = malloc(len + 2);
59     if (!mem) {
60         return nullptr;
61     }
62     return (char *)mem + 2;
63 }
64 
65 static
two_aligned_free(void * mem)66 void two_aligned_free(void *mem) {
67     if (!mem) {
68         return;
69     }
70     // Allocated with two_aligned_malloc above.
71     free((char *)mem - 2);
72 }
73 
TEST(CustomAllocator,TwoAlignedCompile)74 TEST(CustomAllocator, TwoAlignedCompile) {
75     hs_set_database_allocator(two_aligned_malloc, two_aligned_free);
76 
77     hs_database_t *db = nullptr;
78     hs_compile_error_t *compile_err = nullptr;
79     const hs_platform_info_t *platform = nullptr;
80     hs_error_t err =
81         hs_compile("foobar", 0, HS_MODE_BLOCK, platform, &db, &compile_err);
82     ASSERT_EQ(HS_COMPILER_ERROR, err);
83     ASSERT_EQ(nullptr, db);
84     ASSERT_NE(nullptr, compile_err);
85     hs_free_compile_error(compile_err);
86     hs_set_database_allocator(nullptr, nullptr);
87 }
88 
TEST(CustomAllocator,TwoAlignedCompileError)89 TEST(CustomAllocator, TwoAlignedCompileError) {
90     hs_set_misc_allocator(two_aligned_malloc, two_aligned_free);
91 
92     hs_database_t *db = nullptr;
93     hs_compile_error_t *compile_err = nullptr;
94     const hs_platform_info_t *platform = nullptr;
95     hs_error_t err =
96         hs_compile("\\1", 0, HS_MODE_BLOCK, platform, &db, &compile_err);
97     ASSERT_EQ(HS_COMPILER_ERROR, err);
98     ASSERT_EQ(nullptr, db);
99     ASSERT_NE(nullptr, compile_err);
100     EXPECT_STREQ("Allocator returned misaligned memory.", compile_err->message);
101     hs_free_compile_error(compile_err);
102     hs_set_database_allocator(nullptr, nullptr);
103 }
104 
TEST(CustomAllocator,TwoAlignedDatabaseInfo)105 TEST(CustomAllocator, TwoAlignedDatabaseInfo) {
106     hs_database_t *db = buildDB("foobar", 0, 0, HS_MODE_BLOCK);
107     ASSERT_TRUE(db != nullptr);
108 
109     hs_set_misc_allocator(two_aligned_malloc, two_aligned_free);
110 
111     char *info = nullptr;
112     hs_error_t err = hs_database_info(db, &info);
113     ASSERT_EQ(HS_BAD_ALLOC, err);
114 
115     hs_set_misc_allocator(nullptr, nullptr);
116     hs_free_database(db);
117 }
118 
TEST(CustomAllocator,TwoAlignedSerialize)119 TEST(CustomAllocator, TwoAlignedSerialize) {
120     hs_database_t *db = buildDB("foobar", 0, 0, HS_MODE_BLOCK);
121     ASSERT_TRUE(db != nullptr);
122 
123     hs_set_misc_allocator(two_aligned_malloc, two_aligned_free);
124 
125     char *bytes = nullptr;
126     size_t serialized_len = 0;
127     hs_error_t err = hs_serialize_database(db, &bytes, &serialized_len);
128     ASSERT_EQ(HS_BAD_ALLOC, err);
129 
130     hs_set_misc_allocator(nullptr, nullptr);
131     hs_free_database(db);
132 }
133 
TEST(CustomAllocator,TwoAlignedDeserialize)134 TEST(CustomAllocator, TwoAlignedDeserialize) {
135     hs_database_t *db = buildDB("foobar", 0, 0, HS_MODE_BLOCK);
136     ASSERT_TRUE(db != nullptr);
137 
138     char *bytes = nullptr;
139     size_t serialized_len = 0;
140     hs_error_t err = hs_serialize_database(db, &bytes, &serialized_len);
141     ASSERT_EQ(HS_SUCCESS, err);
142     ASSERT_NE(nullptr, bytes);
143 
144     hs_free_database(db);
145     db = nullptr;
146 
147     hs_set_database_allocator(two_aligned_malloc, two_aligned_free);
148 
149     err = hs_deserialize_database(bytes, serialized_len, &db);
150     ASSERT_EQ(HS_BAD_ALLOC, err);
151     ASSERT_EQ(nullptr, db);
152 
153     hs_set_database_allocator(nullptr, nullptr);
154 
155     free(bytes);
156 }
157 
TEST(CustomAllocator,TwoAlignedAllocScratch)158 TEST(CustomAllocator, TwoAlignedAllocScratch) {
159     hs_database_t *db = buildDB("foobar", 0, 0, HS_MODE_BLOCK);
160     ASSERT_TRUE(db != nullptr);
161 
162     hs_set_scratch_allocator(two_aligned_malloc, two_aligned_free);
163 
164     hs_scratch_t *scratch = nullptr;
165     hs_error_t err = hs_alloc_scratch(db, &scratch);
166     ASSERT_EQ(HS_BAD_ALLOC, err);
167 
168     hs_set_scratch_allocator(nullptr, nullptr);
169     hs_free_database(db);
170 }
171 
TEST(CustomAllocator,NullMallocExpressionInfo)172 TEST(CustomAllocator, NullMallocExpressionInfo) {
173     hs_set_allocator(null_malloc, nullptr);
174 
175     string pattern = "foobar";
176     hs_expr_info_t *info = nullptr;
177     hs_compile_error_t *c_err = nullptr;
178     hs_error_t err = hs_expression_info(pattern.c_str(), 0, &info, &c_err);
179     ASSERT_EQ(HS_COMPILER_ERROR, err);
180     ASSERT_NE(nullptr, c_err);
181     hs_free_compile_error(c_err);
182     hs_set_allocator(nullptr, nullptr);
183 }
184 
TEST(CustomAllocator,TwoAlignedExpressionInfo)185 TEST(CustomAllocator, TwoAlignedExpressionInfo) {
186     hs_set_misc_allocator(two_aligned_malloc, two_aligned_free);
187 
188     string pattern = "\\1";
189     hs_expr_info_t *info = nullptr;
190     hs_compile_error_t *c_err = nullptr;
191     hs_error_t err = hs_expression_info(pattern.c_str(), 0, &info, &c_err);
192     ASSERT_EQ(HS_COMPILER_ERROR, err);
193     ASSERT_NE(nullptr, c_err);
194     EXPECT_STREQ("Allocator returned misaligned memory.", c_err->message);
195     hs_free_compile_error(c_err);
196     hs_set_allocator(nullptr, nullptr);
197 }
198