/* * * ProLinga-Validate * * Copyright (C) 2002-2009 Xobas Software. * All rights reserved. * * This file is part of ProLinga-Validate. * * ProLinga-Validate is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ProLinga-Validate is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ProLinga-Validate. If not, see . * * More information is available at the following addresses: * * Website : http://www.prolinga.org * * Email : prolinga-list@prolinga.org * * */ #include "ValCommon.h" #include #include #include #include "VCRepositoryCommand.hpp" #define DR_READ_WRITE 1 #define DR_READ_WRITE_READ_ONLY 2 bool IsControlFunctionName(const char *argument) { if (strcmp(argument, "datamanager") == 0) return true; else if (strcmp(argument, "appndev") == 0) return true; else if (strcmp(argument, "cancel") == 0) return true; else if (strcmp(argument, "commit") == 0) return true; else if (strcmp(argument, "exit") == 0) return true; else if (strcmp(argument, "logon") == 0) return true; else if (strcmp(argument, "logout") == 0) return true; else if (strcmp(argument, "painter") == 0) return true; else if (strcmp(argument, "user") == 0) return true; else if (strcmp(argument, "validate") == 0) return true; /* Return */ return false; } bool IsUnsignedInteger(const char *string) { if (string == NULL) return false; const int len = strlen(string); for(int i = 0;i < len;++i) if (!isdigit(string[i])) return false; /* Return */ return true; } bool IsNumeric(const char *string) { double num; const int len = strlen(string); int decimal = 0; num = atof(string); if (num == 0) { /* Check if 0 is result as error or 0 input */ for(int i = 0;i < len;++i) { if (string[i] == '0') continue; if ((i == 0) && (string[i] == '-')) continue; if (string[i] == '.') { decimal++; if (decimal <= 1) continue; } /* Encountered invalid character */ return false; } } /* Return */ return true; } bool IsObjectName(const char *applicationName, const char *objType, const char *argument) { char tmpValue[255], *tableName = NULL, *recName = NULL, *token; int i; bool check = false; /* Exception for Record */ if ((strcmp(objType, "Record") == 0) || (strcmp(objType, "Table") == 0)) { /* Get Table and Record Name */ strcpy(tmpValue, argument); token = strtok((char *)tmpValue, "."); i = 1; while (token != NULL) { if (i == 1) tableName = token; if (i == 2) recName = token; token = strtok(NULL, "."); i++; } /* If invalid number of argument parts, return false */ if ((i < 2) || (i > 3)) return false; /* If no record specified, record is default (HACK is table name for time being) */ if (i == 2) recName = tableName; /* Check if Table is valid */ if (tableName == NULL) return false; check = VCrepPresent(applicationName, "Table", tableName); if (check == false) return false; /* Check if Record is valid */ if (recName == NULL) return false; check = VCrepPresent(applicationName, "Record", recName); if (check == false) return false; /* Check if Record is part of Table */ return VCrepItemPresent(applicationName, recName, "Table", tableName); } else { /* Check if valid Object */ return VCrepPresent(applicationName, objType, argument); } } bool IsValidBuiltInFunc(const int r_rw, const char *argument) { /* Quick and Dirty. To be worked on once all built-ins are defined */ if ((strncmp(argument, "APPN",4 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "APPNDEV",7 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "CLIP",4 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "COMPILEINFO",11 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "CONFIGFILE",10 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "DATAMODELSTATUS",15 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "DATE",4 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "ERRORRETURN",11 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "EXPANDINSERT",12 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "EXPANDUPDATE",12 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "FALSE",5 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "LENGTH",6 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "LISTCOLCOUNT",12 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "LISTROWCOUNT",12 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "NEWLINE",7 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if (strncmp(argument, "QUITLASTSCREEN",14 ) == 0) return true; else if ((strncmp(argument, "REPOSITORYINFO",14 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if (strncmp(argument, "REPOSITORYSTATUS",16 ) == 0) return true; else if (strncmp(argument, "SQLINFO",7 ) == 0) return true; else if (strncmp(argument, "SQLRETURN",9 ) == 0) return true; else if (strncmp(argument, "SQLSTATUS",9 ) == 0) return true; else if (strncmp(argument, "TABLESTATUS",11 ) == 0) return true; else if ((strncmp(argument, "TEXTSTATUS",10 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "THREADEXIT",10 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if (strncmp(argument, "THREADSTATUS",12 ) == 0) return true; else if ((strncmp(argument, "TIME",4 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "TOLOWER",7 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "TOUPPER",7 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "TRUE",4 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "USER",4 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "UTCSTAMP",8 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if (strncmp(argument, "VALIDATESTATUS",14 ) == 0) return true; else if ((strncmp(argument, "VERSION",7 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "WEBPARAMETER",12 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; else if ((strncmp(argument, "XMLSTATUS",9 ) == 0) && (r_rw == DR_READ_WRITE_READ_ONLY)) return true; /* Return */ return false; } bool IsValidGroupDataRef(const int r_rw, const char *applicationName, const char *argument) { char argumentValue[255], tmpValue[255], *token, *tableName = NULL, *recName = NULL; int i; bool check; strcpy(argumentValue, argument); /* Check if valid DataModel */ //if ((r_rw == DR_READ_WRITE_READ_ONLY) && (argumentValue[0] == 'O') && (argumentValue[1] == '-')) // return VCrepPresent(applicationName, "DataModel", argumentValue+2); if ((argumentValue[0] == 'O') && (argumentValue[1] == '-')) return VCrepPresent(applicationName, "DataModel", argumentValue+2); /* Check if valid VariableGroup */ else if ((argumentValue[0] == 'H') && (argumentValue[1] == '-')) return VCrepPresent(applicationName, "VariableGroup", argumentValue+2); /* Check if valid Record */ else if ((argumentValue[0] == 'R') && (argumentValue[1] == '-')) { /* Get Table and Record Name */ strcpy(tmpValue, argumentValue+2); token = strtok((char *)tmpValue, "."); i = 1; while (token != NULL) { if (i == 1) tableName = token; if (i == 2) recName = token; token = strtok(NULL, "."); i++; } /* If invalid number of argument parts, return false */ if ((i < 2) || (i > 3)) return false; /* If no record specified, record is default (HACK is table name for time being) */ if (i == 2) recName = tableName; /* Check if Table is valid */ if (tableName == NULL) return false; check = VCrepPresent(applicationName, "Table", tableName); if (check == false) return false; /* Check if Record is valid */ if (recName == NULL) return false; check = VCrepPresent(applicationName, "Record", recName); if (check == false) return false; /* Check if Record is part of Table */ return VCrepItemPresent(applicationName, recName, "Table", tableName); } else /* Return */ return false; } bool IsValidSingleDataRef(const int r_rw, const char *applicationName, const char *argument) { char *dataModelName = NULL, *variableGroupName = NULL, *dataName = NULL, *recName = NULL, *tableName = NULL, tmpValue[1024], *token, *pickName = NULL; char *entryId = NULL, argumentValue[255], *substrExt = NULL, *position, *range = NULL, *string = NULL, *screenName; bool check = false; int i, j; /* If substring extension, strip */ strcpy(tmpValue, argument); token = strtok((char *)tmpValue, "["); i = 1; while (token != NULL) { if (i == 1) string = token; else if (i == 2) substrExt = token; token = strtok(NULL, "["); i++; } if (string == NULL) strcpy(argumentValue, ""); else strcpy(argumentValue, string); if (i > 3) return false; if (i == 3) { if (substrExt == NULL) return false; /* Check substring def */ if (substrExt[(strlen(substrExt)-1)] != ']') return false; else substrExt[(strlen(substrExt)-1)] = '\0'; /* Split position and range */ strcpy(tmpValue, substrExt); token = strtok((char *)tmpValue, ","); j = 1; while (token != NULL) { if (j == 1) position = token; else if (j == 2) range = token; token = strtok(NULL, ","); j++; } if (j != 3) return false; /* Check for valid number */ check = IsUnsignedInteger(position); if (check == false) { check = IsValidSingleDataRef(DR_READ_WRITE_READ_ONLY, applicationName, position); if (check == false) return false; } check = IsUnsignedInteger(range); if (check == false) { check = IsValidSingleDataRef(DR_READ_WRITE_READ_ONLY, applicationName, range); if (check == false) return false; } } /* Check if valid Variable */ if ((argumentValue[0] == 'V') && (argumentValue[1] == '-')) return VCrepPresent(applicationName, "Variable", argumentValue+2); /* Check if valid Blob */ else if ((argumentValue[0] == 'B') && (argumentValue[1] == '-')) return VCrepPresent(applicationName, "Blob", argumentValue+2); /* Check if valid Constant */ else if ((r_rw == DR_READ_WRITE_READ_ONLY) && (argumentValue[0] == 'C') && (argumentValue[1] == '-')) return VCrepPresent(applicationName, "Constant", argumentValue+2); /* Check if valid DataDictionary */ //else if ((argumentValue[0] == 'D') && (argumentValue[1] == '-')) // return VCrepPresent(applicationName, "DataDictionary", argumentValue+2); /* Check if valid ErrorDialog */ else if ((r_rw == DR_READ_WRITE_READ_ONLY) && (argumentValue[0] == 'E') && (argumentValue[1] == '-')) return VCrepPresent(applicationName, "ErrorDialog", argumentValue+2); /* Check if valid TextDocument */ else if ((argumentValue[0] == 'X') && (argumentValue[1] == '-')) return VCrepPresent(applicationName, "TextDocument", argumentValue+2); /* Check if valid Local Variable */ else if ((argumentValue[0] == 'L') && (argumentValue[1] == '-')) return VCrepPresent(applicationName, "DataDictionary", argumentValue+2); /* Check if valid DataDictionary */ else if ((argumentValue[0] == 'T') && (argumentValue[1] == '-')) return VCrepPresent(applicationName, "Table", argumentValue+2); /* Check if valid screen widget entry */ else if ((argumentValue[0] == 'S') && (argumentValue[1] == '-')) { /* If no widget name given, return false */ if (argumentValue[2] == '.') return false; /* Get widget and screen Name (last one optional) */ strcpy(tmpValue, argumentValue+2); token = strtok((char *)tmpValue, "."); i = 1; dataName = NULL; screenName = NULL; while (token != NULL) { if (i == 1) dataName = token; if (i == 2) screenName = token; token = strtok(NULL, "."); i++; } /* If invalid number of argument parts, return false */ if ((i < 2) || (i > 3)) return false; /* If no data name, return false */ if (dataName == NULL) return false; /* If screen name entered, check */ if (screenName != NULL) return VCrepPresent(applicationName, "Screen", screenName); else return true; } /* Check if valid VariableGroup entry */ else if ((argumentValue[0] == 'G') && (argumentValue[1] == '-')) { /* Get VariableGroup and DataDictionary Name */ strcpy(tmpValue, argumentValue+2); token = strtok((char *)tmpValue, "."); i = 1; while (token != NULL) { if (i == 1) dataName = token; if (i == 2) variableGroupName = token; token = strtok(NULL, "."); i++; } /* If invalid number of argument parts, return false */ if (i != 3) return false; /* Check if Data Dictionary is valid */ if (dataName == NULL) return false; check = VCrepPresent(applicationName, "DataDictionary", dataName); if (check == false) return false; /* Check if Data Dictionary is part of VariableGroup */ if (variableGroupName == NULL) return false; check = VCrepItemPresent(applicationName, dataName, "VariableGroup", variableGroupName); /* Return */ return check; } /* Check if valid DataModel entry */ //else if ((r_rw == DR_READ_WRITE_READ_ONLY) && (argumentValue[0] == 'M') && (argumentValue[1] == '-')) else if ((argumentValue[0] == 'M') && (argumentValue[1] == '-')) { /* Get VariableGroup and DataDictionary Name */ strcpy(tmpValue, argumentValue+2); token = strtok((char *)tmpValue, "."); i = 1; while (token != NULL) { if (i == 1) dataName = token; if (i == 2) dataModelName = token; token = strtok(NULL, "."); i++; } /* If invalid number of argument parts, return false */ if (i != 3) return false; /* Check if Data Dictionary is valid */ //if (dataName == NULL) // return false; //check = VCrepPresent(applicationName, "DataDictionary", dataName); //if (check == false) // return false; /* Check if Data Model is valid */ if (dataModelName == NULL) return false; check = VCrepPresent(applicationName, "DataModel", dataModelName); if (check == false) return false; /* Return */ return check; } /* Check if valid Data Field */ else if ((argumentValue[0] == 'F') && (argumentValue[1] == '-')) { /* Get Table, Record and DataDictionary Name */ strcpy(tmpValue, argumentValue+2); token = strtok((char *)tmpValue, "."); i = 1; while (token != NULL) { if (i == 1) dataName = token; if (i == 2) tableName = token; if (i == 3) recName = token; token = strtok(NULL, "."); i++; } /* If invalid number of argument parts, return false */ if ((i < 3) || (i > 4)) return false; /* If no record specified, record is default (HACK is table name for time being) */ if (i == 3) recName = tableName; /* Check if Data Dictionary is valid */ if (dataName == NULL) return false; check = VCrepPresent(applicationName, "DataDictionary", dataName); if (check == false) return false; /* Check if Table is valid */ if (tableName == NULL) return false; check = VCrepPresent(applicationName, "Table", tableName); if (check == false) return false; /* Check if Record is valid */ if (recName == NULL) return false; check = VCrepPresent(applicationName, "Record", recName); if (check == false) return false; /* Check if Data Dictionary is part of Record */ check = VCrepItemPresent(applicationName, dataName, "Record", recName); if (check == false) return false; /* Check if Record is part of Table */ return VCrepItemPresent(applicationName, recName, "Table", tableName); } /* Check if valid PickList entry */ else if ((argumentValue[0] == 'P') && (argumentValue[1] == '-')) { strcpy(tmpValue, argumentValue+2); token = strtok((char *)tmpValue, "("); i = 1; while (token != NULL) { if (i == 1) pickName = token; if (i == 2) entryId = token; token = strtok(NULL, ")"); i++; } /* Check if expected split up */ if (i != 3) return false; /* Check if last char is ) */ if (argumentValue[(strlen(argumentValue)-1)] != ')') return false; /* Check if PickList is valid */ if (pickName == NULL) return false; check = VCrepPresent(applicationName, "PickList", pickName); if (check == false) return false; /* Check for valid entry number */ if (entryId == NULL) return false; check = IsUnsignedInteger(entryId); if (check == false) return IsValidSingleDataRef(DR_READ_WRITE_READ_ONLY, applicationName, entryId); else return true; } /* Check if valid TextContents */ else if ((argumentValue[0] == 'X') && (argumentValue[1] == '-')) { check = VCrepPresent(applicationName, "TextDocument", argumentValue+2); if (check == false) return false; } /* Check for built-in function */ else return IsValidBuiltInFunc(r_rw, argumentValue); /* Return */ return false; } bool IsAnyName(const char *argument) { /* Simple check to see if it is not a string */ if ((argument[0] == '"') || (argument[(strlen(argument)-1)] == '"')) return false; /* Simple check to see if it starts with a number */ if (isdigit(argument[0]) != 0) return false; /* Simple check to see if data reference */ if (argument[1] == '-') return false; /* More tests ?? */ /* Return */ return true; } bool IsComparator(const char *argument) { if (strcmp(argument, "=") == 0) return true; else if (strcmp(argument, "<") == 0) return true; else if (strcmp(argument, "<=") == 0) return true; else if (strcmp(argument, ">") == 0) return true; else if (strcmp(argument, ">=") == 0) return true; else if (strcmp(argument, "<>") == 0) return true; /* Return */ return false; } bool IsValidString(const char *argument) { /* Check if valid String */ if ((argument[0] == '"') && (argument[(strlen(argument)-1)] == '"')) return true; /* Return */ return false; } bool IsMathOperator(const char *argument) { /* Operators */ if (strcmp(argument, "++") == 0) return true; else if (strcmp(argument, "--") == 0) return true; else if (strcmp(argument, "!") == 0) return true; else if (strcmp(argument, "~") == 0) return true; else if (strcmp(argument, "unary") == 0) return true; else if (strcmp(argument, "+") == 0) return true; else if (strcmp(argument, "-") == 0) return true; else if (strcmp(argument, "**") == 0) return true; else if (strcmp(argument, "*") == 0) return true; else if (strcmp(argument, "/") == 0) return true; else if (strcmp(argument, "%") == 0) return true; else if (strcmp(argument, "<<") == 0) return true; else if (strcmp(argument, ">>") == 0) return true; else if (strcmp(argument, ">>>") == 0) return true; else if (strcmp(argument, "<") == 0) return true; else if (strcmp(argument, "<=") == 0) return true; else if (strcmp(argument, ">") == 0) return true; else if (strcmp(argument, ">=") == 0) return true; else if (strcmp(argument, "==") == 0) return true; else if (strcmp(argument, "!=") == 0) return true; else if (strcmp(argument, "&") == 0) return true; else if (strcmp(argument, "^") == 0) return true; else if (strcmp(argument, "|") == 0) return true; else if (strcmp(argument, "=") == 0) return true; else if (strcmp(argument, "+=") == 0) return true; else if (strcmp(argument, "-=") == 0) return true; else if (strcmp(argument, "*=") == 0) return true; else if (strcmp(argument, "/=") == 0) return true; else if (strcmp(argument, "%=") == 0) return true; else if (strcmp(argument, "<<=") == 0) return true; else if (strcmp(argument, ">>=") == 0) return true; else if (strcmp(argument, ">>>=") == 0) return true; else if (strcmp(argument, "&=") == 0) return true; else if (strcmp(argument, "|=") == 0) return true; else if (strcmp(argument, "^=") == 0) return true; else if (strcmp(argument, "**=") == 0) return true; /* Return */ return false; } bool IsMathFunction(const char *argument) { /* Functions */ if ((strncmp(argument, "abs(",4) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "acos(",5) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "asin(",5) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "atan(",5) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "atan2(",6) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "cos(",4) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "cosh(",5) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "exp(",4) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "int(",4) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "float(",6) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "log(",4) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "log10(",6) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "prime(",6) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "sin(",4) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "sinh(",5) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "sqrt(",5) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "tan(",4) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; else if ((strncmp(argument, "tanh(",5) == 0) && (argument[(strlen(argument)-1)] == ')')) return true; /* Return */ return false; } bool CheckArgumentStyle(const char *applicationName, const char *argument, const char *style, const char *staticValue) { /* Any valid name format which can not be checked */ if (strcmp(style, "AnyName") == 0) return IsAnyName(argument); /* Comparator */ else if (strcmp(style, "Comparator") == 0) return IsComparator(argument); /* Math Function */ else if (strcmp(style, "ControlFunctionName") == 0) return IsControlFunctionName(argument); /* Math Function */ else if (strcmp(style, "MathFunction") == 0) return IsMathFunction(argument); /* Math Operator */ else if (strcmp(style, "MathOperator") == 0) return IsMathOperator(argument); /* Any Numeric */ else if (strcmp(style, "Numeric") == 0) return IsNumeric(argument); /* A specific Object */ else if (strncmp(style, "ObjectName",10) == 0) return IsObjectName(applicationName, style+10, argument); /* Single Reference */ else if (strcmp(style, "SingleDataReference") == 0) return IsValidSingleDataRef(DR_READ_WRITE_READ_ONLY, applicationName, argument); else if (strcmp(style, "SingleDataReferenceWrite") == 0) return IsValidSingleDataRef(DR_READ_WRITE, applicationName, argument); /* Group Reference */ else if (strcmp(style, "GroupDataReference") == 0) return IsValidGroupDataRef(DR_READ_WRITE_READ_ONLY, applicationName, argument); else if (strcmp(style, "GroupDataReferenceWrite") == 0) return IsValidGroupDataRef(DR_READ_WRITE, applicationName, argument); else if (strcmp(style, "Static") == 0) { if (staticValue == NULL) return false; if (strcmp(argument, staticValue) == 0) return true; else return false; } /* String */ else if (strcmp(style, "String") == 0) return IsValidString(argument); /* Number */ else if (strcmp(style, "UnsignedInteger") == 0) return IsUnsignedInteger(argument); else return false; }