1
1
Fork 0
mirror of https://github.com/QB64-Phoenix-Edition/QB64pe.git synced 2024-07-12 22:45:13 +00:00

Merge pull request #428 from a740g/main

Fix OPEN COM from locking up inside gfs_open_com_syntax()
This commit is contained in:
Samuel Gomes 2024-01-05 22:44:46 +05:30 committed by GitHub
commit d040763823
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -29163,46 +29163,46 @@ int64 gfs_lof(int32 i) {
return -1; return -1;
} }
int32 gfs_open_com_syntax(qbs *fstr, gfs_file_struct *f) { int32_t gfs_open_com_syntax(qbs *fstr, gfs_file_struct *f) {
// 0=not an open com statement // 0=not an open com statement
//-1=syntax error //-1=syntax error
// 1=valid // 1=valid
// check if filename is a COM open command // check if filename is a COM open command
static int32 x, i;
static int32 v, c, z;
f->com_port = 0; f->com_port = 0;
if (fstr->len <= 3)
return 0; if (fstr->len <= 3 || (fstr->chr[0] & 223) != 67 || (fstr->chr[1] & 223) != 79 || (fstr->chr[2] & 223) != 77)
if ((fstr->chr[0] & 223) != 67) return 0; // ! C/c,O/o,M/m
return 0; //"C"/"c"
if ((fstr->chr[1] & 223) != 79) int32_t c, i, v = -1, x = 0;
return 0; //"O"/"o"
if ((fstr->chr[2] & 223) != 77)
return 0; //"M"/"m"
v = -1;
for (i = 3; i < fstr->len - 1; i++) { for (i = 3; i < fstr->len - 1; i++) {
c = fstr->chr[i]; c = fstr->chr[i];
if (c == 58) if (c == ':')
goto comstatment; goto comstatment;
if ((c < 48) || (c > 57)) if ((c < '0') || (c > '9'))
return 0; // not 0-9 return 0; // not 0-9
if (v == -1) { if (v == -1) {
if (c == 48) if (c == '0')
return 0; // first digit 0 return 0; // first digit 0
v = 0; v = 0;
} }
v = v * 10 + (c - 48); v = v * 10 + (c - '0');
} }
return 0; // no ":" return 0; // no ":"
comstatment: comstatment:
if ((x >= 7) || (v <= 0) || (v > 255)) if (x >= 7 || v <= 0 || v > 255)
return -1; // invalid port number (1-255) return -1; // invalid port number (1-255)
f->com_port = v; f->com_port = v;
// COM open confirmed // COM open confirmed
static qbs *str = NULL; static qbs *str = nullptr;
if (!str) if (!str)
str = qbs_new(0, 0); str = qbs_new(0, 0);
qbs_set(str, qbs_ucase(fstr)); qbs_set(str, qbs_ucase(fstr));
str->len--; // remove null term. str->len--; // remove null term.
@ -29221,25 +29221,26 @@ comstatment:
f->com_ds_x = -1; f->com_ds_x = -1;
f->com_op_x = -1; f->com_op_x = -1;
static int32 str_or_num; int32_t str_or_num = 1;
static int64 strv; int64_t strv = 0;
static int32 stage; int32_t stage = 1;
static int32 com_rb_used, com_tb_used; int32_t com_rb_used = 0;
com_rb_used = 0; int32_t com_tb_used = 0;
com_tb_used = 0;
stage = 1;
str_or_num = 1;
strv = 0;
v = -1; v = -1;
for (i = i + 1; i < str->len; i++) { for (i = i + 1; i < str->len; i++) {
c = str->chr[i]; c = str->chr[i];
if (c != 44) {
if ((c < 48) || ((c > 57) && (c < 65)) || (c > 90)) if (c != ',') {
if ((c < '0') || ((c > '9') && (c < 'A')) || (c > 'Z'))
return -1; // invalid character return -1; // invalid character
if ((str_or_num == 2) && (c >= 65))
if ((str_or_num == 2) && (c >= 'A'))
return -1; // invalid character return -1; // invalid character
if (c < 65)
if (c < 'A')
str_or_num = 2; // ABC->123 str_or_num = 2; // ABC->123
if ((str_or_num == 1) || (stage == 4)) { // note: stage 4 is interpreted as a string if ((str_or_num == 1) || (stage == 4)) { // note: stage 4 is interpreted as a string
if (strv & 0xFF0000) if (strv & 0xFF0000)
strv = strv | (c << 24); strv = strv | (c << 24);
@ -29249,20 +29250,26 @@ comstatment:
strv = strv | (c << 8); strv = strv | (c << 8);
else else
strv = strv = c; strv = strv = c;
if (strv > 16777216) if (strv > 16777216)
return -1; // string option too long (max 3 characters) return -1; // string option too long (max 3 characters)
} else { } else {
if ((c > 48) && (c <= 57)) { if ((c > '0') && (c <= '9')) {
if (v == -2) if (v == -2)
return -1; // leading 0s are invalid return -1; // leading 0s are invalid
if (v == -1) if (v == -1)
v = 0; v = 0;
v = v * 10 + (c - 48);
v = v * 10 + (c - '0');
} else { // 0 } else { // 0
if (v == -2) if (v == -2)
return -1; // leading 0s are invalid return -1; // leading 0s are invalid
if (v == -1) if (v == -1)
v = -2; // 0... v = -2; // 0...
if (v > 0) if (v > 0)
v = v * 10; v = v * 10;
} }
@ -29270,76 +29277,104 @@ comstatment:
return -1; // numeric value too large (LONG values only) return -1; // numeric value too large (LONG values only)
} }
} // c!=44 } // c!=44
if ((c == 44) || (i == str->len - 1)) {
if ((c == ',') || (i == str->len - 1)) {
if (v == -2) if (v == -2)
v = 0; v = 0;
// note: v==-1 means omit // note: v==-1 means omit
if (stage == 1) { if (stage == 1) {
if (f->com_baud_rate != -1) if (f->com_baud_rate != -1)
return -1; return -1;
if (strv) if (strv)
return -1; return -1;
if (v == 0) if (v == 0)
return -1; return -1;
if (v == -1) if (v == -1)
v = 300; v = 300;
f->com_baud_rate = v; f->com_baud_rate = v;
stage++; stage++;
goto done_stage; goto done_stage;
} } else if (stage == 2) {
if (stage == 2) {
if (f->com_parity != -1) if (f->com_parity != -1)
return -1; return -1;
if (v != -1) if (v != -1)
return -1; return -1;
x = -1; x = -1;
if (strv == 78) if (strv == 78)
x = 0; // N x = 0; // N
if (strv == 0) if (strv == 0)
x = 1; // E* x = 1; // E*
if (strv == 69) if (strv == 69)
x = 1; // E x = 1; // E
if (strv == 79) if (strv == 79)
x = 2; // O x = 2; // O
if (strv == 83) if (strv == 83)
x = 3; // S x = 3; // S
if (strv == 77) if (strv == 77)
x = 4; // M x = 4; // M
if (strv == 17744) if (strv == 17744)
x = 5; // PE x = 5; // PE
if (x == -1) if (x == -1)
return -1; return -1;
f->com_parity = x; f->com_parity = x;
stage++; stage++;
goto done_stage; goto done_stage;
} } else if (stage == 3) {
if (stage == 3) {
if (f->com_data_bits_per_byte != -1) if (f->com_data_bits_per_byte != -1)
return -1; return -1;
if (strv) if (strv)
return -1; return -1;
x = -1; x = -1;
if (v == -1) if (v == -1)
x = 7; x = 7;
if (v == 5) if (v == 5)
x = 5; x = 5;
if (v == 6) if (v == 6)
x = 6; x = 6;
if (v == 7) if (v == 7)
x = 7; x = 7;
if (v == 8) if (v == 8)
x = 8; x = 8;
if (x == -1) if (x == -1)
return -1; return -1;
f->com_data_bits_per_byte = x; f->com_data_bits_per_byte = x;
stage++; stage++;
goto done_stage; goto done_stage;
} } else if (stage == 4) {
if (stage == 4) {
if (f->com_stop_bits != -1) if (f->com_stop_bits != -1)
return -1; return -1;
if (v != -1) if (v != -1)
return -1; return -1;
x = -1; x = -1;
if (strv == 0) { if (strv == 0) {
x = 10; x = 10;
@ -29349,98 +29384,134 @@ comstatment:
x = 15; x = 15;
} }
} // 0 } // 0
if (strv == 49) if (strv == 49)
x = 10; //"1" x = 10; //"1"
if (strv == 3485233) if (strv == 3485233)
x = 15; //"1.5" x = 15; //"1.5"
if (strv == 50) if (strv == 50)
x = 20; //"2" x = 20; //"2"
if (x == -1) if (x == -1)
return -1; return -1;
f->com_stop_bits = x; f->com_stop_bits = x;
stage++; stage++;
goto done_stage; goto done_stage;
} }
// stage > 4 // stage > 4
if (!strv) if (!strv)
return -1; // all options after 4 require a string return -1; // all options after 4 require a string
if (strv == 21330) { if (strv == 21330) {
if (f->com_rs != -1) if (f->com_rs != -1)
return -1; // RS return -1; // RS
f->com_rs = 1; f->com_rs = 1;
goto done_stage; goto done_stage;
} }
if (strv == 5130562) { if (strv == 5130562) {
if (f->com_bin_asc != -1) if (f->com_bin_asc != -1)
return -1; // BIN return -1; // BIN
f->com_bin_asc = 0; f->com_bin_asc = 0;
goto done_stage; goto done_stage;
} }
if (strv == 4412225) { if (strv == 4412225) {
if (f->com_bin_asc != -1) if (f->com_bin_asc != -1)
return -1; // ASC return -1; // ASC
f->com_bin_asc = 1; f->com_bin_asc = 1;
goto done_stage; goto done_stage;
} }
if (strv == 16980) { if (strv == 16980) {
if (com_tb_used) if (com_tb_used)
return -1; // TB return -1; // TB
com_tb_used = 1; com_tb_used = 1;
goto done_stage; goto done_stage;
} }
if (strv == 16978) { if (strv == 16978) {
if (com_rb_used) if (com_rb_used)
return -1; // RB return -1; // RB
com_rb_used = 1; com_rb_used = 1;
goto done_stage; goto done_stage;
} }
if (strv == 17996) { if (strv == 17996) {
if (f->com_asc_lf != -1) if (f->com_asc_lf != -1)
return -1; // LF return -1; // LF
f->com_asc_lf = 1; f->com_asc_lf = 1;
goto done_stage; goto done_stage;
} }
if (strv == 17475) { if (strv == 17475) {
if (f->com_cd_x != -1) if (f->com_cd_x != -1)
return -1; // CD return -1; // CD
if (v == -1) if (v == -1)
v = 0; v = 0;
if (v > 65535) if (v > 65535)
return -1; return -1;
f->com_cd_x = v; f->com_cd_x = v;
goto done_stage; goto done_stage;
} }
if (strv == 21315) { if (strv == 21315) {
if (f->com_cs_x != -1) if (f->com_cs_x != -1)
return -1; // CS return -1; // CS
if (v == -1) if (v == -1)
v = 1000; v = 1000;
if (v > 65535) if (v > 65535)
return -1; return -1;
f->com_cs_x = v; f->com_cs_x = v;
goto done_stage; goto done_stage;
} }
if (strv == 21316) { if (strv == 21316) {
if (f->com_ds_x != -1) if (f->com_ds_x != -1)
return -1; // DS return -1; // DS
if (v == -1) if (v == -1)
v = 1000; v = 1000;
if (v > 65535) if (v > 65535)
return -1; return -1;
f->com_ds_x = v; f->com_ds_x = v;
goto done_stage; goto done_stage;
} }
if (strv == 20559) { if (strv == 20559) {
if (f->com_op_x != -1) if (f->com_op_x != -1)
return -1; // OP return -1; // OP
if (v == -1) if (v == -1)
v = 10000; v = 10000;
if (v > 65535) if (v > 65535)
return -1; return -1;
f->com_op_x = v; f->com_op_x = v;
goto done_stage; goto done_stage;
} }
return -1; // invalid option return -1; // invalid option
done_stage: done_stage:
str_or_num = 1; str_or_num = 1;
strv = 0; strv = 0;
@ -29451,10 +29522,13 @@ comstatment:
// complete omitted options with defaults // complete omitted options with defaults
if (f->com_baud_rate == -1) if (f->com_baud_rate == -1)
f->com_baud_rate = 300; f->com_baud_rate = 300;
if (f->com_parity == -1) if (f->com_parity == -1)
f->com_parity = 1; f->com_parity = 1;
if (f->com_data_bits_per_byte == -1) if (f->com_data_bits_per_byte == -1)
f->com_data_bits_per_byte = 7; f->com_data_bits_per_byte = 7;
if (f->com_stop_bits == -1) { if (f->com_stop_bits == -1) {
x = 10; x = 10;
if (f->com_baud_rate <= 110) { if (f->com_baud_rate <= 110) {
@ -29462,33 +29536,46 @@ comstatment:
if (f->com_data_bits_per_byte == 5) if (f->com_data_bits_per_byte == 5)
x = 15; x = 15;
} }
f->com_stop_bits = x; f->com_stop_bits = x;
} }
if (f->com_bin_asc == -1) if (f->com_bin_asc == -1)
f->com_bin_asc = 0; f->com_bin_asc = 0;
if (f->com_asc_lf == -1) if (f->com_asc_lf == -1)
f->com_asc_lf = 0; f->com_asc_lf = 0;
if (f->com_asc_lf == 1) { if (f->com_asc_lf == 1) {
if (f->com_bin_asc == 0) if (f->com_bin_asc == 0)
f->com_asc_lf = 0; f->com_asc_lf = 0;
} }
if (f->com_rs == -1) if (f->com_rs == -1)
f->com_rs = 0; f->com_rs = 0;
if (f->com_cd_x == -1) if (f->com_cd_x == -1)
f->com_cd_x = 0; f->com_cd_x = 0;
if (f->com_cs_x == -1) if (f->com_cs_x == -1)
f->com_cs_x = 1000; f->com_cs_x = 1000;
if (f->com_ds_x == -1) if (f->com_ds_x == -1)
f->com_ds_x = 1000; f->com_ds_x = 1000;
if (f->com_op_x == -1) { if (f->com_op_x == -1) {
x = f->com_cd_x * 10; x = f->com_cd_x * 10;
z = f->com_ds_x * 10; auto z = f->com_ds_x * 10;
if (z > x) if (z > x)
x = z; x = z;
if (x > 65535) if (x > 65535)
x = 65535; x = 65535;
f->com_op_x = x; f->com_op_x = x;
} }
return 1; // valid
} }
int32 gfs_open(qbs *filename, int32 access, int32 restrictions, int32 how) { int32 gfs_open(qbs *filename, int32 access, int32 restrictions, int32 how) {