8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 07:23:03 +01:00

Postfix for CORE-5277 - Parameters with multibyte character sets allow to bypass the character limit of varchar fields. (9fede1e)

This commit is contained in:
Adriano dos Santos Fernandes 2016-06-30 10:02:41 -03:00
parent d963ef8db5
commit df233ae4ad
8 changed files with 51 additions and 19 deletions

View File

@ -11204,9 +11204,14 @@ ValueExprNode* UdfCallNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
++ptr)
{
unsigned pos = ptr - node->args->items.begin();
dsc desc = node->dsqlFunction->udf_arguments[pos];
// UNICODE_FSS_HACK
if (node->dsqlFunction->udf_fld_system_arguments[pos])
DataTypeUtilBase::adjustSysFieldLength(&desc);
if (pos < node->dsqlFunction->udf_arguments.getCount())
PASS1_set_parameter_type(dsqlScratch, *ptr, &node->dsqlFunction->udf_arguments[pos], false);
PASS1_set_parameter_type(dsqlScratch, *ptr, &desc, false);
else
{
// We should complain here in the future! The parameter is

View File

@ -327,7 +327,7 @@ class dsql_udf : public pool_alloc<dsql_type_udf>
{
public:
explicit dsql_udf(MemoryPool& p)
: udf_name(p), udf_arguments(p)
: udf_name(p), udf_arguments(p), udf_fld_system_arguments(p)
{
}
@ -340,6 +340,7 @@ public:
USHORT udf_flags;
Firebird::QualifiedName udf_name;
Firebird::Array<dsc> udf_arguments;
Firebird::Array<bool> udf_fld_system_arguments;
bool udf_private; // Packaged private function
SSHORT udf_def_count; // number of inputs with default values
};

View File

@ -63,21 +63,6 @@ using namespace Jrd;
using namespace Firebird;
static void adjustLength(dsc* desc)
{
USHORT adjust = 0;
if (desc->dsc_dtype == dtype_varying)
adjust = sizeof(USHORT);
else if (desc->dsc_dtype == dtype_cstring)
adjust = 1;
desc->dsc_length -= adjust;
desc->dsc_length *= 3;
desc->dsc_length += adjust;
}
LiteralNode* MAKE_const_slong(SLONG value)
{
thread_db* tdbb = JRD_get_thread_data();
@ -277,7 +262,7 @@ void MAKE_desc_from_field(dsc* desc, const dsql_fld* field)
// UNICODE_FSS_HACK
// check if the field is a system domain and CHARACTER SET is UNICODE_FSS
if (desc->isText() && (INTL_GET_CHARSET(desc) == CS_UNICODE_FSS) && (field->flags & FLD_system))
adjustLength(desc);
DataTypeUtilBase::adjustSysFieldLength(desc);
}
@ -350,7 +335,7 @@ FieldNode* MAKE_field(dsql_ctx* context, dsql_fld* field, ValueListNode* indices
if ((field->flags & FLD_system) && node->nodDesc.dsc_dtype <= dtype_varying &&
INTL_GET_CHARSET(&node->nodDesc) == CS_METADATA)
{
adjustLength(&node->nodDesc);
DataTypeUtilBase::adjustSysFieldLength(&node->nodDesc);
}
}
else

View File

@ -980,6 +980,8 @@ dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
}
userFunc->udf_arguments.add(d);
userFunc->udf_fld_system_arguments.add(
isSystemDomain(tdbb, transaction, X.RDB$FIELD_SOURCE));
}
}
END_FOR
@ -1052,6 +1054,7 @@ dsql_udf* METD_get_function(jrd_tra* transaction, DsqlCompilerScratch* dsqlScrat
}
userFunc->udf_arguments.add(d);
userFunc->udf_fld_system_arguments.add(false);
}
}
}

View File

