Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6217053

Browse files
committed
Avoid ERRCODE_INTERNAL_ERROR in oracle_compat.c functions.
repeat() checked for integer overflow during its calculation of therequired output space, but it just passed the resulting integer topalloc(). This meant that result sizes between 1GB and 2GB led toERRCODE_INTERNAL_ERROR, "invalid memory alloc request size" ratherthan ERRCODE_PROGRAM_LIMIT_EXCEEDED, "requested length too large".That seems like a bit of a wart, so add an explicit AllocSizeIsValidcheck to make these error cases uniform.Do likewise in the sibling functions lpad() etc. While we're here,also modernize their overflow checks to use pg_mul_s32_overflow() etcinstead of expensive divisions.Per complaint from Japin Li. This is basically cosmetic, so I don'tfeel a need to back-patch.Discussion:https://postgr.es/m/ME3P282MB16676ED32167189CB0462173B6D69@ME3P282MB1667.AUSP282.PROD.OUTLOOK.COM
1 parentde89d87 commit6217053

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

‎src/backend/utils/adt/oracle_compat.c

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include"miscadmin.h"
2121
#include"utils/builtins.h"
2222
#include"utils/formatting.h"
23+
#include"utils/memutils.h"
24+
2325

2426
statictext*dotrim(constchar*string,intstringlen,
2527
constchar*set,intsetlen,
@@ -155,7 +157,6 @@ lpad(PG_FUNCTION_ARGS)
155157
intm,
156158
s1len,
157159
s2len;
158-
159160
intbytelen;
160161

161162
/* Negative len is silently taken as zero */
@@ -178,15 +179,16 @@ lpad(PG_FUNCTION_ARGS)
178179
if (s2len <=0)
179180
len=s1len;/* nothing to pad with, so don't pad */
180181

181-
bytelen=pg_database_encoding_max_length()*len;
182-
183-
/* check for integer overflow */
184-
if (len!=0&&bytelen /pg_database_encoding_max_length()!=len)
182+
/* compute worst-case output length */
183+
if (unlikely(pg_mul_s32_overflow(pg_database_encoding_max_length(),len,
184+
&bytelen))||
185+
unlikely(pg_add_s32_overflow(bytelen,VARHDRSZ,&bytelen))||
186+
unlikely(!AllocSizeIsValid(bytelen)))
185187
ereport(ERROR,
186188
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
187189
errmsg("requested length too large")));
188190

189-
ret= (text*)palloc(VARHDRSZ+bytelen);
191+
ret= (text*)palloc(bytelen);
190192

191193
m=len-s1len;
192194

@@ -253,7 +255,6 @@ rpad(PG_FUNCTION_ARGS)
253255
intm,
254256
s1len,
255257
s2len;
256-
257258
intbytelen;
258259

259260
/* Negative len is silently taken as zero */
@@ -276,15 +277,17 @@ rpad(PG_FUNCTION_ARGS)
276277
if (s2len <=0)
277278
len=s1len;/* nothing to pad with, so don't pad */
278279

279-
bytelen=pg_database_encoding_max_length()*len;
280-
281-
/* Check for integer overflow */
282-
if (len!=0&&bytelen /pg_database_encoding_max_length()!=len)
280+
/* compute worst-case output length */
281+
if (unlikely(pg_mul_s32_overflow(pg_database_encoding_max_length(),len,
282+
&bytelen))||
283+
unlikely(pg_add_s32_overflow(bytelen,VARHDRSZ,&bytelen))||
284+
unlikely(!AllocSizeIsValid(bytelen)))
283285
ereport(ERROR,
284286
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
285287
errmsg("requested length too large")));
286288

287-
ret= (text*)palloc(VARHDRSZ+bytelen);
289+
ret= (text*)palloc(bytelen);
290+
288291
m=len-s1len;
289292

290293
ptr1=VARDATA_ANY(string1);
@@ -805,7 +808,7 @@ translate(PG_FUNCTION_ARGS)
805808
tolen,
806809
retlen,
807810
i;
808-
intworst_len;
811+
intbytelen;
809812
intlen;
810813
intsource_len;
811814
intfrom_index;
@@ -824,15 +827,16 @@ translate(PG_FUNCTION_ARGS)
824827
* The worst-case expansion is to substitute a max-length character for a
825828
* single-byte character at each position of the string.
826829
*/
827-
worst_len=pg_database_encoding_max_length()*m;
828-
829-
/* check for integer overflow */
830-
if (worst_len /pg_database_encoding_max_length()!=m)
830+
if (unlikely(pg_mul_s32_overflow(pg_database_encoding_max_length(),m,
831+
&bytelen))||
832+
unlikely(pg_add_s32_overflow(bytelen,VARHDRSZ,&bytelen))||
833+
unlikely(!AllocSizeIsValid(bytelen)))
831834
ereport(ERROR,
832835
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
833836
errmsg("requested length too large")));
834837

835-
result= (text*)palloc(worst_len+VARHDRSZ);
838+
result= (text*)palloc(bytelen);
839+
836840
target=VARDATA(result);
837841
retlen=0;
838842

@@ -1128,7 +1132,8 @@ repeat(PG_FUNCTION_ARGS)
11281132
slen=VARSIZE_ANY_EXHDR(string);
11291133

11301134
if (unlikely(pg_mul_s32_overflow(count,slen,&tlen))||
1131-
unlikely(pg_add_s32_overflow(tlen,VARHDRSZ,&tlen)))
1135+
unlikely(pg_add_s32_overflow(tlen,VARHDRSZ,&tlen))||
1136+
unlikely(!AllocSizeIsValid(tlen)))
11321137
ereport(ERROR,
11331138
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
11341139
errmsg("requested length too large")));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp