Skip to content

Commit b921088

Browse files
committed
ocesql.c (create_coboldata):
* prefer local buffers over temporary mallocs * only space-pad PIC X/PIC N instead of space-fill then overwrite
1 parent d100e5e commit b921088

File tree

2 files changed

+61
-67
lines changed

2 files changed

+61
-67
lines changed

dblib/ChangeLog

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11

2+
2024-04-26 Simon Sobisch <simonsobisch@gnu.org>
3+
4+
* ocesql.c (create_coboldata): prefer local buffers over temporary mallocs;
5+
only space-pad PIC X/PIC N instead of space-fill then overwrite
6+
27
2024-04-24 Simon Sobisch <simonsobisch@gnu.org>
38

49
* ocesql.c (init_sql_var_list, reset_sql_var_list, add_sql_var_list,
@@ -35,11 +40,16 @@
3540
to current working directory instead of D:\develop
3641
* ocdbutil.c (com_sleep, com_strdup): inlined calculation
3742

43+
2022-01-13 Simon Sobisch <simonsobisch@gnu.org>
44+
45+
* ocesql.c (create_coboldata): fixed buffer-overflows with COMP-3
46+
and signed DISPLAY
47+
3848
2021-07-05 Simon Sobisch <simonsobisch@gnu.org>
3949

4050
* Makefile.am: added EXTRA_DIST to ship headers, necessary for make dist
4151

42-
Copyright 2021 Simon Sobisch
52+
Copyright 2021,2022,2024 Simon Sobisch
4353

4454
Copying and distribution of this file, with or without modification, are
4555
permitted provided the copyright notice and this notice are preserved.

dblib/ocesql.c

Lines changed: 50 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "ocdbutil.h"
2727
#include "ocesql.h"
2828

29+
#define MAX_DIGITS 38
30+
2931
typedef struct sql_var {
3032
int type; // set OCDB_TYPE_*
3133
int length; // size
@@ -2767,12 +2769,7 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
27672769

27682770
int fillzero;
27692771
int zcount;
2770-
char *final;
2771-
int finalbuflen;
2772-
2773-
// fill zero
2774-
finalbuflen = sv->length + TERMINAL_LENGTH;
2775-
final = (char *)calloc(finalbuflen, sizeof(char));
2772+
char final[MAX_DIGITS + 1 + TERMINAL_LENGTH] = { 0 };
27762773

27772774
// before decimal point
27782775
int beforedp = 0;
@@ -2813,7 +2810,6 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
28132810
}
28142811

28152812
memcpy(addr, final, sv->length);
2816-
free(final);
28172813
break;
28182814
}
28192815
case OCDB_TYPE_SIGNED_NUMBER_TC:
@@ -2824,14 +2820,9 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
28242820

28252821
int fillzero;
28262822
int zcount;
2827-
char *final;
2828-
int finalbuflen;
2823+
char final[MAX_DIGITS + SIGN_LENGTH + 1 + TERMINAL_LENGTH] = {0};
28292824
int final_length;
28302825

2831-
// fill zero
2832-
finalbuflen = sv->length;
2833-
final = (char *)calloc(finalbuflen, sizeof(char));
2834-
28352826
if(retstr[0] == '-'){
28362827
is_negative = true;
28372828
value = retstr + 1;
@@ -2883,7 +2874,6 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
28832874
}
28842875

28852876
memcpy(addr, final, sv->length);
2886-
free(final);
28872877
break;
28882878
}
28892879
case OCDB_TYPE_SIGNED_NUMBER_LS:
@@ -2893,12 +2883,7 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
28932883

28942884
int fillzero;
28952885
int zcount;
2896-
char *final;
2897-
int finalbuflen;
2898-
2899-
// fill zero
2900-
finalbuflen = SIGN_LENGTH + sv->length + TERMINAL_LENGTH;
2901-
final = (char *)calloc(finalbuflen, sizeof(char));
2886+
char final[MAX_DIGITS + SIGN_LENGTH + 1 + TERMINAL_LENGTH] = {0};
29022887

29032888
if(retstr[0] == '-'){
29042889
final[0] = '-';
@@ -2947,7 +2932,6 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
29472932
}
29482933

29492934
memcpy(addr, final, sv->length + SIGN_LENGTH);
2950-
free(final);
29512935
break;
29522936
}
29532937
case OCDB_TYPE_UNSIGNED_NUMBER_PD:
@@ -2958,9 +2942,9 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
29582942

29592943
int fillzero;
29602944
int zcount;
2961-
char *pre_final;
2962-
int pre_final_len;
2963-
char *final;
2945+
2946+
char pre_final[MAX_DIGITS];
2947+
char final[(MAX_DIGITS + 1) / 2];
29642948

29652949
int i;
29662950
unsigned char ubit = 0xF0;
@@ -2969,9 +2953,6 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
29692953
const int dlength = (sv->length / 2) + 1;
29702954
const int skip_first = (sv->length + 1) % 2; // 1 -> skip first 4 bits
29712955

2972-
pre_final_len = sv->length + TERMINAL_LENGTH;
2973-
pre_final = (char *)calloc(pre_final_len, sizeof(char));
2974-
29752956
// before decimal point
29762957
int beforedp = 0;
29772958
for(ptr = value; *ptr != '\0'; ptr++){
@@ -3010,7 +2991,6 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
30102991
}
30112992

30122993
// format setting
3013-
final = (char *)calloc((int)dlength + TERMINAL_LENGTH, sizeof(char));
30142994
ptr = pre_final;
30152995
for(i=0; i<dlength; i++){
30162996
unsigned char vubit = 0x00;
@@ -3035,9 +3015,7 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
30353015
final[i] = vubit | vlbit;
30363016
}
30373017

3038-
memcpy(addr, final, (int)dlength);
3039-
free(pre_final);
3040-
free(final);
3018+
memcpy(addr, final, dlength);
30413019
break;
30423020
}
30433021
case OCDB_TYPE_SIGNED_NUMBER_PD:
@@ -3048,9 +3026,9 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
30483026

30493027
int fillzero;
30503028
int zcount;
3051-
char *pre_final;
3052-
int pre_final_len;
3053-
char *final;
3029+
3030+
char pre_final [MAX_DIGITS];
3031+
char final[(MAX_DIGITS + 1) / 2];
30543032

30553033
int i;
30563034
unsigned char ubit = 0xF0;
@@ -3066,9 +3044,6 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
30663044
value = retstr;
30673045
}
30683046

3069-
pre_final_len = (int)dlength + TERMINAL_LENGTH;
3070-
pre_final = (char *)calloc(pre_final_len, sizeof(char));
3071-
30723047
// before decimal point
30733048
int beforedp = 0;
30743049
for(ptr = value; *ptr != '\0'; ptr++){
@@ -3107,7 +3082,6 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
31073082
}
31083083

31093084
// format setting
3110-
final = (char *)calloc((int)dlength + TERMINAL_LENGTH, sizeof(char));
31113085
ptr = pre_final;
31123086
for(i=0; i<dlength; i++){
31133087
unsigned char vubit = 0x00;
@@ -3136,65 +3110,75 @@ create_coboldata(SQLVAR *sv, int index, char *retstr){
31363110
final[i] = vubit | vlbit;
31373111
}
31383112

3139-
memcpy(addr, final, (int)dlength);
3140-
free(pre_final);
3141-
free(final);
3113+
memcpy(addr, final, dlength);
31423114
break;
31433115
}
3144-
case OCDB_TYPE_ALPHANUMERIC:
3116+
case OCDB_TYPE_ALPHANUMERIC: {
31453117
// 文字の長さだけメモリコピー
3146-
if(strlen(retstr) >= sv->length){
3118+
const size_t rlen = strlen(retstr);
3119+
if(rlen >= sv->length){
31473120
memcpy(addr, retstr, sv->length);
31483121
}else{
3149-
memset(addr,' ',sv->length);
3150-
memcpy(addr,retstr,strlen(retstr));
3122+
memcpy(addr,retstr,rlen);
3123+
memset(addr + rlen,' ',sv->length - rlen);
31513124
}
31523125
break;
3153-
case OCDB_TYPE_JAPANESE:
3126+
}
3127+
case OCDB_TYPE_JAPANESE: {
31543128
// 文字の長さだけメモリコピー
3155-
if(strlen(retstr) >= sv->length*2){
3156-
memcpy(addr, retstr, sv->length*2);
3129+
const size_t memlen = sv->length*2;
3130+
const size_t rlen = strlen(retstr);
3131+
if(rlen >= memlen){
3132+
memcpy(addr, retstr, memlen);
31573133
}else{
3158-
int i;
3159-
char *tmp = (char *)addr;
3160-
for(i=0;i+1<sv->length*2;i=i+2){
3134+
size_t i;
3135+
char *tmp;
3136+
memcpy(addr,retstr,rlen);
3137+
tmp = (char *)addr + rlen;
3138+
for(i=0;i+1<(memlen - rlen);i=i+2){
31613139
tmp[i] = 0x81;
31623140
tmp[i+1] = 0x40;
31633141
}
3164-
memcpy(addr,retstr,strlen(retstr));
31653142
}
31663143
break;
3167-
case OCDB_TYPE_ALPHANUMERIC_VARYING:
3168-
if(strlen(retstr) >= sv->length){
3144+
}
3145+
case OCDB_TYPE_ALPHANUMERIC_VARYING: {
3146+
const size_t rlen = strlen(retstr);
3147+
if(rlen >= sv->length){
31693148
tmp_len = sv->length;
31703149
memcpy(addr, &tmp_len, OCDB_VARCHAR_HEADER_BYTE);
31713150
memcpy((char *)addr + OCDB_VARCHAR_HEADER_BYTE, retstr, sv->length);
31723151
} else {
3173-
tmp_len = strlen(retstr);
3152+
tmp_len = rlen;
31743153
memcpy(addr, &tmp_len, OCDB_VARCHAR_HEADER_BYTE);
3175-
memset((char *)addr + OCDB_VARCHAR_HEADER_BYTE,' ',sv->length);
3176-
memcpy((char *)addr + OCDB_VARCHAR_HEADER_BYTE,retstr,strlen(retstr));
3154+
memcpy((char *)addr + OCDB_VARCHAR_HEADER_BYTE,retstr,rlen);
3155+
memset((char *)addr + OCDB_VARCHAR_HEADER_BYTE + rlen,' ',sv->length - rlen);
31773156
}
31783157
LOG("VARYING-LEN:%d\n",tmp_len);
31793158
break;
3180-
case OCDB_TYPE_JAPANESE_VARYING:
3181-
if(strlen(retstr) >= sv->length*2){
3159+
}
3160+
case OCDB_TYPE_JAPANESE_VARYING: {
3161+
const size_t memlen = sv->length*2;
3162+
const size_t rlen = strlen(retstr);
3163+
if(rlen >= memlen){
31823164
tmp_len = sv->length;
31833165
memcpy(addr, &tmp_len, OCDB_VARCHAR_HEADER_BYTE);
3184-
memcpy(addr, retstr, sv->length*2);
3185-
}else{
3166+
memcpy(addr, retstr, memlen);
3167+
} else {
31863168
int i;
3187-
char *tmp = (char *)((char *)addr+OCDB_VARCHAR_HEADER_BYTE);
3188-
for(i=0;i+1<sv->length*2;i=i+2){
3169+
char *tmp;
3170+
tmp_len = rlen/2;
3171+
memcpy(addr, &tmp_len, OCDB_VARCHAR_HEADER_BYTE);
3172+
memcpy((char *)addr + OCDB_VARCHAR_HEADER_BYTE + rlen,retstr,rlen);
3173+
tmp = (char *)((char *)addr+OCDB_VARCHAR_HEADER_BYTE+rlen);
3174+
for(i=0;i+1<(memlen-rlen);i=i+2){
31893175
tmp[i] = 0x81;
31903176
tmp[i+1] = 0x40;
31913177
}
3192-
tmp_len = strlen(retstr)/2;
3193-
memcpy(addr, &tmp_len, OCDB_VARCHAR_HEADER_BYTE);
3194-
memcpy((char *)addr + OCDB_VARCHAR_HEADER_BYTE,retstr,tmp_len*2);
31953178
}
31963179
LOG("VARYING-LEN:%d\n",tmp_len);
31973180
break;
3181+
}
31983182
default:
31993183
break;
32003184
}

0 commit comments

Comments
 (0)