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) { const TRI_aql_node_t* const node) {
TRI_aql_codegen_scope_t* scope = CurrentScope(generator); TRI_aql_codegen_scope_t* scope = CurrentScope(generator);
if (!scope->_buffer) { if (! scope->_buffer) {
return; 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; 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) { const TRI_aql_node_t* const node) {
TRI_aql_codegen_scope_t* scope = CurrentScope(generator); TRI_aql_codegen_scope_t* scope = CurrentScope(generator);
if (!scope->_buffer) { if (! scope->_buffer) {
return; return;
} }

View File

@ -29,6 +29,7 @@
#include "BasicsC/conversions.h" #include "BasicsC/conversions.h"
#include "BasicsC/json.h" #include "BasicsC/json.h"
#include "BasicsC/logging.h"
#include "BasicsC/string-buffer.h" #include "BasicsC/string-buffer.h"
#include "BasicsC/strings.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) { else if (node->_type == TRI_AQL_NODE_OPERATOR_UNARY_MINUS) {
// - number => eval! // - 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) { if (node == NULL) {
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, 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 { else {
value = 0.0; 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); node = TRI_CreateNodeValueDoubleAql(context, value);

View File

@ -752,7 +752,7 @@ function ahuacatlQuerySimpleTestSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testListIndexes: function () { testListIndexes: function () {
var actual, expected; var actual;
actual = getQueryResults("LET l = [ 1, 2, 3 ] RETURN l[0]"); actual = getQueryResults("LET l = [ 1, 2, 3 ] RETURN l[0]");
assertEqual([ 1 ], actual); assertEqual([ 1 ], actual);
@ -814,7 +814,7 @@ function ahuacatlQuerySimpleTestSuite () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
testNaming: function () { testNaming: function () {
var actual, expected; var actual;
actual = getQueryResults("LET a = [ 1 ] RETURN a[0]"); actual = getQueryResults("LET a = [ 1 ] RETURN a[0]");
assertEqual([ 1 ], actual); assertEqual([ 1 ], actual);
@ -832,6 +832,14 @@ function ahuacatlQuerySimpleTestSuite () {
assertEqual([ 1 ], actual); assertEqual([ 1 ], actual);
assertEqual(errors.ERROR_ARANGO_ILLEGAL_NAME.code, getErrorCode(function() { QUERY("LET a = 1 RETURN `a b c`"); } )); 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 TRI_AppendDoubleStringBuffer (TRI_string_buffer_t * self, double attr) {
int res; 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); res = Reserve(self, 1);
if (res != TRI_ERROR_NO_ERROR) { if (res != TRI_ERROR_NO_ERROR) {