dfilter: Use exceptions for error handling in semcheck

Instead of checking for an error return and throwing the exception
then do it where the errors occurs. This takes advantage of the nice
properties of error exceptions to reduce the amount of error
checking code.
This commit is contained in:
João Valverde 2021-10-06 18:51:02 +01:00 committed by Wireshark GitLab Utility
parent 5fcdf25697
commit 4d2f469212
1 changed files with 98 additions and 156 deletions

View File

@ -38,6 +38,9 @@ check_param_entity(dfwork_t *dfw, stnode_t *st_node);
static void static void
check_function(dfwork_t *dfw, stnode_t *st_node); check_function(dfwork_t *dfw, stnode_t *st_node);
static fvalue_t *
mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, const char *s);
typedef gboolean (*FtypeCanFunc)(enum ftenum); typedef gboolean (*FtypeCanFunc)(enum ftenum);
/* Compares to ftenum_t's and decides if they're /* Compares to ftenum_t's and decides if they're
@ -134,22 +137,59 @@ compatible_ftypes(ftenum_t a, ftenum_t b)
} }
/* Gets an fvalue from a string, and sets the error message on failure. */ /* Gets an fvalue from a string, and sets the error message on failure. */
WS_RETNONNULL
static fvalue_t* static fvalue_t*
dfilter_fvalue_from_unparsed(dfwork_t *dfw, ftenum_t ftype, const char *s, gboolean allow_partial_value) dfilter_fvalue_from_unparsed(dfwork_t *dfw, ftenum_t ftype, stnode_t *st,
gboolean allow_partial_value, header_field_info *hfinfo_value_string)
{ {
/* fvalue_t *fv;
* Don't set the error message if it's already set. const char *s = stnode_data(st);
*/
return fvalue_from_unparsed(ftype, s, allow_partial_value, /* Don't set the error message if it's already set. */
fv = fvalue_from_unparsed(ftype, s, allow_partial_value,
dfw->error_message == NULL ? &dfw->error_message : NULL); dfw->error_message == NULL ? &dfw->error_message : NULL);
if (fv == NULL && hfinfo_value_string) {
/* check value_string */
fv = mk_fvalue_from_val_string(dfw, hfinfo_value_string, s);
/*
* Ignore previous errors if this can be mapped
* to an item from value_string.
*/
if (fv && dfw->error_message) {
g_free(dfw->error_message);
dfw->error_message = NULL;
}
}
if (fv == NULL)
THROW(TypeError);
return fv;
} }
/* Gets an fvalue from a string, and sets the error message on failure. */ /* Gets an fvalue from a string, and sets the error message on failure. */
WS_RETNONNULL
static fvalue_t* static fvalue_t*
dfilter_fvalue_from_string(dfwork_t *dfw, ftenum_t ftype, const char *s) dfilter_fvalue_from_string(dfwork_t *dfw, ftenum_t ftype, stnode_t *st,
header_field_info *hfinfo_value_string)
{ {
return fvalue_from_string(ftype, s, fvalue_t *fv;
const char *s = stnode_data(st);
fv = fvalue_from_string(ftype, s,
dfw->error_message == NULL ? &dfw->error_message : NULL); dfw->error_message == NULL ? &dfw->error_message : NULL);
if (fv == NULL && hfinfo_value_string) {
fv = mk_fvalue_from_val_string(dfw, hfinfo_value_string, s);
/*
* Ignore previous errors if this can be mapped
* to an item from value_string.
*/
if (fv && dfw->error_message) {
g_free(dfw->error_message);
dfw->error_message = NULL;
}
}
if (fv == NULL)
THROW(TypeError);
return fv;
} }
/* Creates a FT_UINT32 fvalue with a given value. */ /* Creates a FT_UINT32 fvalue with a given value. */
@ -180,7 +220,7 @@ mk_uint64_fvalue(guint64 val)
* This works only for ftypes that are integers. Returns the created fvalue_t* * This works only for ftypes that are integers. Returns the created fvalue_t*
* or NULL if impossible. */ * or NULL if impossible. */
static fvalue_t* static fvalue_t*
mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, char *s) mk_fvalue_from_val_string(dfwork_t *dfw, header_field_info *hfinfo, const char *s)
{ {
static const true_false_string default_tf = { "True", "False" }; static const true_false_string default_tf = { "True", "False" };
const true_false_string *tf = &default_tf; const true_false_string *tf = &default_tf;
@ -385,12 +425,14 @@ is_bytes_type(enum ftenum type)
} }
/* Gets a GRegex from a string, and sets the error message on failure. */ /* Gets a GRegex from a string, and sets the error message on failure. */
WS_RETNONNULL
static GRegex* static GRegex*
dfilter_g_regex_from_string(dfwork_t *dfw, const char *s) dfilter_g_regex_from_string(dfwork_t *dfw, stnode_t *st)
{ {
GError *regex_error = NULL; GError *regex_error = NULL;
GRegexCompileFlags cflags = (GRegexCompileFlags)(G_REGEX_CASELESS | G_REGEX_OPTIMIZE); GRegexCompileFlags cflags = (GRegexCompileFlags)(G_REGEX_CASELESS | G_REGEX_OPTIMIZE);
GRegex *pcre; GRegex *pcre;
const char *s = stnode_data(st);
/* /*
* As FT_BYTES and FT_PROTOCOL contain arbitrary binary data * As FT_BYTES and FT_PROTOCOL contain arbitrary binary data
@ -421,7 +463,7 @@ dfilter_g_regex_from_string(dfwork_t *dfw, const char *s)
if (pcre) { if (pcre) {
g_regex_unref(pcre); g_regex_unref(pcre);
} }
return NULL; THROW(TypeError);
} }
return pcre; return pcre;
} }
@ -669,21 +711,27 @@ check_function(dfwork_t *dfw, stnode_t *st_node)
/* Convert a character constant to a 1-byte BYTE_STRING containing the /* Convert a character constant to a 1-byte BYTE_STRING containing the
* character. */ * character. */
WS_RETNONNULL
static fvalue_t * static fvalue_t *
dfilter_fvalue_from_charconst_string(dfwork_t *dfw, ftenum_t ftype, char *s, gboolean allow_partial_value) dfilter_fvalue_from_charconst_string(dfwork_t *dfw, ftenum_t ftype, stnode_t *st, gboolean allow_partial_value)
{ {
fvalue_t *fvalue; fvalue_t *fvalue;
const char *s = stnode_data(st);
fvalue = fvalue_from_unparsed(ftype, s, allow_partial_value,
dfw->error_message == NULL ? &dfw->error_message : NULL);
if (fvalue == NULL)
THROW(TypeError);
fvalue = dfilter_fvalue_from_unparsed(dfw, FT_CHAR, s, allow_partial_value);
if (fvalue) {
char *temp_string; char *temp_string;
/* It's valid. Create a 1-byte BYTE_STRING from its value. */ /* It's valid. Create a 1-byte BYTE_STRING from its value. */
temp_string = g_strdup_printf("%02x", fvalue->value.uinteger); temp_string = g_strdup_printf("%02x", fvalue->value.uinteger);
FVALUE_FREE(fvalue); FVALUE_FREE(fvalue);
fvalue = dfilter_fvalue_from_unparsed(dfw, ftype, temp_string, allow_partial_value); fvalue = fvalue_from_unparsed(ftype, temp_string, allow_partial_value, NULL);
ws_assert(fvalue);
g_free(temp_string); g_free(temp_string);
}
return (fvalue); return fvalue;
} }
/* If the LHS of a relation test is a FIELD, run some checks /* If the LHS of a relation test is a FIELD, run some checks
@ -700,7 +748,6 @@ check_relation_LHS_FIELD(dfwork_t *dfw, const char *relation_string,
ftenum_t ftype1, ftype2; ftenum_t ftype1, ftype2;
fvalue_t *fvalue; fvalue_t *fvalue;
GRegex *pcre; GRegex *pcre;
char *s;
type2 = stnode_type_id(st_arg2); type2 = stnode_type_id(st_arg2);
@ -739,13 +786,9 @@ check_relation_LHS_FIELD(dfwork_t *dfw, const char *relation_string,
} }
else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED || else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED ||
type2 == STTYPE_CHARCONST) { type2 == STTYPE_CHARCONST) {
s = (char *)stnode_data(st_arg2);
if (strcmp(relation_string, "matches") == 0) { if (strcmp(relation_string, "matches") == 0) {
/* Convert to a GRegex */ /* Convert to a GRegex */
pcre = dfilter_g_regex_from_string(dfw, s); pcre = dfilter_g_regex_from_string(dfw, st_arg2);
if (!pcre) {
THROW(TypeError);
}
stnode_replace(st_arg2, STTYPE_PCRE, pcre); stnode_replace(st_arg2, STTYPE_PCRE, pcre);
} else { } else {
/* Skip incompatible fields */ /* Skip incompatible fields */
@ -756,37 +799,18 @@ check_relation_LHS_FIELD(dfwork_t *dfw, const char *relation_string,
ftype1 = hfinfo1->type; ftype1 = hfinfo1->type;
} }
if (type2 == STTYPE_STRING) if (type2 == STTYPE_STRING) {
fvalue = dfilter_fvalue_from_string(dfw, ftype1, s); fvalue = dfilter_fvalue_from_string(dfw, ftype1, st_arg2, NULL);
}
else if (type2 == STTYPE_CHARCONST && else if (type2 == STTYPE_CHARCONST &&
strcmp(relation_string, "contains") == 0) { strcmp(relation_string, "contains") == 0) {
/* The RHS should be the same type as the LHS, /* The RHS should be the same type as the LHS,
* but a character is just a one-byte byte * but a character is just a one-byte byte
* string. */ * string. */
fvalue = dfilter_fvalue_from_charconst_string(dfw, ftype1, s, allow_partial_value); fvalue = dfilter_fvalue_from_charconst_string(dfw, ftype1, st_arg2, allow_partial_value);
} else
fvalue = dfilter_fvalue_from_unparsed(dfw, ftype1, s, allow_partial_value);
/*
* If this is a character constant, just report the
* error, don't try to treat it as a string from
* a value_string table.
*/
if (!fvalue && type2 != STTYPE_CHARCONST) {
/* check value_string */
fvalue = mk_fvalue_from_val_string(dfw, hfinfo1, s);
/*
* Ignore previous errors if this can be mapped
* to an item from value_string.
*/
if (fvalue && dfw->error_message) {
g_free(dfw->error_message);
dfw->error_message = NULL;
} }
} else {
if (!fvalue) { fvalue = dfilter_fvalue_from_unparsed(dfw, ftype1, st_arg2, allow_partial_value, hfinfo1);
THROW(TypeError);
} }
stnode_replace(st_arg2, STTYPE_FVALUE, fvalue); stnode_replace(st_arg2, STTYPE_FVALUE, fvalue);
} }
@ -884,7 +908,6 @@ check_relation_LHS_STRING(dfwork_t *dfw, const char* relation_string,
df_func_def_t *funcdef; df_func_def_t *funcdef;
ftenum_t ftype2; ftenum_t ftype2;
fvalue_t *fvalue; fvalue_t *fvalue;
char *s;
type2 = stnode_type_id(st_arg2); type2 = stnode_type_id(st_arg2);
@ -901,16 +924,7 @@ check_relation_LHS_STRING(dfwork_t *dfw, const char* relation_string,
THROW(TypeError); THROW(TypeError);
} }
s = (char*)stnode_data(st_arg1); fvalue = dfilter_fvalue_from_string(dfw, ftype2, st_arg1, hfinfo2);
fvalue = dfilter_fvalue_from_string(dfw, ftype2, s);
if (!fvalue) {
/* check value_string */
fvalue = mk_fvalue_from_val_string(dfw, hfinfo2, s);
if (!fvalue) {
THROW(TypeError);
}
}
stnode_replace(st_arg1, STTYPE_FVALUE, fvalue); stnode_replace(st_arg1, STTYPE_FVALUE, fvalue);
} }
else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED || else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED ||
@ -923,14 +937,12 @@ check_relation_LHS_STRING(dfwork_t *dfw, const char* relation_string,
} }
else if (type2 == STTYPE_RANGE) { else if (type2 == STTYPE_RANGE) {
check_drange_sanity(dfw, st_arg2); check_drange_sanity(dfw, st_arg2);
s = (char*)stnode_data(st_arg1); fvalue = dfilter_fvalue_from_string(dfw, FT_BYTES, st_arg1, NULL);
fvalue = dfilter_fvalue_from_string(dfw, FT_BYTES, s);
if (!fvalue) {
THROW(TypeError);
}
stnode_replace(st_arg1, STTYPE_FVALUE, fvalue); stnode_replace(st_arg1, STTYPE_FVALUE, fvalue);
} }
else if (type2 == STTYPE_FUNCTION) { else if (type2 == STTYPE_FUNCTION) {
check_function(dfw, st_arg2);
funcdef = sttype_function_funcdef(st_arg2); funcdef = sttype_function_funcdef(st_arg2);
ftype2 = funcdef->retval_ftype; ftype2 = funcdef->retval_ftype;
@ -941,14 +953,7 @@ check_relation_LHS_STRING(dfwork_t *dfw, const char* relation_string,
THROW(TypeError); THROW(TypeError);
} }
s = (char*)stnode_data(st_arg1); fvalue = dfilter_fvalue_from_string(dfw, ftype2, st_arg1, NULL);
fvalue = dfilter_fvalue_from_string(dfw, ftype2, s);
if (!fvalue) {
THROW(TypeError);
}
check_function(dfw, st_arg2);
stnode_replace(st_arg1, STTYPE_FVALUE, fvalue); stnode_replace(st_arg1, STTYPE_FVALUE, fvalue);
} }
else if (type2 == STTYPE_SET) { else if (type2 == STTYPE_SET) {
@ -971,7 +976,6 @@ check_relation_LHS_UNPARSED(dfwork_t *dfw, const char* relation_string,
df_func_def_t *funcdef; df_func_def_t *funcdef;
ftenum_t ftype2; ftenum_t ftype2;
fvalue_t *fvalue; fvalue_t *fvalue;
char *s;
type2 = stnode_type_id(st_arg2); type2 = stnode_type_id(st_arg2);
@ -988,16 +992,7 @@ check_relation_LHS_UNPARSED(dfwork_t *dfw, const char* relation_string,
THROW(TypeError); THROW(TypeError);
} }
s = (char*)stnode_data(st_arg1); fvalue = dfilter_fvalue_from_unparsed(dfw, ftype2, st_arg1, allow_partial_value, hfinfo2);
fvalue = dfilter_fvalue_from_unparsed(dfw, ftype2, s, allow_partial_value);
if (!fvalue) {
/* check value_string */
fvalue = mk_fvalue_from_val_string(dfw, hfinfo2, s);
if (!fvalue) {
THROW(TypeError);
}
}
stnode_replace(st_arg1, STTYPE_FVALUE, fvalue); stnode_replace(st_arg1, STTYPE_FVALUE, fvalue);
} }
else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED || else if (type2 == STTYPE_STRING || type2 == STTYPE_UNPARSED ||
@ -1010,14 +1005,12 @@ check_relation_LHS_UNPARSED(dfwork_t *dfw, const char* relation_string,
} }
else if (type2 == STTYPE_RANGE) { else if (type2 == STTYPE_RANGE) {
check_drange_sanity(dfw, st_arg2); check_drange_sanity(dfw, st_arg2);
s = (char*)stnode_data(st_arg1); fvalue = dfilter_fvalue_from_unparsed(dfw, FT_BYTES, st_arg1, allow_partial_value, NULL);
fvalue = dfilter_fvalue_from_unparsed(dfw, FT_BYTES, s, allow_partial_value);
if (!fvalue) {
THROW(TypeError);
}
stnode_replace(st_arg1, STTYPE_FVALUE, fvalue); stnode_replace(st_arg1, STTYPE_FVALUE, fvalue);
} }
else if (type2 == STTYPE_FUNCTION) { else if (type2 == STTYPE_FUNCTION) {
check_function(dfw, st_arg2);
funcdef = sttype_function_funcdef(st_arg2); funcdef = sttype_function_funcdef(st_arg2);
ftype2 = funcdef->retval_ftype; ftype2 = funcdef->retval_ftype;
@ -1027,15 +1020,7 @@ check_relation_LHS_UNPARSED(dfwork_t *dfw, const char* relation_string,
THROW(TypeError); THROW(TypeError);
} }
s = (char*)stnode_data(st_arg1); fvalue = dfilter_fvalue_from_unparsed(dfw, ftype2, st_arg1, allow_partial_value, NULL);
fvalue = dfilter_fvalue_from_unparsed(dfw, ftype2, s, allow_partial_value);
if (!fvalue) {
THROW(TypeError);
}
check_function(dfw, st_arg2);
stnode_replace(st_arg1, STTYPE_FVALUE, fvalue); stnode_replace(st_arg1, STTYPE_FVALUE, fvalue);
} }
else if (type2 == STTYPE_SET) { else if (type2 == STTYPE_SET) {
@ -1060,7 +1045,6 @@ check_relation_LHS_RANGE(dfwork_t *dfw, const char *relation_string,
ftenum_t ftype2; ftenum_t ftype2;
fvalue_t *fvalue; fvalue_t *fvalue;
GRegex *pcre; GRegex *pcre;
char *s;
ws_debug("5 check_relation_LHS_RANGE(%s)", relation_string); ws_debug("5 check_relation_LHS_RANGE(%s)", relation_string);
@ -1089,57 +1073,36 @@ check_relation_LHS_RANGE(dfwork_t *dfw, const char *relation_string,
} }
else if (type2 == STTYPE_STRING) { else if (type2 == STTYPE_STRING) {
ws_debug("5 check_relation_LHS_RANGE(type2 = STTYPE_STRING)"); ws_debug("5 check_relation_LHS_RANGE(type2 = STTYPE_STRING)");
s = (char*)stnode_data(st_arg2);
if (strcmp(relation_string, "matches") == 0) { if (strcmp(relation_string, "matches") == 0) {
/* Convert to a GRegex * */ /* Convert to a GRegex * */
pcre = dfilter_g_regex_from_string(dfw, s); pcre = dfilter_g_regex_from_string(dfw, st_arg2);
if (!pcre) {
THROW(TypeError);
}
stnode_replace(st_arg2, STTYPE_PCRE, pcre); stnode_replace(st_arg2, STTYPE_PCRE, pcre);
} else { } else {
fvalue = dfilter_fvalue_from_string(dfw, FT_BYTES, s); fvalue = dfilter_fvalue_from_string(dfw, FT_BYTES, st_arg2, NULL);
if (!fvalue) {
THROW(TypeError);
}
stnode_replace(st_arg2, STTYPE_FVALUE, fvalue); stnode_replace(st_arg2, STTYPE_FVALUE, fvalue);
} }
} }
else if (type2 == STTYPE_UNPARSED) { else if (type2 == STTYPE_UNPARSED) {
ws_debug("5 check_relation_LHS_RANGE(type2 = STTYPE_UNPARSED)"); ws_debug("5 check_relation_LHS_RANGE(type2 = STTYPE_UNPARSED)");
s = (char*)stnode_data(st_arg2);
if (strcmp(relation_string, "matches") == 0) { if (strcmp(relation_string, "matches") == 0) {
/* Convert to a GRegex */ /* Convert to a GRegex */
pcre = dfilter_g_regex_from_string(dfw, s); pcre = dfilter_g_regex_from_string(dfw, st_arg2);
if (!pcre) {
THROW(TypeError);
}
stnode_replace(st_arg2, STTYPE_PCRE, pcre); stnode_replace(st_arg2, STTYPE_PCRE, pcre);
} else { } else {
fvalue = dfilter_fvalue_from_unparsed(dfw, FT_BYTES, s, allow_partial_value); fvalue = dfilter_fvalue_from_unparsed(dfw, FT_BYTES, st_arg2, allow_partial_value, NULL);
if (!fvalue) {
THROW(TypeError);
}
stnode_replace(st_arg2, STTYPE_FVALUE, fvalue); stnode_replace(st_arg2, STTYPE_FVALUE, fvalue);
} }
} }
else if (type2 == STTYPE_CHARCONST) { else if (type2 == STTYPE_CHARCONST) {
ws_debug("5 check_relation_LHS_RANGE(type2 = STTYPE_CHARCONST)"); ws_debug("5 check_relation_LHS_RANGE(type2 = STTYPE_CHARCONST)");
s = (char*)stnode_data(st_arg2);
if (strcmp(relation_string, "matches") == 0) { if (strcmp(relation_string, "matches") == 0) {
/* Convert to a GRegex */ /* Convert to a GRegex */
pcre = dfilter_g_regex_from_string(dfw, s); pcre = dfilter_g_regex_from_string(dfw, st_arg2);
if (!pcre) {
THROW(TypeError);
}
stnode_replace(st_arg2, STTYPE_PCRE, pcre); stnode_replace(st_arg2, STTYPE_PCRE, pcre);
} else { } else {
/* The RHS should be FT_BYTES, but a character is just a /* The RHS should be FT_BYTES, but a character is just a
* one-byte byte string. */ * one-byte byte string. */
fvalue = dfilter_fvalue_from_charconst_string(dfw, FT_BYTES, s, allow_partial_value); fvalue = dfilter_fvalue_from_charconst_string(dfw, FT_BYTES, st_arg2, allow_partial_value);
if (!fvalue) {
THROW(TypeError);
}
stnode_replace(st_arg2, STTYPE_FVALUE, fvalue); stnode_replace(st_arg2, STTYPE_FVALUE, fvalue);
} }
} }
@ -1182,17 +1145,11 @@ check_param_entity(dfwork_t *dfw, stnode_t *st_node)
sttype_id_t e_type; sttype_id_t e_type;
stnode_t *new_st; stnode_t *new_st;
fvalue_t *fvalue; fvalue_t *fvalue;
char *s;
e_type = stnode_type_id(st_node); e_type = stnode_type_id(st_node);
/* If there's an unparsed string, change it to an FT_STRING */ /* If there's an unparsed string, change it to an FT_STRING */
if (e_type == STTYPE_UNPARSED || e_type == STTYPE_CHARCONST) { if (e_type == STTYPE_UNPARSED || e_type == STTYPE_CHARCONST) {
s = (char*)stnode_data(st_node); fvalue = dfilter_fvalue_from_unparsed(dfw, FT_STRING, st_node, TRUE, NULL);
fvalue = dfilter_fvalue_from_unparsed(dfw, FT_STRING, s, FALSE);
if (!fvalue) {
THROW(TypeError);
}
new_st = stnode_new(STTYPE_FVALUE, fvalue, st_node->token_value); new_st = stnode_new(STTYPE_FVALUE, fvalue, st_node->token_value);
stnode_free(st_node); stnode_free(st_node);
return new_st; return new_st;
@ -1215,7 +1172,6 @@ check_relation_LHS_FUNCTION(dfwork_t *dfw, const char *relation_string,
ftenum_t ftype1, ftype2; ftenum_t ftype1, ftype2;
fvalue_t *fvalue; fvalue_t *fvalue;
GRegex *pcre; GRegex *pcre;
char *s;
df_func_def_t *funcdef; df_func_def_t *funcdef;
df_func_def_t *funcdef2; df_func_def_t *funcdef2;
/* GSList *params; */ /* GSList *params; */
@ -1255,36 +1211,22 @@ check_relation_LHS_FUNCTION(dfwork_t *dfw, const char *relation_string,
} }
} }
else if (type2 == STTYPE_STRING) { else if (type2 == STTYPE_STRING) {
s = (char*)stnode_data(st_arg2);
if (strcmp(relation_string, "matches") == 0) { if (strcmp(relation_string, "matches") == 0) {
/* Convert to a GRegex */ /* Convert to a GRegex */
pcre = dfilter_g_regex_from_string(dfw, s); pcre = dfilter_g_regex_from_string(dfw, st_arg2);
if (!pcre) {
THROW(TypeError);
}
stnode_replace(st_arg2, STTYPE_PCRE, pcre); stnode_replace(st_arg2, STTYPE_PCRE, pcre);
} else { } else {
fvalue = dfilter_fvalue_from_string(dfw, ftype1, s); fvalue = dfilter_fvalue_from_string(dfw, ftype1, st_arg2, NULL);
if (!fvalue) {
THROW(TypeError);
}
stnode_replace(st_arg2, STTYPE_FVALUE, fvalue); stnode_replace(st_arg2, STTYPE_FVALUE, fvalue);
} }
} }
else if (type2 == STTYPE_UNPARSED || type2 == STTYPE_CHARCONST) { else if (type2 == STTYPE_UNPARSED || type2 == STTYPE_CHARCONST) {
s = (char*)stnode_data(st_arg2);
if (strcmp(relation_string, "matches") == 0) { if (strcmp(relation_string, "matches") == 0) {
/* Convert to a GRegex */ /* Convert to a GRegex */
pcre = dfilter_g_regex_from_string(dfw, s); pcre = dfilter_g_regex_from_string(dfw, st_arg2);
if (!pcre) {
THROW(TypeError);
}
stnode_replace(st_arg2, STTYPE_PCRE, pcre); stnode_replace(st_arg2, STTYPE_PCRE, pcre);
} else { } else {
fvalue = dfilter_fvalue_from_unparsed(dfw, ftype1, s, allow_partial_value); fvalue = dfilter_fvalue_from_unparsed(dfw, ftype1, st_arg2, allow_partial_value, NULL);
if (!fvalue) {
THROW(TypeError);
}
stnode_replace(st_arg2, STTYPE_FVALUE, fvalue); stnode_replace(st_arg2, STTYPE_FVALUE, fvalue);
} }
} }