File firebird-CVE-2017-11509.patch of Package firebird.40436
From 7bbb981cf8021dc5756acf0c072e03dfaa80ef9d Mon Sep 17 00:00:00 2001
From: AlexPeshkoff <alexander.peshkoff@gmail.com>
Date: Fri, 25 Jan 2019 13:57:42 +0300
Subject: [PATCH] Added script converting previously distributed UDF to
PSQL/UDR functions
---
src/misc/upgrade/v4.0/udf_replace.sql | 452 ++++++++++++++++++++++++++
src/misc/upgrade/v4.0/udf_replace.txt | 56 ++++
2 files changed, 508 insertions(+)
create mode 100644 src/misc/upgrade/v4.0/udf_replace.sql
create mode 100644 src/misc/upgrade/v4.0/udf_replace.txt
diff --git a/src/misc/upgrade/v4.0/udf_replace.sql b/src/misc/upgrade/v4.0/udf_replace.sql
new file mode 100644
index 0000000000..a8aa28056d
--- /dev/null
+++ b/src/misc/upgrade/v4.0/udf_replace.sql
@@ -0,0 +1,452 @@
+/*
+ * PROGRAM: Firebird functions migration.
+ * MODULE: udf_replace.sql
+ * DESCRIPTION: UDFs were deprecated in FB4 - first of all due to security reasons.
+ * This script alters UDFs from if_udf & fbudf to appropriate PSQL or UDR functions.
+ *
+ * The contents of this file are subject to the Initial
+ * Developer's Public License Version 1.0 (the "License");
+ * you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
+ *
+ * Software distributed under the License is distributed AS IS,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied.
+ * See the License for the specific language governing rights
+ * and limitations under the License.
+ *
+ * The Original Code was created by Alex Peshkov
+ * for the Firebird Open Source RDBMS project.
+ *
+ * Copyright (c) 2019 Alex Peshkov <peshkoff at mail.ru>
+ * and all contributors signed below.
+ *
+ * All Rights Reserved.
+ * Contributor(s): ______________________________________.
+ *
+ *
+ */
+
+set term ^;
+
+execute block as begin
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'DIV')) then execute statement
+'alter function div (
+ n1 integer,
+ n2 integer
+) returns double precision
+ external name ''udf_compat!UC_div''
+ engine udr';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'FRAC')) then execute statement
+'alter function frac (
+ val double precision
+) returns double precision
+ external name ''udf_compat!UC_frac''
+ engine udr';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'UDF_FRAC')) then execute statement
+'alter function udf_frac (
+ val double precision
+) returns double precision
+ external name ''udf_compat!UC_frac''
+ engine udr';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'DOW')) then execute statement
+'alter function dow (
+ val timestamp
+) returns varchar(14) character set ascii
+ external name ''udf_compat!UC_dow''
+ engine udr';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'SDOW')) then execute statement
+'alter function sdow (
+ val timestamp
+) returns varchar(4) character set ascii
+ external name ''udf_compat!UC_sdow''
+ engine udr';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'GETEXACTTIMESTAMPUTC')) then execute statement
+'alter function getExactTimestampUTC
+ returns timestamp
+ external name ''udf_compat!UC_getExactTimestampUTC''
+ engine udr';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'ISLEAPYEAR')) then begin
+execute statement
+'create or alter function booleanIsLeapYear (
+ val timestamp
+) returns boolean
+ external name ''udf_compat!UC_isLeapYear''
+ engine udr';
+execute statement
+'alter function isLeapYear (
+ val timestamp
+) returns int
+as
+begin
+ if (booleanIsLeapYear(val)) then return 1;
+ return 0;
+end
+';
+end
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'LTRIM')) then execute statement
+'
+alter function ltrim (
+ val varchar(255)
+) returns varchar(255)
+as
+begin
+ return trim(leading from val);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'RTRIM')) then execute statement
+'
+alter function rtrim (
+ val varchar(255)
+) returns varchar(255)
+as
+begin
+ return trim(trailing from val);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'SUBSTR')) then execute statement
+'
+alter function substr (
+ val varchar(255),
+ vfrom smallint,
+ vto smallint
+) returns varchar(255)
+as
+begin
+ if (vto < vfrom) then
+ return '''';
+ return substring(val from vfrom for (vto + 1 - vfrom));
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'SUBSTRLEN')) then execute statement
+'
+alter function substrlen (
+ val varchar(255),
+ vfrom smallint,
+ vfor smallint
+) returns varchar(255)
+as
+begin
+ return substring(val from vfrom for vfor);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'STRLEN')) then execute statement
+'
+alter function strlen (
+ val varchar(32764) character set none
+) returns integer
+as
+begin
+ return octet_length(val);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'INVL')) then execute statement
+'
+alter function invl (
+ v1 int,
+ v2 int
+) returns int
+as
+begin
+ return coalesce(v1, v2);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'I64NVL')) then execute statement
+'
+alter function i64nvl (
+ v1 numeric(18,0),
+ v2 numeric(18,0)
+) returns numeric(18,0)
+as
+begin
+ return coalesce(v1, v2);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'DNVL')) then execute statement
+'
+alter function dnvl (
+ v1 double precision,
+ v2 double precision
+) returns double precision
+as
+begin
+ return coalesce(v1, v2);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'SNVL')) then execute statement
+'
+alter function snvl (
+ v1 varchar(100),
+ v2 varchar(100)
+) returns varchar(100)
+as
+begin
+ return coalesce(v1, v2);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'INULLIF')) then execute statement
+'
+alter function inullif (
+ v1 int,
+ v2 int
+) returns int
+as
+begin
+ return nullif(v1, v2);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'DNULLIF')) then execute statement
+'
+alter function dnullif (
+ v1 double precision,
+ v2 double precision
+) returns double precision
+as
+begin
+ return nullif(v1, v2);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'I64NULLIF')) then execute statement
+'
+alter function i64nullif (
+ v1 numeric(18,4),
+ v2 numeric(18,4)
+) returns numeric(18,4)
+as
+begin
+ return nullif(v1, v2);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'SNULLIF')) then execute statement
+'
+alter function snullif (
+ v1 varchar(100),
+ v2 varchar(100)
+) returns varchar(100)
+as
+begin
+ return nullif(v1, v2);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'SRIGHT')) then execute statement
+'
+alter function sright (
+ v1 varchar(100),
+ v2 smallint
+) returns varchar(100)
+as
+begin
+ return right(v1, v2);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'ADDDAY')) then execute statement
+'
+alter function addDay (
+ v timestamp,
+ ndays int
+) returns timestamp
+as
+begin
+ return dateadd(ndays day to v);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'ADDDAY2')) then execute statement
+'
+alter function addDay2 (
+ v timestamp,
+ ndays int
+) returns timestamp
+as
+begin
+ return dateadd(ndays day to v);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'ADDWEEK')) then execute statement
+'
+alter function addWeek (
+ v timestamp,
+ nweeks int
+) returns timestamp
+as
+begin
+ return dateadd(nweeks week to v);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'ADDMONTH')) then execute statement
+'
+alter function addMonth (
+ v timestamp,
+ nmonths int
+) returns timestamp
+as
+begin
+ return dateadd(nmonths month to v);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'ADDYEAR')) then execute statement
+'
+alter function addYear (
+ v timestamp,
+ nyears int
+) returns timestamp
+as
+begin
+ return dateadd(nyears year to v);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'ADDMILLISECOND')) then execute statement
+'
+alter function addMilliSecond (
+ v timestamp,
+ nMilliseconds int
+) returns timestamp
+as
+begin
+ return dateadd(nMilliseconds millisecond to v);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'ADDSECOND')) then execute statement
+'
+alter function addSecond (
+ v timestamp,
+ nseconds int
+) returns timestamp
+as
+begin
+ return dateadd(nseconds second to v);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'ADDMINUTE')) then execute statement
+'
+alter function addMinute (
+ v timestamp,
+ nminutes int
+) returns timestamp
+as
+begin
+ return dateadd(nminutes minute to v);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'ADDHOUR')) then execute statement
+'
+alter function addHour (
+ v timestamp,
+ nhours int
+) returns timestamp
+as
+begin
+ return dateadd(nhours hour to v);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'TRUNCATE')) then execute statement
+'
+alter function Truncate (
+ v numeric(9, 2)
+) returns integer
+as
+begin
+ return cast (v - 0.5 as integer);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'I64TRUNCATE')) then execute statement
+'
+alter function i64Truncate (
+ v numeric(18, 4)
+) returns numeric(18)
+as
+begin
+ return cast (v - 0.5 as bigint);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'ROUND')) then execute statement
+'
+alter function Round (
+ v numeric(9, 2)
+) returns integer
+as
+begin
+ return cast (v as integer);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'I64ROUND')) then execute statement
+'
+alter function i64Round (
+ v numeric(18, 4)
+) returns numeric(18)
+as
+begin
+ return cast (v as bigint);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'DPOWER')) then execute statement
+'
+alter function dPower (
+ b double precision, p double precision
+) returns double precision
+as
+begin
+ return power(b, p);
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'STRING2BLOB')) then execute statement
+'
+alter function string2blob (
+ s varchar(300)
+) returns blob
+as
+begin
+ return s;
+end
+';
+
+if (exists(select * from RDB$FUNCTIONS where RDB$MODULE_NAME is not null and RDB$FUNCTION_NAME = 'GETEXACTTIMESTAMP')) then execute statement
+'
+alter function getExactTimestamp
+returns timestamp
+as
+begin
+ return localtimestamp;
+end
+';
+
+end^
+
+set term ;^
+
+commit;
diff --git a/src/misc/upgrade/v4.0/udf_replace.txt b/src/misc/upgrade/v4.0/udf_replace.txt
new file mode 100644
index 0000000000..28d4cbefcc
--- /dev/null
+++ b/src/misc/upgrade/v4.0/udf_replace.txt
@@ -0,0 +1,56 @@
+*****************************************************************
+What to do when after restoring 3.0 database in FB4 you get:
+"function XXX is not defined" errors?
+*****************************************************************
+
+UDFs (implemented in dynamic libraries and defined in database using
+statement DECLARE FUNCTION functions) are deprecated in FB4. That means
+that UdfAccess parameter in firebird.conf defaults to 'None' instead
+'Restrict UDF' and no UDF libraries are distributed with firebird.
+But you can implement your own dynamic library (or use one from
+previous FB version), tune configuration and work with deprecated
+functions format. Certainly this is not recommended solution - you
+should better switch to use of UDR or PSQL functions, and in order
+to simplify that a little script replacing functions distributed with
+previous FB versions is present.
+
+First of all take into an account that most of ib_udf/fbudf functions
+were already replaced with builtin functions in prior versions (like
+trigonometric, logarithmic and exponential functions). A lot of others
+have direct replacement with builtin functions (like invl with
+coalesce). But replacing them in real database during (and together
+with) firebird upgrade is hardly good idea therefore this script
+which converts UDFs to exact PSQL/UDR replacement is provided.
+
+In a case when you get warnings like:
+gbak: WARNING:function UDF_FRAC is not defined
+gbak: WARNING: module name or entrypoint could not be found
+
+First of all check - is mentioned function (UDF_FRAC in this example)
+from the list of distributed with previous FB version functions:
+ADDDAY ADDDAY2
+ADDHOUR ADDMILLISECOND
+ADDMINUTE ADDMONTH
+ADDSECOND ADDWEEK
+ADDYEAR DIV
+DNULLIF DNVL
+DOW DPOWER
+GETEXACTTIMESTAMP GETEXACTTIMESTAMPUTC
+I64NULLIF I64NVL
+I64ROUND I64TRUNCATE
+INULLIF INVL
+ISLEAPYEAR LTRIM
+ROUND RTRIM
+SDOW SNULLIF
+SNVL SRIGHT
+STRING2BLOB STRLEN
+SUBSTR SUBSTRLEN
+TRUNCATE UDF_FRAC
+
+If yes this script will help you quickly solve that problem. Just run it:
+ isql -user sysdba -pas masterkey -i udf_replace.sql {your-database}
+and UDFs distributed in ib_udf and fbudf will be replaced with appropriate
+modern functions.
+
+WARNING: Script has nothing to do with THIRD-PARTY libraries!!!
+
--
2.51.0