Library: simplified code and added test cases for validating <valid>-tag expressions
This commit is contained in:
parent
05c36a79b5
commit
9f445fc735
|
@ -708,46 +708,11 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co
|
|||
else if (argnodename == "valid") {
|
||||
// Validate the validation expression
|
||||
const char *p = argnode->GetText();
|
||||
bool error = false;
|
||||
bool range = false;
|
||||
bool has_dot = false;
|
||||
bool has_E = false;
|
||||
|
||||
if (!p)
|
||||
return Error(BAD_ATTRIBUTE_VALUE, "\"\"");
|
||||
|
||||
error = *p == '.';
|
||||
for (; *p; p++) {
|
||||
if (std::isdigit(*p))
|
||||
error |= (*(p+1) == '-');
|
||||
else if (*p == ':') {
|
||||
error |= range | (*(p+1) == '.');
|
||||
range = true;
|
||||
has_dot = false;
|
||||
has_E = false;
|
||||
} else if (*p == '-')
|
||||
error |= (!std::isdigit(*(p+1)));
|
||||
else if (*p == ',') {
|
||||
range = false;
|
||||
error |= *(p+1) == '.';
|
||||
has_dot = false;
|
||||
has_E = false;
|
||||
} else if (*p == '.') {
|
||||
error |= has_dot | (!std::isdigit(*(p+1)));
|
||||
has_dot = true;
|
||||
} else if (*p == 'E' || *p == 'e') {
|
||||
error |= has_E;
|
||||
has_E = true;
|
||||
} else
|
||||
error = true;
|
||||
}
|
||||
if (error)
|
||||
return Error(BAD_ATTRIBUTE_VALUE, argnode->GetText());
|
||||
|
||||
if (!isCompliantValidationExpression(p))
|
||||
return Error(BAD_ATTRIBUTE_VALUE, (!p ? "\"\"" : argnode->GetText()));
|
||||
// Set validation expression
|
||||
ac.valid = argnode->GetText();
|
||||
}
|
||||
|
||||
else if (argnodename == "minsize") {
|
||||
const char *typeattr = argnode->Attribute("type");
|
||||
if (!typeattr)
|
||||
|
@ -1242,6 +1207,48 @@ const Library::WarnInfo* Library::getWarnInfo(const Token* ftok) const
|
|||
return &i->second;
|
||||
}
|
||||
|
||||
bool Library::isCompliantValidationExpression(const char* p)
|
||||
{
|
||||
if (!p)
|
||||
return false;
|
||||
|
||||
bool error = false;
|
||||
bool range = false;
|
||||
bool has_dot = false;
|
||||
bool has_E = false;
|
||||
|
||||
error = *p == '.';
|
||||
for (; *p; p++) {
|
||||
if (std::isdigit(*p))
|
||||
error |= (*(p + 1) == '-');
|
||||
else if (*p == ':') {
|
||||
error |= range | (*(p + 1) == '.');
|
||||
range = true;
|
||||
has_dot = false;
|
||||
has_E = false;
|
||||
}
|
||||
else if ((*p == '-')|| (*p == '+'))
|
||||
error |= (!std::isdigit(*(p + 1)));
|
||||
else if (*p == ',') {
|
||||
range = false;
|
||||
error |= *(p + 1) == '.';
|
||||
has_dot = false;
|
||||
has_E = false;
|
||||
}
|
||||
else if (*p == '.') {
|
||||
error |= has_dot | (!std::isdigit(*(p + 1)));
|
||||
has_dot = true;
|
||||
}
|
||||
else if (*p == 'E' || *p == 'e') {
|
||||
error |= has_E;
|
||||
has_E = true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return !error;
|
||||
}
|
||||
|
||||
bool Library::formatstr_function(const Token* ftok) const
|
||||
{
|
||||
if (isNotLibraryFunction(ftok))
|
||||
|
|
|
@ -142,6 +142,8 @@ public:
|
|||
mNoReturn[funcname] = noreturn;
|
||||
}
|
||||
|
||||
static bool isCompliantValidationExpression(const char* p);
|
||||
|
||||
/** is allocation type memory? */
|
||||
static bool ismemory(const int id) {
|
||||
return ((id > 0) && ((id & 1) == 0));
|
||||
|
|
|
@ -40,6 +40,7 @@ private:
|
|||
Settings settings;
|
||||
|
||||
void run() OVERRIDE {
|
||||
TEST_CASE(isCompliantValidationExpression);
|
||||
TEST_CASE(empty);
|
||||
TEST_CASE(function);
|
||||
TEST_CASE(function_match_scope);
|
||||
|
@ -72,6 +73,26 @@ private:
|
|||
return library.load(doc);
|
||||
}
|
||||
|
||||
void isCompliantValidationExpression()
|
||||
{
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression("-1"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression("1"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression("1:"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression(":1"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression("-1,42"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression("-1,-42"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression("-1.0:42.0"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression("1.175494e-38:3.402823e+38"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression("1.175494e-38,3.402823e+38"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression("1.175494e-38:"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression(":1.175494e-38"));
|
||||
ASSERT_EQUALS(true, Library::isCompliantValidationExpression(":42.0"));
|
||||
|
||||
// Robustness tests
|
||||
ASSERT_EQUALS(false, Library::isCompliantValidationExpression(nullptr));
|
||||
ASSERT_EQUALS(false, Library::isCompliantValidationExpression("x"));
|
||||
}
|
||||
|
||||
void empty() const {
|
||||
// Reading an empty library file is considered to be OK
|
||||
const char xmldata[] = "<?xml version=\"1.0\"?>\n<def/>";
|
||||
|
|
Loading…
Reference in New Issue