Annotation of freem/src/mref.c, revision 1.7

1.1       snw         1: /*
1.7     ! snw         2:  *   $Id: mref.c,v 1.6 2025/04/09 15:16:50 snw Exp $
1.1       snw         3:  *    supporting functions for handling freem_ref_t structures
                      4:  *
                      5:  *  
1.3       snw         6:  *   Author: Serena Willis <snw@coherent-logic.com>
1.1       snw         7:  *    Copyright (C) 1998 MUG Deutschland
1.4       snw         8:  *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
1.1       snw         9:  *
                     10:  *
                     11:  *   This file is part of FreeM.
                     12:  *
                     13:  *   FreeM is free software: you can redistribute it and/or modify
                     14:  *   it under the terms of the GNU Affero Public License as published by
                     15:  *   the Free Software Foundation, either version 3 of the License, or
                     16:  *   (at your option) any later version.
                     17:  *
                     18:  *   FreeM is distributed in the hope that it will be useful,
                     19:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
                     20:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     21:  *   GNU Affero Public License for more details.
                     22:  *
                     23:  *   You should have received a copy of the GNU Affero Public License
                     24:  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
                     25:  *
1.5       snw        26:  *   $Log: mref.c,v $
1.7     ! snw        27:  *   Revision 1.6  2025/04/09 15:16:50  snw
        !            28:  *   Fix buffer overruns in mref_to_external and ssvn.c
        !            29:  *
1.6       snw        30:  *   Revision 1.5  2025/03/22 18:43:54  snw
                     31:  *   Make STRLEN 255 chars and add BIGSTR macro for larger buffers
                     32:  *
1.5       snw        33:  *   Revision 1.4  2025/03/09 19:50:47  snw
                     34:  *   Second phase of REUSE compliance and header reformat
                     35:  *
1.4       snw        36:  *
                     37:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
                     38:  * SPDX-License-Identifier: AGPL-3.0-or-later
1.1       snw        39:  **/
                     40: 
                     41: #include <stdio.h>
                     42: #include <stdlib.h>
                     43: #include <string.h>
                     44: #include <mpsdef0.h>
                     45: 
                     46: #include "freem.h"
                     47: 
                     48: #define MREF_CHECK(ref,index,type) if (ref->status != MREF_ST_INIT || index > 255 || index < 0) return (type) NULL