@ -75,6 +75,24 @@ USHORT DataTypeUtilBase::getResultTextType(const dsc* value1, const dsc* value2)
}
void DataTypeUtilBase::adjustSysFieldLength(dsc* desc)
{
if (INTL_GET_CHARSET(desc) != CS_UNICODE_FSS)
return;
USHORT adjust = 0;
if (desc->dsc_dtype == dtype_varying)
adjust = sizeof(USHORT);
else if (desc->dsc_dtype == dtype_cstring)
adjust = 1;
desc->dsc_length -= adjust;
desc->dsc_length *= 3;
desc->dsc_length += adjust;
}
// This function is made to determine a output descriptor from a given list
// of expressions according to the latest SQL-standard that was available.
// (ISO/ANSI SQL:200n WG3:DRS-013 H2-2002-358 August, 2002).

View File

@ -40,6 +40,7 @@ public:
public:
static SSHORT getResultBlobSubType(const dsc* value1, const dsc* value2);
static USHORT getResultTextType(const dsc* value1, const dsc* value2);
static void adjustSysFieldLength(dsc* desc); //// UNICODE_FSS_HACK
public:
void makeFromList(dsc* result, const char* expressionName, int argsCount, const dsc** args);

View File

@ -30,6 +30,7 @@
#include "../jrd/blb.h"
#include "../jrd/met.h"
#include "../jrd/align.h"
#include "../jrd/DataTypeUtil.h"
#include "../dsql/ExprNodes.h"
#include "../dsql/StmtNodes.h"
#include "../jrd/blb_proto.h"
@ -302,6 +303,10 @@ Function* Function::loadMetadata(thread_db* tdbb, USHORT id, bool noscan, USHORT
F.RDB$FIELD_SUB_TYPE, F.RDB$CHARACTER_SET_ID,
(collation_id_null ? F.RDB$COLLATION_ID : collation_id));
// UNICODE_FSS_HACK
if (F.RDB$SYSTEM_FLAG == 1)
DataTypeUtilBase::adjustSysFieldLength(&parameter->prm_desc);
if (default_value_null && fb_utils::implicit_domain(F.RDB$FIELD_NAME))
{
default_value_null = F.RDB$DEFAULT_VALUE.NULL;

View File

@ -61,6 +61,7 @@
#include "../jrd/intl.h"
#include "../jrd/align.h"
#include "../jrd/flu.h"
#include "../jrd/DataTypeUtil.h"
#include "../jrd/blob_filter.h"
#include "../dsql/StmtNodes.h"
#include "../intl/charsets.h"
@ -224,6 +225,10 @@ void MET_get_domain(thread_db* tdbb, MemoryPool& csbPool, const MetaName& name,
{
found = true;
// UNICODE_FSS_HACK
if (FLD.RDB$SYSTEM_FLAG == 1)
DataTypeUtilBase::adjustSysFieldLength(desc);
if (fieldInfo)
{
fieldInfo->nullable = FLD.RDB$NULL_FLAG.NULL || FLD.RDB$NULL_FLAG == 0;
@ -291,6 +296,11 @@ MetaName MET_get_relation_field(thread_db* tdbb, MemoryPool& csbPool, const Meta
(RFL.RDB$COLLATION_ID.NULL ? FLD.RDB$COLLATION_ID : RFL.RDB$COLLATION_ID)))
{
found = true;
// UNICODE_FSS_HACK
if (FLD.RDB$SYSTEM_FLAG == 1)
DataTypeUtilBase::adjustSysFieldLength(desc);
sourceName = RFL.RDB$FIELD_SOURCE;
if (fieldInfo)
@ -3370,6 +3380,10 @@ jrd_prc* MET_procedure(thread_db* tdbb, USHORT id, bool noscan, USHORT flags)
F.RDB$FIELD_SUB_TYPE, F.RDB$CHARACTER_SET_ID,
(pa_collation_id_null ? F.RDB$COLLATION_ID : pa_collation_id));
// UNICODE_FSS_HACK
if (F.RDB$SYSTEM_FLAG == 1)
DataTypeUtilBase::adjustSysFieldLength(&parameter->prm_desc);
if (PA.RDB$PARAMETER_TYPE == 0 &&
(!pa_default_value_null ||
(fb_utils::implicit_domain(F.RDB$FIELD_NAME) && !F.RDB$DEFAULT_VALUE.NULL)))