1
0
Fork 0

prevent endless loops for inf double values being appended to string buffer

This commit is contained in:
Jan Steemann 2013-01-29 12:07:30 +01:00
parent b7cec5dc22
commit 9773a88cf9
5 changed files with 80 additions and 7 deletions

View File

@ -1346,11 +1346,11 @@ static void ProcessValue (TRI_aql_codegen_js_t* const generator,
const TRI_aql_node_t* const node) {
TRI_aql_codegen_scope_t* scope = CurrentScope(generator);
if (!scope->_buffer) {
if (! scope->_buffer) {
return;
}
if (!TRI_ValueJavascriptAql(scope->_buffer, &node->_value, node->_value._type)) {
if (! TRI_ValueJavascriptAql(scope->_buffer, &node->_value, node->_value._type)) {
generator->_errorCode = TRI_ERROR_OUT_OF_MEMORY;
}
}
@ -1401,7 +1401,7 @@ static void ProcessArrayElement (TRI_aql_codegen_js_t* const generator,
const TRI_aql_node_t* const node) {
TRI_aql_codegen_scope_t* scope = CurrentScope(generator);
if (!scope->_buffer) {
if (! scope->_buffer) {
return;
}

View File

@ -29,6 +29,7 @@
#include "BasicsC/conversions.h"
#include "BasicsC/json.h"
#include "BasicsC/logging.h"
#include "BasicsC/string-buffer.h"
#include "BasicsC/strings.h"

View File

@ -973,7 +973,26 @@ static TRI_aql_node_t* OptimiseUnaryArithmeticOperation (TRI_aql_context_t* cons
}
else if (node->_type == TRI_AQL_NODE_OPERATOR_UNARY_MINUS) {
// - number => eval!
node = TRI_CreateNodeValueDoubleAql(context, - TRI_GetNumericNodeValueAql(operand));
double value = - TRI_GetNumericNodeValueAql(operand);
// check for result validity
#ifdef isnan
if (isnan(value)) {
LOG_TRACE("nan value detected after arithmetic optimisation");
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE, NULL);
return NULL;
}
#endif
#ifdef isinf
if (isinf(value)) {
LOG_TRACE("inf value detected after arithmetic optimisation");
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE, NULL);
return NULL;
}
#endif
node = TRI_CreateNodeValueDoubleAql(context, value);
if (node == NULL) {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
}
@ -1230,6 +1249,24 @@ static TRI_aql_node_t* OptimiseBinaryArithmeticOperation (TRI_aql_context_t* con
else {
value = 0.0;
}
// check for result validity
#ifdef isnan
if (isnan(value)) {
LOG_TRACE("nan value detected after arithmetic optimisation");
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE, NULL);
return NULL;
}
#endif
#ifdef isinf
if (isinf(value)) {
LOG_TRACE("inf value detected after arithmetic optimisation");
TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_INVALID_ARITHMETIC_VALUE, NULL);
return NULL;
}
#endif
node = TRI_CreateNodeValueDoubleAql(context, value);

View File

@ -752,7 +752,7 @@ function ahuacatlQuerySimpleTestSuite () {
////////////////////////////////////////////////////////////////////////////////
testListIndexes: function () {
var actual, expected;
var actual;
actual = getQueryResults("LET l = [ 1, 2, 3 ] RETURN l[0]");
assertEqual([ 1 ], actual);
@ -814,7 +814,7 @@ function ahuacatlQuerySimpleTestSuite () {
////////////////////////////////////////////////////////////////////////////////
testNaming: function () {
var actual, expected;
var actual;
actual = getQueryResults("LET a = [ 1 ] RETURN a[0]");
assertEqual([ 1 ], actual);
@ -832,6 +832,14 @@ function ahuacatlQuerySimpleTestSuite () {
assertEqual([ 1 ], actual);
assertEqual(errors.ERROR_ARANGO_ILLEGAL_NAME.code, getErrorCode(function() { QUERY("LET a = 1 RETURN `a b c`"); } ));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief numeric overflow
////////////////////////////////////////////////////////////////////////////////
testOverflow: function () {
assertEqual(errors.ERROR_QUERY_INVALID_ARITHMETIC_VALUE.code, getErrorCode(function() { QUERY("LET l = 4444444444444555555555555555555555555555555555554444333333333333333333333334444444544 RETURN l * l * l * l"); }));
}
};
}

View File

@ -876,12 +876,39 @@ int TRI_AppendSizeHexStringBuffer (TRI_string_buffer_t * self, size_t attr) {
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief appends floating point number with 8 bits
/// @brief appends floating point number
////////////////////////////////////////////////////////////////////////////////
int TRI_AppendDoubleStringBuffer (TRI_string_buffer_t * self, double attr) {
int res;
// TODO: before activating this check, make it portable
// isnan and isinf macros are available in posix, and probably in C99 only
// // check for NaN
// #ifdef isnan
// if (isnan(attr)) {
// res = Reserve(self, 3);
// if (res != TRI_ERROR_NO_ERROR) {
// return res;
// }
// TRI_AppendStringStringBuffer(self, "NaN");
// return TRI_ERROR_NO_ERROR;
// }
// #endif
//
// // check for infinity
// // if we do not enforce this check, one of the below loops might never terminate
// #ifdef isinf
// if (isinf(attr)) {
// res = Reserve(self, 3);
// if (res != TRI_ERROR_NO_ERROR) {
// return res;
// }
// TRI_AppendStringStringBuffer(self, "inf");
// return TRI_ERROR_NO_ERROR;
// }
// #endif
res = Reserve(self, 1);
if (res != TRI_ERROR_NO_ERROR) {