1.2       snw        49: #define MREF_CHECK_EXIT(ref,index,type) if (ref->status != MREF_ST_INIT || index > 255 || index < 0) exit (type) NULL
1.1       snw        50: 
                     51: extern short g_numeric (char *str);
                     52: 
                     53: freem_ref_t *mref_init (freem_ref_t *ref, short ref_type, char *name) 
                     54: {
                     55:     if (strlen (name) > 255) {
                     56:         ref->status = MREF_ST_ERR;
                     57:         return ref;
                     58:     }
                     59: 
                     60:     ref->reftype = ref_type;
                     61:     ref->status = MREF_ST_INIT;
                     62:     strncpy (ref->name, name, 255);
                     63:     ref->subscript_count = 0;
                     64: 
                     65:     return ref;
                     66: }
                     67: 
                     68: char *mref_get_name (freem_ref_t *ref)
                     69: {
                     70:     MREF_CHECK (ref, 0, char *);
                     71: 
                     72:     return ref->name;
                     73: }
                     74: 
                     75: char *mref_get_subscript (freem_ref_t *ref, int index)
                     76: {
                     77:     /* ref must be initialized, and index within range */
                     78:     MREF_CHECK (ref, index, char *);
                     79:     
                     80:     return ref->subscripts[index];
                     81: }
                     82: 
                     83: freem_ref_t *mref_set_subscript (freem_ref_t *ref, int index, char *value)
                     84: {
                     85:     MREF_CHECK (ref, index, freem_ref_t *);
                     86: 
                     87:     if (ref->subscript_count == 0 && index == 0) ref->subscript_count = 1;
                     88: 
                     89:     if (ref->subscript_count < (index + 1)) {
                     90:         ref->subscript_count = index + 1;
                     91:     }
                     92: 
                     93:     strncpy (ref->subscripts[index], value, 255);
                     94: 
                     95:     return ref;
                     96: }
                     97: 
                     98: void mref_to_internal_prealloc (char *res, freem_ref_t *ref)
                     99: {
                    100:     register int i;
                    101: 
1.2       snw       102: /*    MREF_CHECK (ref, 0, char *); */
1.1       snw       103: 
                    104:     strncpy (res, ref->name, STRLEN - 1);
                    105:     
                    106:     for (i = 0; i < ref->subscript_count; i++) {
                    107:         strncat (res, "\202", STRLEN - 1);
                    108:         strncat (res, ref->subscripts[i], STRLEN - 1);
                    109:     }
                    110: 
                    111:     strncat (res, "\201", STRLEN - 1);
                    112:     stcnv_c2m (res);   
                    113: 
                    114: }
                    115: 
                    116: char *mref_to_internal (freem_ref_t *ref)
                    117: {
                    118: 
                    119:     char *tmp = (char *) malloc (STRLEN * sizeof(char));
                    120:     register int i;
                    121: 
                    122:     MREF_CHECK (ref, 0, char *);
                    123: 
                    124:     strncpy (tmp, ref->name, STRLEN - 1);
                    125:     
                    126:     for (i = 0; i < ref->subscript_count; i++) {
                    127:         strncat (tmp, "\202", STRLEN - 1);
                    128:         strncat (tmp, ref->subscripts[i], STRLEN - 1);
                    129:     }
                    130: 
                    131:     strncat (tmp, "\201", STRLEN - 1);
                    132:     stcnv_c2m (tmp);
                    133: 
                    134:     return tmp;
                    135: }
                    136: 
                    137: /* convert a DELIM-delimited, EOL-terminated key to a freem_ref_t* */
                    138: freem_ref_t *internal_to_mref (freem_ref_t *ref, char *key)
                    139: {
                    140:     register int i;
                    141:     register int j;
                    142:     char *ptr = key;
                    143:     char ch;
                    144:     char *nam = (char *) malloc (STRLEN * sizeof(char));
                    145:     char *tmp = (char *) malloc (STRLEN * sizeof(char));
                    146: 
                    147:     MREF_CHECK (ref, 0, freem_ref_t *);
                    148: 
                    149:     /* shunt the name into ref->name */
                    150:     i = 0;
                    151:     while ((ch = *(ptr++)) != DELIM && ch != EOL) {
                    152:         nam[i++] = ch;
                    153:     }
                    154: 
                    155:     nam[i] = '\0';
                    156: 
                    157:     if (nam[0] == '^') {
                    158:         
                    159:         if (nam[1] == '$') {
                    160:             ref->reftype = MREF_RT_SSVN;
                    161:         }
                    162:         else {
                    163:             ref->reftype = MREF_RT_GLOBAL;
                    164:         }
                    165: 
                    166:     }
                    167:     else {
                    168:         ref->reftype = MREF_RT_LOCAL;
                    169:     }
                    170: 
1.5       snw       171:     strncpy (ref->name, nam, STRLEN);
1.1       snw       172: 
                    173:     /* if no subscripts, return the ref */
                    174:     if (*(ptr - 1) == EOL) {
                    175:         ref->subscript_count = 0;
                    176: 
                    177:         free (nam);
                    178:         free (tmp);
                    179: 
                    180:         return ref;
                    181:     }
                    182: 
                    183: 
                    184:     /* grab the subscripts */
                    185:     i = 0;
                    186:     j = 0;
                    187:     while ((ch = *(ptr++)) != EOL) {
                    188: 
                    189:         switch (ch) {
                    190: 
                    191:             case '\001':                
                    192:                 break;
                    193:             case DELIM:
                    194:                 
                    195:                 tmp[j] = '\0';
                    196: 
                    197:                 mref_set_subscript (ref, i++, tmp);
                    198:                 ref->subscript_count++;
                    199:                 
                    200:                 j = 0;
                    201:                 tmp[j] = '\0';
                    202:                 
                    203:                 break;
                    204: 
                    205: 
                    206:             default:
                    207:                 tmp[j++] = ch;
                    208: 
                    209:         }
                    210: 
                    211:     }
                    212: 
                    213:     tmp[j] = '\0';
                    214: 
                    215:     /* grab the last one */
                    216:     mref_set_subscript (ref, i, tmp);
                    217:     
                    218:     free (nam);
                    219:     free (tmp);
                    220: 
                    221:     return ref;
                    222: 
                    223: }
                    224: 
                    225: void mref_to_external (freem_ref_t *ref, char *buf)
                    226: {
                    227:     register int i;
                    228:     register int j;
                    229:     short is_numeric = FALSE;
                    230:     short is_ref = FALSE;
                    231:     char *t_buf = (char *) malloc (STRLEN * sizeof (char));
                    232:     NULLPTRCHK(t_buf,"mref_to_external");
                    233:     
                    234:     strcpy (buf, ref->name);
                    235: 
                    236:     if (ref->subscript_count) {
                    237: 
                    238:         strcat (buf, "(");  
                    239: 
                    240: 
                    241:         for (i = 0; i < ref->subscript_count; i++) {
                    242: 
                    243:             if (ref->subscripts[i][0] == '.') {
                    244:                 is_ref = TRUE;
                    245:             }
                    246:             else {
                    247:                 is_ref = FALSE;
                    248:             }
                    249: 
                    250:             strcpy (t_buf, ref->subscripts[i]);
                    251: 
                    252:             for (j = 0; j < strlen (t_buf); j++) {
                    253:                 if (t_buf[j] == '\001') t_buf[j] = '\201';
                    254:             }
                    255: 
                    256:             stcnv_c2m (t_buf);
                    257: 
                    258:             is_numeric = numeric (t_buf);
                    259: 
                    260:             
                    261:             if (!is_numeric && !is_ref) strcat (buf, "\"");
                    262: 
                    263:             for (j = 0; j < strlen (ref->subscripts[i]); j++) {
                    264:                 if (ref->subscripts[i][j] == '\001') ref->subscripts[i][j] = '\201';
                    265:             }
                    266:             strcat (buf, ref->subscripts[i]);
                    267:             if (!is_numeric && !is_ref) strcat (buf, "\"");
                    268: 
                    269:             if (i < (ref->subscript_count - 1)) {
                    270:                 strcat (buf, ",");
                    271:             }
                    272: 
                    273:         }
1.6       snw       274:         stncnv_m2c (buf, STRLEN);
1.1       snw       275: 
                    276:         strcat (buf, ")");
                    277: 
                    278:     }
                    279: 
                    280:     free (t_buf);
                    281:     return;
                    282:     
                    283: }
                    284: 
                    285: /* returns TRUE if b is a descendant of a */
                    286: short mref_is_descendant(freem_ref_t *a, freem_ref_t *b)
                    287: {    
                    288:     register int i;
                    289: 
                    290:     if (a->subscript_count > b->subscript_count) return FALSE;
                    291:     if ((strcmp (a->name, b->name) == 0) && (a->subscript_count == 0)) return TRUE;
                    292:     
                    293:     
                    294:     for (i = 0; i < a->subscript_count; i++) {
1.7     ! snw       295:         if (strcmp (b->subscripts[i], a->subscripts[i]) != 0 ) {
1.1       snw       296: 
                    297:             return FALSE;
                    298:         }
                    299:     }
                    300:     
                    301:     return TRUE;    
                    302: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>