[ZBX-11204] remove_param() breaks double quote escaping Created: 2016 Sep 14 Updated: 2017 May 30 Resolved: 2016 Sep 26 |
|
Status: | Closed |
Project: | ZABBIX BUGS AND ISSUES |
Component/s: | Server (S) |
Affects Version/s: | 2.2.15rc1, 3.0.5rc1, 3.2.1rc1, 3.4.0alpha1 |
Fix Version/s: | 2.2.15rc1, 3.0.5rc1, 3.2.1rc1, 3.4.0alpha1 |
Type: | Incident report | Priority: | Critical |
Reporter: | Glebs Ivanovskis (Inactive) | Assignee: | Unassigned |
Resolution: | Fixed | Votes: | 0 |
Labels: | calculateditems, codequality, count, macrocontext, triggerfunctions | ||
Remaining Estimate: | Not Specified | ||
Time Spent: | Not Specified | ||
Original Estimate: | Not Specified |
Description |
This function was completely broken in
As a result, calculated item count(dummy.echo[{$ECHO}],10m,"{$MACRO:\"with , and } characters\"}") was simply counting values ignoring pattern. Debug log wasn't very helpful: 4807:20160914:142725.827 In get_value_calculated() key:'dummy.echo.count' expression:'count(dummy.echo[{$ECHO}],10m,"{$MACRO:\"with , and } characters\"}")' 4807:20160914:142725.828 In calcitem_parse_expression() expression:'count(dummy.echo[{$ECHO}],10m,"{$MACRO:\"with , and } characters\"}")' 4807:20160914:142725.828 calcitem_parse_expression() functionid:1 function:'count(dummy.echo[{$ECHO}],10m,"{$MACRO:\"with , and } characters\"}")' 4807:20160914:142725.828 calcitem_parse_expression() expression:'{1}' 4807:20160914:142725.828 In substitute_simple_macros() data:'{1}' 4807:20160914:142725.828 End substitute_simple_macros() data:'{1}' 4807:20160914:142725.828 End of calcitem_parse_expression():SUCCEED 4807:20160914:142725.828 In calcitem_evaluate_expression() 4807:20160914:142725.828 calcitem_evaluate_expression() function:'lld macro test:dummy.echo[{$ECHO}].count(10m,"{$MACRO:"with , and } characters"}")' 4807:20160914:142725.828 In evaluate_function() function:'lld macro test:dummy.echo[{$ECHO}].count(10m,"{$MACRO:"with , and } characters"}")' 4807:20160914:142725.828 In evaluate_COUNT() 4807:20160914:142725.829 In __get_function_parameter_uint31() parameters:'10m,"{$MACRO:"with , and } characters"}"' Nparam:1 4807:20160914:142725.829 In substitute_simple_macros() data:'10m' 4807:20160914:142725.829 __get_function_parameter_uint31() flag:0 value:600 4807:20160914:142725.829 End of __get_function_parameter_uint31():SUCCEED 4807:20160914:142725.829 In zbx_vc_get_value_range() itemid:23934 value_type:4 seconds:600 count:0 timestamp:1473852445 4807:20160914:142725.829 End of zbx_vc_get_value_range():SUCCEED count:20 cached:1 4807:20160914:142725.829 End of evaluate_COUNT():SUCCEED 4807:20160914:142725.829 End of evaluate_function():SUCCEED value:'20' 4807:20160914:142725.829 End of calcitem_evaluate_expression():SUCCEED 4807:20160914:142725.829 In evaluate() expression:'20' 4807:20160914:142725.829 End of evaluate() value:20.000000 4807:20160914:142725.829 get_value_calculated() value:20.000000 4807:20160914:142725.829 End of get_value_calculated():SUCCEED |
Comments |
Comment by Sergejs Paskevics [ 2016 Sep 16 ] |
Fixed in development branch svn://svn.zabbix.com/branches/dev/ZBX-11204 |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Sep 16 ] |
(1) Your fix works, but introduces extra variable. I think it can be simplified. void remove_param(char *p, int num) { int quoted = 0; char *buf; num--; for (buf = p; '\0' != *p; p++) { if (0 != num) *buf++ = *p; if (0 == quoted) { if (',' == *p) num--; else if ('"' == *p) quoted = 1; } else if ('"' == *p && '\\' != p[-1]) quoted = 0; } *buf = '\0'; } It's shorter, simpler and it's easier to comprehend (to my opinion ). What do you think? glebs.ivanovskis As s.paskevics rightly pointed out, my version leaves comma if the last parameter is removed. Here is a new version: void remove_param(char *buf, int num) { int quoted = 0; char *p; for (p = buf, num--; '\0' != *p; p++) { if (0 != num) *buf++ = *p; if (0 == quoted) { if (',' == *p) num--; else if ('"' == *p) quoted = 1; } else if ('"' == *p && '\\' != p[-1]) quoted = 0; } /* terminate the string, overwrite comma if the last parameter was removed */ *(0 == num ? --buf : buf) = '\0'; } s.paskevics Looks good. RESOLVED in r62645. glebs.ivanovskis Thanks! Good enough for a fix, I think. Please review my stylistic changes in r62682. Still RESOLVED. glebs.ivanovskis Just realized that this implementation will fail to remove the first and the only parameter (and will write '\0' outside of array). We don't need such universal function, let's get rid of remove_param() and use slightly modified function_parse_param() and memcpy(). glebs.ivanovskis After a brief discussion we decided not to mess with 2.2 and get back to minimal r62560 fix. |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Sep 19 ] |
(2) Common pattern in trigger function evaluation functions (like evaluate_FUNC()) is to check that num_param() isn't too high and then read the first parameter unconditionally. Should we add some protection there to catch situations when num_param() returns 0 for malformed parameter list? s.paskevics You're rights. I added checking for minimal allowed number of parameters in trigger functions. RESOLVED in r62645. glebs.ivanovskis num_param() is strange... For parameter-less function it returns 1 (meaning one empty parameter). So, validation for parameter-less functions must be a bit more sophisticated. Currently trigger {host:key.diff()}=0 and diff(key) in calculated item formula fail.
zabbix_log(LOG_LEVEL_ERR, "TEST4 %d", nparams);
REOPENED glebs.ivanovskis Get back to r62560, we will do more cleanup of the code related to calculated items and trigger expressions in |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Sep 22 ] |
(3) Please sync parameter names with header file. s.paskevics RESOLVED in r62709. glebs.ivanovskis Thank you! CLOSED |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Sep 22 ] |
(4) It's safe to use p - 1 instead of prev because if we are already in "quoted" state this must be at least second character. s.paskevics RESOLVED in r62709. glebs.ivanovskis Nice! CLOSED |
Comment by Glebs Ivanovskis (Inactive) [ 2016 Sep 23 ] |
Successfully tested! |
Comment by Sergejs Paskevics [ 2016 Sep 26 ] |
Fixed in :
|