--- freem/src/expr.c 2025/03/22 03:05:19 1.6 +++ freem/src/expr.c 2025/04/13 04:22:43 1.13 @@ -1,5 +1,5 @@ /* - * $Id: expr.c,v 1.6 2025/03/22 03:05:19 snw Exp $ + * $Id: expr.c,v 1.13 2025/04/13 04:22:43 snw Exp $ * expression parser * * @@ -24,6 +24,27 @@ * along with FreeM. If not, see . * * $Log: expr.c,v $ + * Revision 1.13 2025/04/13 04:22:43 snw + * Fix snprintf calls + * + * Revision 1.12 2025/04/10 01:24:38 snw + * Remove C++ style comments + * + * Revision 1.11 2025/03/30 01:36:58 snw + * Make it easier to bring back fma_gedit, fix double-free in global handler, limit $CHAR to 7-bit ASCII + * + * Revision 1.10 2025/03/24 04:13:11 snw + * Replace action macro dat with fra_dat to avoid symbol conflict on OS/2 + * + * Revision 1.9 2025/03/24 01:32:22 snw + * Guard declaration of time function in expr.c for portability + * + * Revision 1.8 2025/03/22 04:47:18 snw + * Silently truncate long names in STRING exprs when evaluates to an obsolete MDC standard + * + * Revision 1.7 2025/03/22 03:39:23 snw + * Fix reverse query polyfill call-in from C side and make NAME exprs silently truncate long names in obsolete MDC dialects + * * Revision 1.6 2025/03/22 03:05:19 snw * Comply with X11-96/13 portable length of names * @@ -132,7 +153,7 @@ #define GET 'Y' #define GETX ':' -#if !defined(__OpenBSD__) && !defined(_AIX) && !defined(__osf__) && !defined(MSDOS) && !defined(__vax__) +#if !defined(__OpenBSD__) && !defined(_AIX) && !defined(__osf__) && !defined(MSDOS) && !defined(__vax__) && !defined(__OS2__) long time (); #endif void cond_round (char *a, int digits); @@ -218,13 +239,31 @@ void expr (short extyp) varnam[i++] = ch; } else { - merr_raise (M56); - return; + if ((rtn_dialect () == D_M77) || + (rtn_dialect () == D_M84) || + (rtn_dialect () == D_M90) || + (rtn_dialect () == D_M95)) { + /* silently truncate... yeah, the standard is stupid af */ + continue; + } + else { + merr_raise (M56); + return; + } } } - varnam[i] = EOL; + varnam[i] = EOL; + + #if 0 + { + char gooby[256]; + stcpy (gooby, varnam); + stcnv_m2c (gooby); + printf ("name = '%s'\r\n", gooby); + } + #endif if (ch == '(') { /* it's an array */ @@ -345,8 +384,23 @@ scan_name: merr_raise (INVEXPR); return; } - - varnam[i++] = ch; + + if ((i + 1) <= max_namlen) { + varnam[i++] = ch; + } + else { + if ((rtn_dialect () == D_M77) || + (rtn_dialect () == D_M84) || + (rtn_dialect () == D_M90) || + (rtn_dialect () == D_M95)) { + /* silently truncate... yeah, the standard is stupid af */ + continue; + } + else { + merr_raise (M56); + return; + } + } lastch = ch; } @@ -362,7 +416,24 @@ scan_name: else { /* local variable name */ while (isalnum (ch = *++codptr)) { - varnam[i++] = ch; + + if ((i + 1) <= max_namlen) { + varnam[i++] = ch; + } + else { + if ((rtn_dialect () == D_M77) || + (rtn_dialect () == D_M84) || + (rtn_dialect () == D_M90) || + (rtn_dialect () == D_M95)) { + /* silently truncate... yeah, the standard is stupid af */ + continue; + } + else { + merr_raise (M56); + return; + } + } + } varnam[i] = EOL; @@ -502,7 +573,7 @@ var1: case 'd': /* $DATA */ - ch = dat; + ch = fra_dat; glv_fcn: @@ -704,7 +775,7 @@ d_o_n: if (merr () == UNDEF) { - //smw 15 nov 2023 merr_raise (ierr < 0 ? OK - CTRLB : OK); + /* smw 15 nov 2023 merr_raise (ierr < 0 ? OK - CTRLB : OK); */ merr_clear (); if (*++codptr == ',') { @@ -889,7 +960,7 @@ undefglvn: stcpy (refsav[refsx], zref); stcpy (refsav[refsx++] + 256, zloc); - ierr -= M7; //smw TODO HUH?? + ierr -= M7; arg--; goto nextchr; @@ -1616,7 +1687,9 @@ uparrow: case 'c': /* $CHARACTER */ - { + { + char chrtmp[256]; + long pnum; short l, l1, m, n; l1 = f; @@ -1627,6 +1700,15 @@ uparrow: n = 1; l = 0; + stcpy (chrtmp, a); + stcnv_m2c (chrtmp); + pnum = atol (chrtmp); + + if (pnum > 127) { + merr_raise (MXNUM); + return; + } + for (;;) { if ((ch = a[i++]) == EOL) { @@ -2235,7 +2317,7 @@ f20: stcnv_c2m (qryarg_ext); /* put the $QUERY argument into the local variable %INT.REVQ */ - symtab (set_sym, "%INT.REVQ\201\201", qryarg_ext); + symtab (set_sym, "%INTREVQ\201\201", qryarg_ext); /* set up for calling into polyfill wrapper */ code[0] = '\201'; @@ -4514,9 +4596,9 @@ extra_fun: if (obj_field) { - char t_objf[255]; + char t_objf[STRLEN]; - snprintf (t_objf, 254, "%s\201", object_instance); + snprintf (t_objf, STRLEN - 1, "%s\201", object_instance); dofram0 = dofrmptr; *dofrmptr++ = DELIM; @@ -4531,7 +4613,7 @@ extra_fun: obj_field = FALSE; - //dofram0 = dofrmptr; + /* dofram0 = dofrmptr; */ i = 0; codptr++; @@ -4593,7 +4675,7 @@ extra_fun: obj_field = FALSE; - //dofram0 = 0; + /* dofram0 = 0; */ if (*codptr == '(') codptr += 2; } @@ -4669,7 +4751,7 @@ extra_fun: /* save off the return type to be checked by QUIT code */ extr_types[nstx + 1] = ret_type; - //printf ("return_type = '%s' *reg = '%c'\r\n", return_type, *reg); + /* printf ("return_type = '%s' *reg = '%c'\r\n", return_type, *reg); */ } if (*reg == TAB || *reg == SP) goto off; @@ -4804,21 +4886,23 @@ off: else { /* PARSE FORMALLIST */ short fl_type; - short fl_mandatory; - short fl_byref; + /* re-enable following 3 later */ + /*short fl_mandatory;*/ + /*short fl_byref;*/ + /*short lastparm;*/ char fl_typestr[255]; char fl_mand; short dtcheck_result; register short typei; - short lastparm; short gotparm; int paramct; fl_type = DT_AUTO; - fl_mandatory = TRUE; - fl_byref = FALSE; + /* re-enable following 3 later */ + /*fl_mandatory = TRUE;*/ + /*fl_byref = FALSE;*/ + /*lastparm = FALSE;*/ dtcheck_result = FALSE; - lastparm = FALSE; gotparm = FALSE; paramct = 0; @@ -4841,6 +4925,7 @@ off: fl_typestr[typei] = '\0'; fl_mand = *(reg + 1); + /* if ((fl_mand == 'o') || (fl_mand == 'O')) { fl_mandatory = FALSE; } @@ -4855,12 +4940,29 @@ off: goto errexfun; } + */ + + if ((fl_mand != 'o') && (fl_mand != 'O')) { + merr_raise (INVLIBOPT); + dofrmptr = dofram0; + + errex = TRUE; + + nstx--; + estack--; + + goto errexfun; + } + + } else if ((ch == ',') || (ch == ')')) { + /* re-enable later if (ch == ')') { lastparm = TRUE; } + */ gotparm = TRUE; paramct++; @@ -4897,7 +4999,7 @@ off: if (dtcheck_result == FALSE) { merr_raise (TYPMISMATCH); - dofrmptr = dofram0; // reset frame pointer + dofrmptr = dofram0; /* reset frame pointer */ errex = TRUE; @@ -5418,8 +5520,6 @@ errexfun: ilong = ilong1 - (ilong * 86400); lintstr (&a[i], ilong); - -// printf ("unix epoch = %d\r\n", horolog_to_unix (a)); goto exec; @@ -5462,7 +5562,7 @@ errexfun: { char doggie_bag[50]; - snprintf (doggie_bag, 49, ".%ld\201", ilong); + snprintf (doggie_bag, sizeof (doggie_bag) - 1, ".%ld\201", ilong); stcat (a, doggie_bag); } } @@ -5471,7 +5571,7 @@ errexfun: case SVNsystem: - snprintf (a, 512, "%d,\"%s\"\201", MDC_VENDOR_ID, jour_hostid); + sprintf (a, "%d,\"%s\"\201", MDC_VENDOR_ID, jour_hostid); goto exec; @@ -5483,7 +5583,7 @@ errexfun: case SVNtlevel: - snprintf (a, 255, "%d\201", tp_level); + sprintf (a, "%d\201", tp_level); goto exec; @@ -5496,7 +5596,7 @@ errexfun: case SVNecode: - //write_m ("in SVNecode\r\n\201"); + /* write_m ("in SVNecode\r\n\201"); */ if (stlen (user_ecode)) { stcpy (a, user_ecode); @@ -5511,7 +5611,7 @@ errexfun: case SVNestack: { char esbuf[256]; - snprintf (esbuf, 255, "%d\201", estack); + sprintf (esbuf, "%d\201", estack); stcpy (a, esbuf); goto exec; @@ -5520,7 +5620,7 @@ errexfun: case SVNetrap: -// write_m ("in SVNetrap\r\n\201"); +/* write_m ("in SVNetrap\r\n\201"); */ stcpy (a, etrap); goto exec; @@ -5544,17 +5644,17 @@ errexfun: /* $DEVICE */ case 'd': if (devstat[io].mdc_err == 0) { - snprintf (a, 3, "0\201\0"); + sprintf (a, "0\201\0"); } else { - snprintf (a, 120, "%d,%d,%s\201\0", devstat[io].mdc_err, devstat[io].frm_err, devstat[io].err_txt); + sprintf (a, "%d,%d,%s\201\0", devstat[io].mdc_err, devstat[io].frm_err, devstat[io].err_txt); } goto exec; /* $STORAGE */ case 's': - snprintf (a, 255 , "%ld\201", DEFPSIZE); + sprintf (a, "%ld\201", DEFPSIZE); goto exec; /* $WITH */ @@ -5604,15 +5704,15 @@ errexfun: goto exec; - ///* $ZX (number of columns) */ - //case 'X': - //intstr (a, n_columns); - // goto exec; - - ///* $ZY (number of rows) */ - //case 'Y': - //intstr (a, n_lines); - //goto exec; + /* $ZX (number of columns) */ + case 'X': + intstr (a, n_columns); + goto exec; + + /* $ZY (number of rows) */ + case 'Y': + intstr (a, n_lines); + goto exec; /* $ZERROR */ case 'E': @@ -5675,7 +5775,7 @@ errexfun: char zdf_key[50]; char fmt_string[128]; - snprintf (zdf_key, 49, "^$JOB\202%d\202ZDATE_FORMAT\201", pid); + snprintf (zdf_key, sizeof (zdf_key) - 1, "^$JOB\202%d\202ZDATE_FORMAT\201", pid); ssvn (get_sym, zdf_key, fmt_string); stcnv_c2m (fmt_string);