[TRAFODION-2725] SQL types are REAL, FLOAT, and DOUBLE. Some values are inserted, a stack overflow occurs when SQLGetData is executed. #1220
Conversation
Check Test Started: https://jenkins.esgyn.com/job/Check-PR-master/2028/ |
Test Passed. https://jenkins.esgyn.com/job/Check-PR-master/2028/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 Looks good to me
While reviewing the double_to_char function to determine if the size includes null termination, I found that ecvt function is being used to convert the double to character. ecvt function is not thread safe. Can you please fix the surround code too. Also, it looks like size shouldn't include null termination. The refactored code using sprintf can decide how the size should be used |
Hi Selva, thank you for your comments. seems ecvt function is obsolete, sprintf is recommended. Can I use sprintf to refactor the function double_to_char? |
Yes. you can using sprintf |
Check Test Started: https://jenkins.esgyn.com/job/Check-PR-master/2049/ |
Test Failed. https://jenkins.esgyn.com/job/Check-PR-master/2049/ |
Previous Test Aborted. New Check Test Started: https://jenkins.esgyn.com/job/Check-PR-master/2050/ |
Test Failed. https://jenkins.esgyn.com/job/Check-PR-master/2050/ |
Previous Test Aborted. New Check Test Started: https://jenkins.esgyn.com/job/Check-PR-master/2051/ |
Test Failed. https://jenkins.esgyn.com/job/Check-PR-master/2051/ |
} | ||
bool rc = false; | ||
char format[16]; | ||
char buf[MAX_DOUBLE_TO_CHAR_LEN]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need initialize. char buf[MAX_DOUBLE_TO_CHAR_LEN] = {0};
length = strlen(buffer); | ||
if (buffer[0] == '.' || (buffer[0] == '-' && buffer[1] == '.')) length++; | ||
sprintf(format, "%%.%dlg", precision); | ||
sprintf(buf, format, number); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
snprint is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there is a risk of writing out of range. So I think sprintf is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a risk of writing out of range because precision is not checked to be within the buf size. Also, you need to allow the numbers to be truncated after a decimal even when there is no sufficient length passed by the caller. So size can be less than strlen(buf) as long as the fraction part alone is getting cut.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@selvaganesang from original code logic, size should larger than strlen(buf). if we still want to return reasonable value though size less than strlen(buf), I think we should use other algorithm instead of snprintf.
New Check Test Started: https://jenkins.esgyn.com/job/Check-PR-master/2052/ |
Test Passed. https://jenkins.esgyn.com/job/Check-PR-master/2052/ |
New Check Test Started: https://jenkins.esgyn.com/job/Check-PR-master/2060/ |
Test Failed. https://jenkins.esgyn.com/job/Check-PR-master/2060/ |
Previous Test Aborted. New Check Test Started: https://jenkins.esgyn.com/job/Check-PR-master/2061/ |
Test Failed. https://jenkins.esgyn.com/job/Check-PR-master/2061/ |
Previous Test Aborted. New Check Test Started: https://jenkins.esgyn.com/job/Check-PR-master/2062/ |
Test Passed. https://jenkins.esgyn.com/job/Check-PR-master/2062/ |
+1. The concepts for this change look good. I am assuming that the boundary conditions are unit tested. |
@selvaganesang Yes, I tested some boundary conditions, the result is expected. test program like below:
|
Looks like this is ready to merge. I will merge it. |
root cause: write stack variable out of range.
unsigned long ODBC::ConvertSQLToC(...., targetLength) {
...
CHAR cTmpBuf[132];
...
double_to_char (dTmp, FLT_DIG + 1, cTmpBuf, targetLength) // when targetLength > 132, the stack will be broken.
...
}
fixed by: limit the max size to sizeof(cTmpBuf)
test result: run coast to check, no new issue introduced.