Skip to content

Commit 9dc9561

Browse files
authored
Print all warnings with error_on_warning (VirusTotal#157)
1 parent fa3795f commit 9dc9561

File tree

1 file changed

+50
-36
lines changed

1 file changed

+50
-36
lines changed

yara-python.c

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,20 @@ typedef long Py_hash_t;
4747

4848
#if PY_MAJOR_VERSION >= 3
4949
#define PY_STRING(x) PyUnicode_DecodeUTF8(x, strlen(x), "ignore" )
50+
#define PY_STRING_FORMAT(...) PyUnicode_FromFormat(__VA_ARGS__)
5051
#define PY_STRING_TO_C(x) PyUnicode_AsUTF8(x)
5152
#define PY_STRING_CHECK(x) PyUnicode_Check(x)
5253
#else
5354
#define PY_STRING(x) PyString_FromString(x)
55+
#define PY_STRING_FORMAT(...) PyString_FromFormat(__VA_ARGS__)
5456
#define PY_STRING_TO_C(x) PyString_AsString(x)
5557
#define PY_STRING_CHECK(x) (PyString_Check(x) || PyUnicode_Check(x))
5658
#endif
5759

60+
#if PY_VERSION_HEX < 0x03020000
61+
#define PyDescr_NAME(x) (((PyDescrObject*)x)->d_name)
62+
#endif
63+
5864
/* Module globals */
5965

6066
static PyObject* YaraError = NULL;
@@ -1694,33 +1700,6 @@ void raise_exception_on_error(
16941700
const YR_RULE* rule,
16951701
const char* message,
16961702
void* user_data)
1697-
{
1698-
if (error_level == YARA_ERROR_LEVEL_ERROR)
1699-
{
1700-
if (file_name != NULL)
1701-
PyErr_Format(
1702-
YaraSyntaxError,
1703-
"%s(%d): %s",
1704-
file_name,
1705-
line_number,
1706-
message);
1707-
else
1708-
PyErr_Format(
1709-
YaraSyntaxError,
1710-
"line %d: %s",
1711-
line_number,
1712-
message);
1713-
}
1714-
}
1715-
1716-
1717-
void raise_exception_on_error_or_warning(
1718-
int error_level,
1719-
const char* file_name,
1720-
int line_number,
1721-
const YR_RULE* rule,
1722-
const char* message,
1723-
void* user_data)
17241703
{
17251704
if (error_level == YARA_ERROR_LEVEL_ERROR)
17261705
{
@@ -1740,22 +1719,25 @@ void raise_exception_on_error_or_warning(
17401719
}
17411720
else
17421721
{
1722+
PyObject* warnings = (PyObject*)user_data;
1723+
PyObject* warning_msg;
17431724
if (file_name != NULL)
1744-
PyErr_Format(
1745-
YaraWarningError,
1725+
warning_msg = PY_STRING_FORMAT(
17461726
"%s(%d): %s",
17471727
file_name,
17481728
line_number,
17491729
message);
17501730
else
1751-
PyErr_Format(
1752-
YaraWarningError,
1731+
warning_msg = PY_STRING_FORMAT(
17531732
"line %d: %s",
17541733
line_number,
17551734
message);
1735+
PyList_Append(warnings, warning_msg);
1736+
Py_DECREF(warning_msg);
17561737
}
17571738
}
17581739

1740+
17591741
////////////////////////////////////////////////////////////////////////////////
17601742

17611743
const char* yara_include_callback(
@@ -1951,6 +1933,8 @@ static PyObject* yara_compile(
19511933
char* filepath = NULL;
19521934
char* source = NULL;
19531935
char* ns = NULL;
1936+
PyObject* warnings = PyList_New(0);
1937+
bool warning_error = false;
19541938

19551939
if (PyArg_ParseTupleAndKeywords(
19561940
args,
@@ -1973,18 +1957,15 @@ static PyObject* yara_compile(
19731957
if (error != ERROR_SUCCESS)
19741958
return handle_error(error, NULL);
19751959

1976-
yr_compiler_set_callback(compiler, raise_exception_on_error, NULL);
1960+
yr_compiler_set_callback(compiler, raise_exception_on_error, warnings);
19771961

19781962
if (error_on_warning != NULL)
19791963
{
19801964
if (PyBool_Check(error_on_warning))
19811965
{
19821966
if (PyObject_IsTrue(error_on_warning) == 1)
19831967
{
1984-
yr_compiler_set_callback(
1985-
compiler,
1986-
raise_exception_on_error_or_warning,
1987-
NULL);
1968+
warning_error = true;
19881969
}
19891970
}
19901971
else
@@ -2170,6 +2151,13 @@ static PyObject* yara_compile(
21702151
"compile() takes 1 argument");
21712152
}
21722153

2154+
if (warning_error & PyList_Size(warnings) > 0)
2155+
{
2156+
PyErr_SetObject(YaraWarningError, warnings);
2157+
}
2158+
2159+
Py_DECREF(warnings);
2160+
21732161
if (PyErr_Occurred() == NULL)
21742162
{
21752163
rules = Rules_NEW();
@@ -2371,6 +2359,24 @@ static PyMethodDef yara_methods[] = {
23712359
ob = Py_InitModule3(name, methods, doc);
23722360
#endif
23732361

2362+
static PyObject* YaraWarningError_getwarnings(PyObject *self, void* closure)
2363+
{
2364+
PyObject *args = PyObject_GetAttrString(self, "args");
2365+
if (!args) {
2366+
return NULL;
2367+
}
2368+
2369+
PyObject* ret = PyTuple_GetItem(args, 0);
2370+
Py_XINCREF(ret);
2371+
Py_XDECREF(args);
2372+
return ret;
2373+
}
2374+
2375+
static PyGetSetDef YaraWarningError_getsetters[] = {
2376+
{"warnings", YaraWarningError_getwarnings, NULL, NULL, NULL},
2377+
{NULL}
2378+
};
2379+
23742380

23752381
MOD_INIT(yara)
23762382
{
@@ -2397,6 +2403,14 @@ MOD_INIT(yara)
23972403
YaraSyntaxError = PyErr_NewException("yara.SyntaxError", YaraError, NULL);
23982404
YaraTimeoutError = PyErr_NewException("yara.TimeoutError", YaraError, NULL);
23992405
YaraWarningError = PyErr_NewException("yara.WarningError", YaraError, NULL);
2406+
2407+
PyTypeObject *YaraWarningError_type = (PyTypeObject *)YaraWarningError;
2408+
PyObject* descr = PyDescr_NewGetSet(YaraWarningError_type, YaraWarningError_getsetters);
2409+
if (PyDict_SetItem(YaraWarningError_type->tp_dict, PyDescr_NAME(descr), descr) < 0) {
2410+
Py_DECREF(m);
2411+
Py_DECREF(descr);
2412+
}
2413+
Py_DECREF(descr);
24002414
#else
24012415
YaraError = Py_BuildValue("s", "yara.Error");
24022416
YaraSyntaxError = Py_BuildValue("s", "yara.SyntaxError");

0 commit comments

Comments
 (0)