struct PacketContextData *current_json = pa_array[i].json_info;
while (current_json) {
struct PacketContextData *next_json = current_json->next;
+ SCFree(current_json->json_string);
SCFree(current_json);
current_json = next_json;
}
struct PacketContextData *allocated_json = pa_array[i].json_info;
while (allocated_json) {
struct PacketContextData *next_json = allocated_json->next;
+ SCFree(allocated_json->json_string);
SCFree(allocated_json);
allocated_json = next_json;
}
if (r.json.len > 0) {
/* we need to add 3 on length check for the added quotes and colon when
building the json string */
- if ((det_ctx->json_content_len < SIG_JSON_CONTENT_ARRAY_LEN) &&
- (r.json.len + strlen(sd->json_key) + 3 < SIG_JSON_CONTENT_ITEM_LEN)) {
+ if (r.json.len + strlen(sd->json_key) + 3 < SIG_JSON_CONTENT_ITEM_LEN) {
+ if (DetectEngineThreadCtxGetJsonContext(det_ctx) < 0) {
+ DatajsonUnlockElt(&r);
+ return 0;
+ }
snprintf(det_ctx->json_content[det_ctx->json_content_len].json_content,
SIG_JSON_CONTENT_ITEM_LEN, "\"%s\":%s", sd->json_key, r.json.value);
det_ctx->json_content[det_ctx->json_content_len].id = sd->id;
det_ctx->json_content_len++;
+ SCLogDebug("Added json content %u (alloc length %u)", det_ctx->json_content_len,
+ det_ctx->json_content_capacity);
}
}
DatajsonUnlockElt(&r);
if (det_ctx->json_content_len) {
/* We have some JSON attached in the current detection so let's try
to see if some need to be used for current signature. */
- struct PacketContextData *current_json = SCCalloc(1, sizeof(struct PacketContextData));
- if (current_json == NULL) {
- /* Allocation error, let's return now */
- return -1;
- }
- pa->json_info = current_json;
- for (size_t i = 0; i < det_ctx->json_content_len; i++) {
+ struct PacketContextData *current_json = NULL;
+ for (uint8_t i = 0; i < det_ctx->json_content_len; i++) {
if (s == det_ctx->json_content[i].id) {
- if (current_json->json_string != NULL) {
+ SCLogDebug("signature %p, content index %u", s, i);
+ if (current_json == NULL) {
+ /* Allocate the first one */
+ current_json = SCCalloc(1, sizeof(struct PacketContextData));
+ if (current_json == NULL) {
+ /* Allocation error, let's return now */
+ return -1;
+ }
+ if (pa->json_info == NULL) {
+ /* If this is the first one, set it */
+ pa->json_info = current_json;
+ }
+ current_json->next = NULL;
+ } else {
+ /* Allocate the next one */
struct PacketContextData *next_json =
SCCalloc(1, sizeof(struct PacketContextData));
if (next_json) {
return -1;
}
}
- current_json->json_string = det_ctx->json_content[i].json_content;
+ current_json->json_string = SCStrdup(det_ctx->json_content[i].json_content);
+ SCLogDebug("json content %u, value '%s' (%p)", (unsigned int)i,
+ current_json->json_string, s);
}
}
}
/* Register a counter for Lua memory limit errors. */
det_ctx->lua_memory_limit_errors = StatsRegisterCounter("detect.lua.memory_limit_errors", tv);
+ det_ctx->json_content = NULL;
+ det_ctx->json_content_capacity = 0;
+ det_ctx->json_content_len = 0;
+
#ifdef PROFILING
det_ctx->counter_mpm_list = StatsRegisterAvgCounter("detect.mpm_list", tv);
det_ctx->counter_nonmpm_list = StatsRegisterAvgCounter("detect.nonmpm_list", tv);
#endif
}
+ if (det_ctx->json_content) {
+ SCFree(det_ctx->json_content);
+ det_ctx->json_content = NULL;
+ det_ctx->json_content_capacity = 0;
+ }
+
AppLayerDecoderEventsFreeEvents(&det_ctx->decoder_events);
PrefilterPktNonPFStatsDump();
SCFree(det_ctx);
DetectEngineDeReference(&de_ctx);
}
+int DetectEngineThreadCtxGetJsonContext(DetectEngineThreadCtx *det_ctx)
+{
+ if (det_ctx->json_content_len > SIG_JSON_CONTENT_ARRAY_LEN - 1) {
+ SCLogDebug("json content length %u exceeds maximum %u", det_ctx->json_content_len,
+ SIG_JSON_CONTENT_ARRAY_LEN);
+ return -1;
+ }
+ if (det_ctx->json_content_len >= det_ctx->json_content_capacity) {
+ if (det_ctx->json_content_capacity == 0) {
+ det_ctx->json_content_capacity = 1;
+ } else {
+ det_ctx->json_content_capacity *= 2;
+ }
+ void *tmp = SCRealloc(
+ det_ctx->json_content, det_ctx->json_content_capacity * sizeof(SigJsonContent));
+ if (unlikely(tmp == NULL)) {
+ return -1;
+ }
+ SCLogDebug("reallocated json content array to %u items", det_ctx->json_content_capacity);
+ det_ctx->json_content = tmp;
+ }
+ return 0;
+}
+
/*************************************Unittest*********************************/
#ifdef UNITTESTS
DetectEngineCtx *DetectEngineCtxInitStubForDD(void);
DetectEngineCtx *DetectEngineCtxInitStubForMT(void);
void DetectEngineCtxFree(DetectEngineCtx *);
+int DetectEngineThreadCtxGetJsonContext(DetectEngineThreadCtx *det_ctx);
int DetectRegisterThreadCtxGlobalFuncs(const char *name,
void *(*InitFunc)(void *), void *data, void (*FreeFunc)(void *));
SCLogDebug("json key: %s", json_key);
/* Setup the data*/
- if ((det_ctx->json_content_len < SIG_JSON_CONTENT_ARRAY_LEN) &&
- (capture_len + strlen(json_key) + 5 < SIG_JSON_CONTENT_ITEM_LEN)) {
+ if (capture_len + strlen(json_key) + 5 < SIG_JSON_CONTENT_ITEM_LEN) {
+ if (DetectEngineThreadCtxGetJsonContext(det_ctx) < 0) {
+ SCFree(str_ptr);
+ return;
+ }
SCJsonBuilder *js = SCJbNewObject();
if (unlikely(js == NULL)) {
SCFree(str_ptr);
/* byte_* values */
uint64_t *byte_values;
- size_t json_content_len;
+ SigJsonContent *json_content;
+ uint8_t json_content_capacity;
+ uint8_t json_content_len;
/* counter for the filestore array below -- up here for cache reasons. */
uint16_t filestore_cnt;
/** stat of lua memory limit errors. */
uint16_t lua_memory_limit_errors;
- SigJsonContent json_content[SIG_JSON_CONTENT_ARRAY_LEN];
#ifdef DEBUG
uint64_t pkt_stream_add_cnt;
uint64_t payload_mpm_cnt;
SCJbOpenObject(js, "context");
const struct PacketContextData *json_info = pa->json_info;
while (json_info) {
+ SCLogDebug("JSON string '{%s}'", json_info->json_string);
/* The string is valid json as it is validated by JANSSON
during parsing and included later via a format string */
SCJbSetFormatted(js, json_info->json_string);