Skip to content

Commit 8230a70

Browse files
authored
CALLBACK_MSG_TOO_MANY_MATCHES now also passes rule identifier and rule (VirusTotal#181)
namespace identifier to the callback
1 parent dc838e2 commit 8230a70

File tree

1 file changed

+65
-5
lines changed

1 file changed

+65
-5
lines changed

yara-python.c

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ limitations under the License.
2222

2323
#if PY_VERSION_HEX >= 0x02060000
2424
#include "bytesobject.h"
25+
#include "structseq.h"
2526
#elif PY_VERSION_HEX < 0x02060000
2627
#define PyBytes_AsString PyString_AsString
2728
#define PyBytes_Check PyString_Check
@@ -421,6 +422,21 @@ typedef struct _CALLBACK_DATA
421422

422423
} CALLBACK_DATA;
423424

425+
static PyStructSequence_Field RuleString_Fields[] = {
426+
{"namespace", "Namespace of the rule"},
427+
{"rule", "Identifier of the rule"},
428+
{"string", "Identifier of the string"},
429+
{NULL}
430+
};
431+
432+
static PyStructSequence_Desc RuleString_Desc = {
433+
"RuleString",
434+
"Named tuple tying together rule identifier and string identifier",
435+
RuleString_Fields,
436+
(sizeof(RuleString_Fields) / sizeof(RuleString_Fields[0])) - 1
437+
};
438+
439+
static PyTypeObject RuleString_Type = {0};
424440

425441
// Forward declarations for handling module data.
426442
PyObject* convert_structure_to_python(
@@ -683,7 +699,11 @@ static int handle_too_many_matches(
683699
PyGILState_STATE gil_state = PyGILState_Ensure();
684700

685701
PyObject* warning_type = NULL;
686-
PyObject* identifier = NULL;
702+
PyObject* string_identifier = NULL;
703+
PyObject* rule_identifier = NULL;
704+
PyObject* namespace_identifier = NULL;
705+
PyObject* rule_string = NULL;
706+
YR_RULE* rule = NULL;
687707

688708
int result = CALLBACK_CONTINUE;
689709

@@ -705,14 +725,49 @@ static int handle_too_many_matches(
705725
{
706726
Py_INCREF(data->warnings_callback);
707727

708-
identifier = PyBytes_FromString(string->identifier);
728+
string_identifier = PY_STRING(string->identifier);
729+
730+
if (string_identifier == NULL)
731+
{
732+
result = CALLBACK_ERROR;
733+
goto _exit;
734+
}
735+
736+
rule = &context->rules->rules_table[string->rule_idx];
737+
rule_identifier = PY_STRING(rule->identifier);
738+
739+
if (rule_identifier == NULL)
740+
{
741+
result = CALLBACK_ERROR;
742+
goto _exit;
743+
}
744+
745+
namespace_identifier = PY_STRING(rule->ns->name);
709746

710-
if (identifier == NULL)
747+
if (namespace_identifier == NULL)
711748
{
712749
result = CALLBACK_ERROR;
713750
goto _exit;
714751
}
715752

753+
rule_string = PyStructSequence_New(&RuleString_Type);
754+
755+
if (rule_string == NULL)
756+
{
757+
result = CALLBACK_ERROR;
758+
goto _exit;
759+
}
760+
761+
PyStructSequence_SET_ITEM(rule_string, 0, namespace_identifier);
762+
PyStructSequence_SET_ITEM(rule_string, 1, rule_identifier);
763+
PyStructSequence_SET_ITEM(rule_string, 2, string_identifier);
764+
765+
// PyStructSequenece steals the reference so we NULL these
766+
// so that Py_XDECREF() can be used in _exit label
767+
namespace_identifier = NULL;
768+
rule_identifier = NULL;
769+
string_identifier = NULL;
770+
716771
warning_type = PyLong_FromLong(CALLBACK_MSG_TOO_MANY_MATCHES);
717772

718773
if (warning_type == NULL)
@@ -724,7 +779,7 @@ static int handle_too_many_matches(
724779
PyObject* callback_result = PyObject_CallFunctionObjArgs(
725780
data->warnings_callback,
726781
warning_type,
727-
identifier,
782+
rule_string,
728783
NULL);
729784

730785
if (callback_result != NULL)
@@ -748,7 +803,10 @@ static int handle_too_many_matches(
748803

749804
_exit:
750805

751-
Py_XDECREF(identifier);
806+
Py_XDECREF(namespace_identifier);
807+
Py_XDECREF(rule_identifier);
808+
Py_XDECREF(string_identifier);
809+
Py_XDECREF(rule_string);
752810
Py_XDECREF(warning_type);
753811
Py_XDECREF(data->warnings_callback);
754812

@@ -2563,6 +2621,8 @@ MOD_INIT(yara)
25632621
if (PyType_Ready(&Match_Type) < 0)
25642622
return MOD_ERROR_VAL;
25652623

2624+
PyStructSequence_InitType(&RuleString_Type, &RuleString_Desc);
2625+
25662626
PyModule_AddObject(m, "Rule", (PyObject*) &Rule_Type);
25672627
PyModule_AddObject(m, "Rules", (PyObject*) &Rules_Type);
25682628
PyModule_AddObject(m, "Match", (PyObject*) &Match_Type);

0 commit comments

Comments
 (0)