From 508f3bbee15be4f72006ccabecc765d3d2ad3068 Mon Sep 17 00:00:00 2001 From: prabatuty Date: Tue, 2 Nov 2010 11:50:59 +0000 Subject: [PATCH] error in parsing date and time leads to wrong value being inserted into the table --- src/server/TableImpl.cxx | 4 ++-- src/sql/DelStatement.cxx | 8 +++++++- src/sql/InsStatement.cxx | 18 ++++++++++++++---- src/sql/SelStatement.cxx | 14 +++++++++++--- src/sql/UpdStatement.cxx | 24 ++++++++++++++++++++---- src/storage/DataType.cxx | 6 ++++++ src/storage/TableImpl.cxx | 8 ++++---- src/tools/isql.cxx | 20 ++++++++++---------- 8 files changed, 74 insertions(+), 28 deletions(-) diff --git a/src/server/TableImpl.cxx b/src/server/TableImpl.cxx index d8ed62e6..710e10f0 100644 --- a/src/server/TableImpl.cxx +++ b/src/server/TableImpl.cxx @@ -607,9 +607,9 @@ DbRetVal TableImpl::copyValuesFromBindBuffer(void *tuplePtr, bool isInsert) break; case typeBinary: if (NULL != def.bindVal_ ) { - DbRetVal rv = AllDataType::strToValue(colPtr, (char *) def.bindVal_, def.type_, def.length_); + DbRetVal rv = AllDataType::strToValue(colPtr, (char *) def.bindVal_, def.type_, def.length_); if (rv != OK) return ErrBadArg; - } + } else if (!def.isNull_ && isInsert) setNullBit(fldpos); colPtr = colPtr + os::align(def.length_); break; diff --git a/src/sql/DelStatement.cxx b/src/sql/DelStatement.cxx index c6a2383a..ada561d2 100644 --- a/src/sql/DelStatement.cxx +++ b/src/sql/DelStatement.cxx @@ -329,6 +329,7 @@ DbRetVal DelStatement::resolveForCondition() for(int n=0;nparsedString[n]; if(!(p>=48 && p<=57 || p==45)) + delete fInfo; return ErrBadArg; } } @@ -337,11 +338,16 @@ DbRetVal DelStatement::resolveForCondition() int len=strlen(value->parsedString); if(len > 8000){ printError(ErrBadRange, "Char DataType length should be less than 8kb(8000)."); + delete fInfo; return ErrBadRange; } } // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary - AllDataType::strToValue(value->value, value->parsedString, fInfo->type, fInfo->length); + rv = AllDataType::strToValue(value->value, value->parsedString, fInfo->type, fInfo->length); + if (rv != OK) { + delete fInfo; + return ErrBadArg; + } } } delete fInfo; diff --git a/src/sql/InsStatement.cxx b/src/sql/InsStatement.cxx index 34cd448d..9c42e968 100644 --- a/src/sql/InsStatement.cxx +++ b/src/sql/InsStatement.cxx @@ -366,18 +366,28 @@ DbRetVal InsStatement::resolve() for(int n=0;nparsedString[n]; if(!(p>=48 && p<=57 || p==45) ) + delete fInfo; return ErrBadArg; } } - // for binary datatype buffer is just strcpy'd. It will be converted into binary datatype in copyValuesToBindBuffer in DBAPI + // for binary datatype buffer is just strcpy'd. + //It will be converted into binary datatype in copyValuesToBindBuffer in DBAPI if (value->type == typeBinary) strncpy((char *)value->value, value->parsedString, 2 * fInfo->length); - else AllDataType::strToValue(value->value, value->parsedString, fInfo->type, fInfo->length); + else { + rv = AllDataType::strToValue(value->value, value->parsedString, fInfo->type, fInfo->length); + if (OK != rv) { + delete fInfo; + return ErrBadArg; + } + } + /* Checking range for char data type 8kb(8000) */ if(value->type==typeString){ int len=strlen(value->parsedString); if(len > 8000){ printError(ErrBadRange,"Char data type length should be less than 8kb(8000)."); + delete fInfo; return ErrBadRange; } } @@ -393,8 +403,8 @@ DbRetVal InsStatement::resolve() delete (Identifier *) iter.nextElement(); fieldNameList.reset(); } - return OK; - } + return OK; + } params = (void**) malloc ( totalParams * sizeof(FieldValue*)); paramValues = (char**) malloc( totalParams * sizeof(char*)); memset(params, 0, totalParams * sizeof(FieldValue*)); diff --git a/src/sql/SelStatement.cxx b/src/sql/SelStatement.cxx index 3586f26f..c8b3c46f 100644 --- a/src/sql/SelStatement.cxx +++ b/src/sql/SelStatement.cxx @@ -878,12 +878,20 @@ DbRetVal SelStatement::resolveForCondition() int len=strlen(value->parsedString); for(int n=0;nparsedString[n]; - if(!(p>=48 && p<=57 || p==45)) return ErrBadArg; + if(!(p>=48 && p<=57 || p==45)) { + delete fInfo; + return ErrBadArg; + } } } - // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary - AllDataType::strToValue(value->value, value->parsedString, value->type, value->length); + // Here for binary dataType it is not strcpy'd bcos internally + // memcmp is done for predicates like f2 = 'abcd' where f2 is binary + rv = AllDataType::strToValue(value->value, value->parsedString, value->type, value->length); + if (OK != rv) { + delete fInfo; + return ErrBadArg; + } } } delete fInfo; diff --git a/src/sql/UpdStatement.cxx b/src/sql/UpdStatement.cxx index 662a8b9a..18192893 100644 --- a/src/sql/UpdStatement.cxx +++ b/src/sql/UpdStatement.cxx @@ -519,19 +519,29 @@ DbRetVal UpdStatement::resolveForAssignment() int len=strlen(value->parsedString); for(int n=0;nparsedString[n]; - if(!(p>=48 && p<=57 || p==45)) + if(!(p>=48 && p<=57 || p==45)) { + delete fInfo; return ErrBadArg; + } } } // for binary datatype buffer is just strcpy'd. It will be converted into binary datatype in copyValuesToBindBuffer in DBAPI if (value->type == typeBinary) strncpy((char *)value->value, value->parsedString, 2 * fInfo->length); - else AllDataType::strToValue(value->value, value->parsedString, fInfo->type, value->length); + else { + rv = AllDataType::strToValue(value->value, value->parsedString, fInfo->type, value->length); + if (OK != rv) + { + delete fInfo; + return ErrBadArg; + } + } /* Check for char data type 8kb(8000) */ if(value->type==typeString){ int len=strlen(value->parsedString); if(len > 8000){ printError(ErrBadRange, "Char DataType length should be less than 8kb(8000)."); + delete fInfo; return ErrBadRange; } } @@ -599,12 +609,18 @@ DbRetVal UpdStatement::resolveForAssignment() int len = strlen(cValue->parsedString); for(int n=0;nparsedString[n]; - if(!(p>=48 && p<=57 || p==45)) + if(!(p>=48 && p<=57 || p==45)) { + delete fInfo; return ErrBadArg; + } } } // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary - AllDataType::strToValue(cValue->value, cValue->parsedString, fInfo->type, fInfo->length); + rv = AllDataType::strToValue(cValue->value, cValue->parsedString, fInfo->type, fInfo->length); + if (OK != rv) { + delete fInfo; + return ErrBadArg; + } } } delete fInfo; diff --git a/src/storage/DataType.cxx b/src/storage/DataType.cxx index 2000beaa..369d8efb 100644 --- a/src/storage/DataType.cxx +++ b/src/storage/DataType.cxx @@ -1758,6 +1758,7 @@ DbRetVal AllDataType::strToValue(void* dest, char *src, DataType type, int lengt if(!date.isValidDate(y, m, d)){ fprintf(stderr,"Error reading date. The value \"%d-%d-%d\" is inappropriate.",y,m,d); d=m=y=0; + return ErrBadArg; } Date dateObj(y,m,d); *(Date*)dest = dateObj; @@ -1777,12 +1778,14 @@ DbRetVal AllDataType::strToValue(void* dest, char *src, DataType type, int lengt if(res!=6){ fprintf(stderr, "Error reading time, hh:mm:ss is the valid format."); h=m=s=0; + return ErrBadArg; } } /* validate time */ if(!time.isValidTime(h, m, s)){ fprintf(stderr,"Error reading Time. The value \"%d-%d-%d\" is inappropriate.",h,m,s); h=m=s=0; + return ErrBadArg; } Time timeObj(h,m,s); *(Time*)dest = timeObj; @@ -1810,16 +1813,19 @@ DbRetVal AllDataType::strToValue(void* dest, char *src, DataType type, int lengt { fprintf(stderr, "Error reading timestamp, yyyy{-/}mm{-/}dd[,] hh:mm:ss is the valid format."); d=m=y=h=mn=s=0; + return ErrBadArg; } /* Looking up at 'YY-MM-DD' */ if(!date.isValidDate(y, m, d)){ fprintf(stderr,"Error reading date. The value \"%d-%d-%d\" is inappropriate.",y,m,d); d=m=y=h=mn=s=0; + return ErrBadArg; } /* Looking up at 'Hour-Min-Sec' */ if(!time.isValidTime(h, m, s)){ fprintf(stderr,"Error reading Time. The value \"%d-%d-%d\" is inappropriate.",h,m,s); d=m=y=h=mn=s=0; + return ErrBadArg; } TimeStamp timeStampObj(y,m,d,h,mn,s); *(TimeStamp*)dest = timeStampObj; diff --git a/src/storage/TableImpl.cxx b/src/storage/TableImpl.cxx index 1946360c..f6e7c8b8 100644 --- a/src/storage/TableImpl.cxx +++ b/src/storage/TableImpl.cxx @@ -1434,11 +1434,11 @@ DbRetVal TableImpl::copyValuesFromBindBuffer(void *tuplePtr, bool isInsert) case typeBinary: if (NULL != def->bindVal_ ) { - if(!isInsert && isFldNull(fldpos)){clearNullBit(fldpos);} - DbRetVal rv = AllDataType::strToValue(colPtr, + if(!isInsert && isFldNull(fldpos)){clearNullBit(fldpos);} + DbRetVal rv = AllDataType::strToValue(colPtr, (char *) def->bindVal_, def->type_, def->length_); - if (rv != OK) return ErrBadArg; - } else if (!def->isNull_ && isInsert && !def->bindVal_) { + if (rv != OK) return ErrBadArg; + } else if (!def->isNull_ && isInsert && !def->bindVal_) { setNullBit(fldpos); } colPtr = colPtr + def->length_; diff --git a/src/tools/isql.cxx b/src/tools/isql.cxx index b4be4617..1154fa37 100644 --- a/src/tools/isql.cxx +++ b/src/tools/isql.cxx @@ -45,7 +45,7 @@ bool gateway=false, silent=false; bool autocommitmode = true; bool isTimer = false; bool network = false; -bool firstPrepare = false; +bool firstPrepare = true; IsolationLevel isoLevel = READ_COMMITTED; void printHelp(); bool getInput(bool); @@ -502,13 +502,13 @@ bool getInput(bool fromFile) NanoTimer timer; DbRetVal rv; if (autocommitmode) { - if (firstPrepare) aconStmt->free(); + if (!firstPrepare) aconStmt->free(); rv = aconStmt->prepare(buf); if (rv != OK) { printf("Statement prepare failed with error %d\n", rv); return true; } - firstPrepare = true; + firstPrepare = false; stmt=aconStmt; } else { @@ -534,7 +534,7 @@ bool getInput(bool fromFile) if (autocommitmode) { conn->rollback(); aconStmt->free(); - firstPrepare = false; //set this so that it does not free again + firstPrepare = true; //set this so that it does not free again conn->beginTrans(isoLevel); } else { @@ -545,14 +545,14 @@ bool getInput(bool fromFile) return true; } timer.stop(); - if (stmtType == OTHER && stmt->isSelect()) stmtType = SELECT; - if (stmtType == OTHER ) + if (stmtType == EXPLAIN) { - if (!silent) printf("Statement Executed: Rows Affected = %d\n", rows); + stmt->close(); } - else if (stmtType == EXPLAIN) + else if (stmtType == OTHER && stmt->isSelect()) stmtType = SELECT; + else if (stmtType == OTHER ) { - stmt->close(); + if (!silent) printf("Statement Executed: Rows Affected = %d\n", rows); } else if (stmtType == DDL) { @@ -588,7 +588,7 @@ bool getInput(bool fromFile) conn->commit(); //conn->beginTrans(isoLevel, TSYNC); stmt->free(); - firstPrepare = false; //set this so that it does not free again + firstPrepare = true; //set this so that it does not free again conn->beginTrans(isoLevel); return true; } -- 2.11.4.GIT