From 364bc1f31ca4fe79699642a27ba32adae21848f0 Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Fri, 25 Jul 2025 14:12:30 -0700 Subject: [PATCH 01/11] Removes StrNCpyFromLispToC(), renames StrNCpyFromCToLisp to MemCpyToLispFromNative Removes StrNCpyFromLispToC and the single use of it in LispStringToCString in the BYTESWAP implementation case. Rename StrNCpyFromCToLisp, which does NOT follow "strncpy" semantics, to be MemCpyToLispFromNative, where the types in the name match the types of the arguments, and the semantics (and argument order) are those of the C library "memcpy". --- inc/locfile.h | 29 +++++++++++++++-------------- src/dir.c | 4 ++-- src/dsk.c | 10 +++++----- src/osmsg.c | 2 +- src/ufs.c | 4 ++-- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/inc/locfile.h b/inc/locfile.h index 856c23d..da69505 100644 --- a/inc/locfile.h +++ b/inc/locfile.h @@ -44,18 +44,17 @@ /* For getfileinfo. For WDATE&RDATE */ /* 29969152 == (timer.c)LISP_UNIX_TIME_DIFF */ -#define StrNCpyFromCToLisp(lispbuf, cbuf ,len) do { \ - char *lf_sptr = (cbuf); \ - char *lf_dptr = (lispbuf); \ - for(size_t lf_i=0;lf_i<(len);lf_i++)\ - GETBYTE(lf_dptr++) = *lf_sptr++; \ - } while (0) - -#define StrNCpyFromLispToC(cbuf , lispbuf, len) do { \ - char *lf_sptr = (lispbuf); \ - char *lf_dptr = (cbuf); \ - for(size_t lf_i=0;lf_i<(len);lf_i++)\ - *lf_dptr++ = GETBYTE(lf_sptr++); \ +/* + * Copy memory between native memory locations accounting for potential + * byte-swapping necessary when then destination is within Lisp memory space + * though the provided destination pointer is a native address within the + * Lisp space. + */ + #define MemCpyToLispFromNative(lispbuf, cbuf, len) \ + do { \ + char *lf_sptr = (cbuf); \ + char *lf_dptr = (lispbuf); \ + for (size_t lf_i = 0; lf_i < (len); lf_i++) *BYTEPTR(lf_dptr++) = *lf_sptr++; \ } while (0) #define FGetNum(ptr, place) do { \ @@ -122,8 +121,10 @@ case THIN_CHAR_TYPENUMBER: \ lf_base = ((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) \ + ((int)(lf_arrayp->offset)); \ - StrNCpyFromLispToC(C , lf_base , lf_length ); \ - (C)[lf_length] = '\0'; \ + lf_dp = C; \ + for (size_t lf_i = 0; lf_i < lf_length; lf_i++) \ + *lf_dp++ = GETBYTE(lf_base++); \ + *lf_dp = '\0'; \ break; \ \ case FAT_CHAR_TYPENUMBER: \ diff --git a/src/dir.c b/src/dir.c index 5b31c4d..01f7b93 100644 --- a/src/dir.c +++ b/src/dir.c @@ -2159,7 +2159,7 @@ LispPTR COM_next_file(LispPTR *args) #ifndef BYTESWAP strncpy(base, fp->lname, fp->lname_len); #else - StrNCpyFromCToLisp(base, fp->lname, fp->lname_len); + MemCpyToLispFromNative(base, fp->lname, fp->lname_len); #endif /* BYTESWAP */ if (!propp) return (GetPosSmallp(fp->lname_len)); @@ -2175,7 +2175,7 @@ LispPTR COM_next_file(LispPTR *args) #ifndef BYTESWAP strncpy(base, pp->author, pp->au_len); #else - StrNCpyFromCToLisp(base, pp->author, pp->au_len); + MemCpyToLispFromNative(base, pp->author, pp->au_len); #endif /* BYTESWAP */ gfsp->aulen = pp->au_len; diff --git a/src/dsk.c b/src/dsk.c index a96a0f4..59983b9 100644 --- a/src/dsk.c +++ b/src/dsk.c @@ -1034,7 +1034,7 @@ LispPTR DSK_getfilename(LispPTR *args) #ifndef BYTESWAP strncpy(base, lfname, len + 1); #else - StrNCpyFromCToLisp(base, lfname, len + 1); + MemCpyToLispFromNative(base, lfname, len + 1); #endif /* BYTESWAP */ return (GetPosSmallp(len)); @@ -1070,7 +1070,7 @@ LispPTR DSK_getfilename(LispPTR *args) #ifndef BYTESWAP strncpy(base, lfname, len + 1); #else - StrNCpyFromCToLisp(base, lfname, len + 1); + MemCpyToLispFromNative(base, lfname, len + 1); #endif /* BYTESWAP */ return (GetPosSmallp(len)); @@ -1509,7 +1509,7 @@ LispPTR DSK_directorynamep(LispPTR *args) #ifndef BYTESWAP strncpy(base, dirname, len + 1); #else - StrNCpyFromCToLisp(base, dirname, len + 1); + MemCpyToLispFromNative(base, dirname, len + 1); #endif /* BYTESWAP */ return (GetPosSmallp(len)); @@ -1671,7 +1671,7 @@ LispPTR COM_getfileinfo(LispPTR *args) #ifndef BYTESWAP strncpy(base, pwd->pw_name, len); #else - StrNCpyFromCToLisp(base, pwd->pw_name, len); + MemCpyToLispFromNative(base, pwd->pw_name, len); #endif /* BYTESWAP */ #endif /* DOS */ return (GetPosSmallp(len)); @@ -1710,7 +1710,7 @@ LispPTR COM_getfileinfo(LispPTR *args) #ifndef BYTESWAP strncpy(base, pwd->pw_name, len); #else - StrNCpyFromCToLisp(base, pwd->pw_name, len); + MemCpyToLispFromNative(base, pwd->pw_name, len); #endif /* BYTESWAP */ #endif /* DOS */ return (GetPosSmallp(len)); diff --git a/src/osmsg.c b/src/osmsg.c index 6c0b748..929b95f 100644 --- a/src/osmsg.c +++ b/src/osmsg.c @@ -283,7 +283,7 @@ LispPTR mess_read(LispPTR *args) if (temp_buf[i] == '\n') temp_buf[i] = '\000'; } /* COPY actual Lisp Buffer(for BYTESWAP magic) */ - StrNCpyFromCToLisp(base, temp_buf, size); + MemCpyToLispFromNative(base, temp_buf, size); return (GetSmallp(size)); #else diff --git a/src/ufs.c b/src/ufs.c index b5173cd..cb62990 100644 --- a/src/ufs.c +++ b/src/ufs.c @@ -218,7 +218,7 @@ LispPTR UFS_getfilename(LispPTR *args) #ifndef BYTESWAP strncpy(base, lfname, len + 1); #else - StrNCpyFromCToLisp(base, lfname, len + 1); + MemCpyToLispFromNative(base, lfname, len + 1); #endif /* BYTESWAP */ return (GetSmallp(len)); @@ -422,7 +422,7 @@ LispPTR UFS_directorynamep(LispPTR *args) #ifndef BYTESWAP strncpy(base, dirname, len + 1); #else - StrNCpyFromCToLisp(base, dirname, len + 1); + MemCpyToLispFromNative(base, dirname, len + 1); #endif /* BYTESWAP */ return (GetSmallp(len)); From a0e703678cf0b761622be3f3ae7a63bf0516c4a3 Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Fri, 25 Jul 2025 17:52:34 -0700 Subject: [PATCH 02/11] Replaces (expanded) lisp string base access pattern with STRING_BASE macro --- src/osmsg.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/osmsg.c b/src/osmsg.c index 929b95f..6644d5a 100644 --- a/src/osmsg.c +++ b/src/osmsg.c @@ -233,15 +233,13 @@ LispPTR mess_read(LispPTR *args) struct stat sbuf; int size, save_size; char *base; - LispPTR *naddress; int i; static char temp_buf[MESSAGE_BUFFER_SIZE]; SETJMP(NIL); /* Get buff address from LISP */ - naddress = (LispPTR *)(NativeAligned4FromLAddr(args[0])); - base = (char *)(NativeAligned2FromLAddr(((OneDArray *)naddress)->base)); + STRING_BASE(args[0], base); close(log_id); TIMEOUT(log_id = open(logfile, O_RDONLY)); From 5343b12991658dbfb354044bcadcd62e54792590 Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Fri, 25 Jul 2025 18:39:53 -0700 Subject: [PATCH 03/11] Eliminates nul at end of Lisp string since Lisp strings are not nul terminated --- src/dsk.c | 12 ++++++------ src/ufs.c | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dsk.c b/src/dsk.c index 59983b9..b9d3e79 100644 --- a/src/dsk.c +++ b/src/dsk.c @@ -1032,9 +1032,9 @@ LispPTR DSK_getfilename(LispPTR *args) len = strlen(lfname); #ifndef BYTESWAP - strncpy(base, lfname, len + 1); + strncpy(base, lfname, len); #else - MemCpyToLispFromNative(base, lfname, len + 1); + MemCpyToLispFromNative(base, lfname, len); #endif /* BYTESWAP */ return (GetPosSmallp(len)); @@ -1068,9 +1068,9 @@ LispPTR DSK_getfilename(LispPTR *args) len = strlen(lfname); #ifndef BYTESWAP - strncpy(base, lfname, len + 1); + strncpy(base, lfname, len); #else - MemCpyToLispFromNative(base, lfname, len + 1); + MemCpyToLispFromNative(base, lfname, len); #endif /* BYTESWAP */ return (GetPosSmallp(len)); @@ -1507,9 +1507,9 @@ LispPTR DSK_directorynamep(LispPTR *args) STRING_BASE(args[1], base); #ifndef BYTESWAP - strncpy(base, dirname, len + 1); + strncpy(base, dirname, len); #else - MemCpyToLispFromNative(base, dirname, len + 1); + MemCpyToLispFromNative(base, dirname, len); #endif /* BYTESWAP */ return (GetPosSmallp(len)); diff --git a/src/ufs.c b/src/ufs.c index cb62990..802f5ee 100644 --- a/src/ufs.c +++ b/src/ufs.c @@ -216,9 +216,9 @@ LispPTR UFS_getfilename(LispPTR *args) len = strlen(lfname); #ifndef BYTESWAP - strncpy(base, lfname, len + 1); + strncpy(base, lfname, len); #else - MemCpyToLispFromNative(base, lfname, len + 1); + MemCpyToLispFromNative(base, lfname, len); #endif /* BYTESWAP */ return (GetSmallp(len)); @@ -420,9 +420,9 @@ LispPTR UFS_directorynamep(LispPTR *args) STRING_BASE(args[1], base); #ifndef BYTESWAP - strncpy(base, dirname, len + 1); + strncpy(base, dirname, len); #else - MemCpyToLispFromNative(base, dirname, len + 1); + MemCpyToLispFromNative(base, dirname, len); #endif /* BYTESWAP */ return (GetSmallp(len)); From fe8c991a112bf4ff83815ec1987fe6b91d6e5089 Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Sat, 26 Jul 2025 11:33:14 -0700 Subject: [PATCH 04/11] Fixes possible buffer overrun when source string too long If the Lisp string passed to LispStringToCString were longer than the destination buffer's MaxLen the could would have written the terminating nul past the end of the array. Fixes formatting of LispStringToCString Corrects English grammar in some comments. --- inc/locfile.h | 122 +++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 66 deletions(-) diff --git a/inc/locfile.h b/inc/locfile.h index da69505..7587aa1 100644 --- a/inc/locfile.h +++ b/inc/locfile.h @@ -78,66 +78,57 @@ /* */ /************************************************************************/ #ifndef BYTESWAP -#define LispStringToCString(Lisp, C, MaxLen) \ - do { \ - OneDArray *lf_arrayp; \ - char *lf_base, *lf_dp; \ - short *lf_sbase; \ - size_t lf_length; \ - lf_arrayp = (OneDArray *)NativeAligned4FromLAddr(Lisp); \ - lf_length = min(MaxLen, lf_arrayp->fillpointer); \ - switch(lf_arrayp->typenumber) \ - { \ - case THIN_CHAR_TYPENUMBER: \ - lf_base = ((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) \ - + ((int)(lf_arrayp->offset)); \ - strncpy(C, lf_base, lf_length); \ - (C)[lf_length] = '\0'; \ - break; \ - \ - case FAT_CHAR_TYPENUMBER: \ - lf_sbase = ((short *)(NativeAligned2FromLAddr(lf_arrayp->base))) \ - + ((int)(lf_arrayp->offset)); \ - lf_dp = C; \ - for(size_t lf_i=0;lf_i<(lf_length);lf_i++) \ - *lf_dp++ = (char)(*lf_sbase++); \ - *lf_dp = '\0'; \ - break; \ - default: \ - error("LispStringToCString: Not a character array.\n"); \ - } \ - } while (0) +#define LispStringToCString(Lisp, C, MaxLen) \ + do { \ + OneDArray *lf_arrayp; \ + char *lf_base, *lf_dp; \ + short *lf_sbase; \ + size_t lf_length; \ + lf_arrayp = (OneDArray *)NativeAligned4FromLAddr(Lisp); \ + lf_length = min(MaxLen - 1, lf_arrayp->fillpointer); \ + lf_dp = (C); \ + switch (lf_arrayp->typenumber) { \ + case THIN_CHAR_TYPENUMBER: \ + lf_base = \ + ((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); \ + strncpy(lf_dp, lf_base, lf_length); \ + lf_dp[lf_length] = '\0'; \ + break; \ + \ + case FAT_CHAR_TYPENUMBER: \ + lf_sbase = \ + ((short *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); \ + for (size_t lf_i = 0; lf_i < (lf_length); lf_i++) *lf_dp++ = (char)(*lf_sbase++); \ + *lf_dp = '\0'; \ + break; \ + default: error("LispStringToCString: Not a character array.\n"); \ + } \ + } while (0) #else /* BYTESWAP == T CHANGED-BY-TAKE */ -#define LispStringToCString(Lisp, C, MaxLen) \ - do { \ - OneDArray *lf_arrayp; \ - char *lf_base, *lf_dp; \ - short *lf_sbase; \ - size_t lf_length; \ - lf_arrayp = (OneDArray *)(NativeAligned4FromLAddr(Lisp)); \ - lf_length = min(MaxLen, lf_arrayp->fillpointer); \ - switch(lf_arrayp->typenumber) \ - { \ - case THIN_CHAR_TYPENUMBER: \ - lf_base = ((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) \ - + ((int)(lf_arrayp->offset)); \ - lf_dp = C; \ - for (size_t lf_i = 0; lf_i < lf_length; lf_i++) \ - *lf_dp++ = GETBYTE(lf_base++); \ - *lf_dp = '\0'; \ - break; \ - \ - case FAT_CHAR_TYPENUMBER: \ - lf_sbase = ((short *)(NativeAligned2FromLAddr(lf_arrayp->base))) \ - + ((int)(lf_arrayp->offset)); \ - lf_dp = C; \ - for(size_t lf_ii=0;lf_ii<(lf_length);lf_ii++,lf_sbase++) \ - *lf_dp++ = (char)(GETWORD(lf_sbase)); \ - *lf_dp = '\0'; \ - break; \ - default: \ - error("LispStringToCString: Not a character array.\n"); \ - } \ +#define LispStringToCString(Lisp, C, MaxLen) \ + do { \ + OneDArray *lf_arrayp; \ + char *lf_base, *lf_dp; \ + short *lf_sbase; \ + size_t lf_length; \ + lf_arrayp = (OneDArray *)(NativeAligned4FromLAddr(Lisp)); \ + lf_length = min(MaxLen - 1, lf_arrayp->fillpointer); \ + lf_dp = (C); \ + switch (lf_arrayp->typenumber) { \ + case THIN_CHAR_TYPENUMBER: \ + lf_base = \ + ((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); \ + for (size_t lf_i = 0; lf_i < lf_length; lf_i++) *lf_dp++ = GETBYTE(lf_base++); \ + break; \ + \ + case FAT_CHAR_TYPENUMBER: \ + lf_sbase = \ + ((short *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); \ + for (size_t lf_ii = 0; lf_ii < lf_length; lf_ii++) *lf_dp++ = (char)(GETWORD(lf_sbase++)); \ + break; \ + default: error("LispStringToCString: Not a character array.\n"); \ + } \ + *lf_dp = '\0'; \ } while (0) #endif /* BYTESWAP */ @@ -300,7 +291,7 @@ do { \ * Argument: char *pathname * Xerox Lisp syntax pathname. * - * Value: If succeed, returns 1, otherwise 0. + * Value: On success returns 1, otherwise 0. * * Side Effect: The version part of pathname is destructively modified. * @@ -313,7 +304,7 @@ do { \ * code. * This macro should be called at the top of the routines which accept the * file name from lisp before converting it into UNIX file name, because - * locating the version part, the informations about quoted characters are needed. + * locating the version part, the information about quoted characters are needed. * They might be lost in the course of the conversion. * */ @@ -338,19 +329,18 @@ do { \ * If 0, versionless file is converted to version 1. * Otherwise, remains as versionless. * - * Value: If succeed, returns 1, otherwise 0. + * Value: On success returns 1, otherwise 0. * * Side Effect: The version part of pathname is destructively modified. * * Description: * - * Destructively modify the version part of pathname which is following the + * Destructively modifies the version part of pathname which is following the * UNIX file naming convention to Xerox Lisp one. * This macro should be called, in the routines which convert the UNIX pathname * to Lisp one, just before it returns the result to Lisp, because converting - * version field will append a semicolon and it might make the routine be - * confused. - * The file which has not a valid version field, that is ".~##~" form, is + * version field will append a semicolon which may confuse the routine + * The file which does not have a valid version field, that is ".~##~" form, is * dealt with as version 1. */ From afe40004b8161c6553f9542a50898d5f693c215b Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Sat, 26 Jul 2025 17:43:14 -0700 Subject: [PATCH 05/11] Removes unnecessary dependency on lisp2c from kbdsubrs.c --- bin/makefile-tail | 2 +- src/kbdsubrs.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/makefile-tail b/bin/makefile-tail index d6277f7..ee098bb 100644 --- a/bin/makefile-tail +++ b/bin/makefile-tail @@ -674,7 +674,7 @@ $(OBJECTDIR)initsout.o: $(SRCDIR)initsout.c $(REQUIRED-INCS) \ $(OBJECTDIR)kbdsubrs.o: $(SRCDIR)kbdsubrs.c $(REQUIRED-INCS) \ $(INCDIR)lispemul.h $(INCDIR)kbdsubrsdefs.h \ - $(INCDIR)commondefs.h $(INCDIR)lisp2cdefs.h $(INCDIR)xwinmandefs.h \ + $(INCDIR)commondefs.h $(INCDIR)xwinmandefs.h \ $(INCDIR)devif.h $(CC) $(RFLAGS) $(SRCDIR)kbdsubrs.c -o $(OBJECTDIR)kbdsubrs.o diff --git a/src/kbdsubrs.c b/src/kbdsubrs.c index 7175431..3bb9a8c 100644 --- a/src/kbdsubrs.c +++ b/src/kbdsubrs.c @@ -28,7 +28,6 @@ #include "kbdsubrsdefs.h" #include "commondefs.h" #ifdef XWINDOW -#include "lisp2cdefs.h" #include "xwinmandefs.h" #endif From cfbd78007a295dd9117013d4f7c633b0a6057a1e Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Sat, 26 Jul 2025 17:46:13 -0700 Subject: [PATCH 06/11] Replaces #defined LispStringToCString with static procedure, reformats code --- inc/locfile.h | 105 ++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 55 deletions(-) diff --git a/inc/locfile.h b/inc/locfile.h index 7587aa1..706962a 100644 --- a/inc/locfile.h +++ b/inc/locfile.h @@ -12,6 +12,7 @@ #include /* for NAME_MAX */ #include /* for MAXNAMLEN */ #include "lispemul.h" /* for DLword */ +#include "commondefs.h" /* for error */ #define FDEV_PAGE_SIZE 512 /* 1 page == 512 byte */ @@ -63,6 +64,10 @@ else {return(NIL);}} while (0) +#ifndef min +#define min(a, b) (((a) <= (b))?(a):(b)) +#endif /* min */ + /************************************************************************/ /* */ /* L i s p S t r i n g T o C S t r i n g */ @@ -78,58 +83,52 @@ /* */ /************************************************************************/ #ifndef BYTESWAP -#define LispStringToCString(Lisp, C, MaxLen) \ - do { \ - OneDArray *lf_arrayp; \ - char *lf_base, *lf_dp; \ - short *lf_sbase; \ - size_t lf_length; \ - lf_arrayp = (OneDArray *)NativeAligned4FromLAddr(Lisp); \ - lf_length = min(MaxLen - 1, lf_arrayp->fillpointer); \ - lf_dp = (C); \ - switch (lf_arrayp->typenumber) { \ - case THIN_CHAR_TYPENUMBER: \ - lf_base = \ - ((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); \ - strncpy(lf_dp, lf_base, lf_length); \ - lf_dp[lf_length] = '\0'; \ - break; \ - \ - case FAT_CHAR_TYPENUMBER: \ - lf_sbase = \ - ((short *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); \ - for (size_t lf_i = 0; lf_i < (lf_length); lf_i++) *lf_dp++ = (char)(*lf_sbase++); \ - *lf_dp = '\0'; \ - break; \ - default: error("LispStringToCString: Not a character array.\n"); \ - } \ - } while (0) +static void LispStringToCString(LispPTR Lisp, char *C, size_t MaxLen) { + OneDArray *lf_arrayp; + char *lf_base, *lf_dp; + short *lf_sbase; + size_t lf_length; + lf_arrayp = (OneDArray *)NativeAligned4FromLAddr(Lisp); + lf_length = min(MaxLen - 1, lf_arrayp->fillpointer); + lf_dp = (C); + switch (lf_arrayp->typenumber) { + case THIN_CHAR_TYPENUMBER: + lf_base = ((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); + strncpy(lf_dp, lf_base, lf_length); + lf_dp[lf_length] = '\0'; + break; + + case FAT_CHAR_TYPENUMBER: + lf_sbase = ((short *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); + for (size_t lf_i = 0; lf_i < (lf_length); lf_i++) *lf_dp++ = (char)(*lf_sbase++); + *lf_dp = '\0'; + break; + default: error("LispStringToCString: Not a character array.\n"); + } +} #else /* BYTESWAP == T CHANGED-BY-TAKE */ -#define LispStringToCString(Lisp, C, MaxLen) \ - do { \ - OneDArray *lf_arrayp; \ - char *lf_base, *lf_dp; \ - short *lf_sbase; \ - size_t lf_length; \ - lf_arrayp = (OneDArray *)(NativeAligned4FromLAddr(Lisp)); \ - lf_length = min(MaxLen - 1, lf_arrayp->fillpointer); \ - lf_dp = (C); \ - switch (lf_arrayp->typenumber) { \ - case THIN_CHAR_TYPENUMBER: \ - lf_base = \ - ((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); \ - for (size_t lf_i = 0; lf_i < lf_length; lf_i++) *lf_dp++ = GETBYTE(lf_base++); \ - break; \ - \ - case FAT_CHAR_TYPENUMBER: \ - lf_sbase = \ - ((short *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); \ - for (size_t lf_ii = 0; lf_ii < lf_length; lf_ii++) *lf_dp++ = (char)(GETWORD(lf_sbase++)); \ - break; \ - default: error("LispStringToCString: Not a character array.\n"); \ - } \ - *lf_dp = '\0'; \ - } while (0) +static void LispStringToCString(LispPTR Lisp, char *C, size_t MaxLen) { + OneDArray *lf_arrayp; + char *lf_base, *lf_dp; + short *lf_sbase; + size_t lf_length; + lf_arrayp = (OneDArray *)(NativeAligned4FromLAddr(Lisp)); + lf_length = min(MaxLen - 1, lf_arrayp->fillpointer); + lf_dp = (C); + switch (lf_arrayp->typenumber) { + case THIN_CHAR_TYPENUMBER: + lf_base = ((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); + for (size_t lf_i = 0; lf_i < lf_length; lf_i++) *lf_dp++ = GETBYTE(lf_base++); + break; + + case FAT_CHAR_TYPENUMBER: + lf_sbase = ((short *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); + for (size_t lf_ii = 0; lf_ii < lf_length; lf_ii++) *lf_dp++ = (char)(GETWORD(lf_sbase++)); + break; + default: error("LispStringToCString: Not a character array.\n"); + } + *lf_dp = '\0'; +} #endif /* BYTESWAP */ @@ -181,10 +180,6 @@ do { \ (cstringp) = (char *)(NativeAligned2FromLAddr(((OneDArray *)lf_naddress)->base)); \ } while (0) -#ifndef min -#define min(a, b) (((a) <= (b))?(a):(b)) -#endif /* min */ - #define LispNumToCInt(Lisp) \ ( (((Lisp) & SEGMASK) == S_POSITIVE) ? ((Lisp) & 0xFFFF) : \ (((Lisp) & SEGMASK) == S_NEGATIVE) ? ((Lisp) | 0xFFFF0000) : \ From 78dfa9b243963e0706f72e21914e37c142cd53a5 Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Sat, 26 Jul 2025 17:47:24 -0700 Subject: [PATCH 07/11] Adds warning note to lisp2c.c LispStringToCStr regarding endianness sensitivity --- src/lisp2c.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lisp2c.c b/src/lisp2c.c index 44b3396..00513e8 100644 --- a/src/lisp2c.c +++ b/src/lisp2c.c @@ -38,6 +38,8 @@ int LispStringSimpleLength(LispPTR lispstring) { return (arrayp->fillpointer); } +/* XXX: this string conversion is NOT useable on byte-swapped (little-endian) machines + */ void LispStringToCStr(LispPTR lispstring, char *cstring) { OneDArray *arrayp; char *base; From c4752e6caab2f63ff1aa8fdb21a1cd6cc9b6cdb7 Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Sat, 26 Jul 2025 17:54:17 -0700 Subject: [PATCH 08/11] Makes vmemsave.c lispstringP implementation local and updates header file accordingly --- inc/vmemsavedefs.h | 3 +-- src/vmemsave.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/inc/vmemsavedefs.h b/inc/vmemsavedefs.h index 3b09540..b4dae60 100644 --- a/inc/vmemsavedefs.h +++ b/inc/vmemsavedefs.h @@ -1,7 +1,6 @@ #ifndef VMEMSAVEDEFS_H #define VMEMSAVEDEFS_H 1 -#include "lispemul.h" /* for LispPTR, DLword */ -int lispstringP(LispPTR Lisp); +#include "lispemul.h" /* for LispPTR */ LispPTR vmem_save(char *sysout_file_name); LispPTR vmem_save0(LispPTR *args); void lisp_finish(int exit_status); diff --git a/src/vmemsave.c b/src/vmemsave.c index e77af0f..3ef5fac 100644 --- a/src/vmemsave.c +++ b/src/vmemsave.c @@ -92,7 +92,7 @@ extern int please_fork; /* */ /************************************************************************/ -int lispstringP(LispPTR Lisp) +static int lispstringP(LispPTR Lisp) { switch (((OneDArray *)(NativeAligned4FromLAddr(Lisp)))->typenumber) { case THIN_CHAR_TYPENUMBER: From ce20b3520eb5d4aee7c52603cc3753cb501e55d7 Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Sat, 26 Jul 2025 22:09:14 -0700 Subject: [PATCH 09/11] Replaces magic number 2 with BYTESPER_DLWORD in calculation of buffer size. --- src/ether_nethub.c | 4 ++-- src/ether_sunos.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ether_nethub.c b/src/ether_nethub.c index df27eec..e9803e2 100644 --- a/src/ether_nethub.c +++ b/src/ether_nethub.c @@ -468,7 +468,7 @@ LispPTR ether_get(LispPTR args[]) log_debug(("ether_get() - begin\n")); target = (u_char *)NativeAligned2FromLAddr(args[1]); - maxByteCount = 2 * LispIntToCInt(args[0]); /* words to bytes */ + maxByteCount = BYTESPER_DLWORD * LispIntToCInt(args[0]); /* words to bytes */ log_debug((" target = %p maxBytecount: %d bytes\n", (void *)target, maxByteCount)); ether_buf = target; @@ -501,7 +501,7 @@ LispPTR ether_send(LispPTR args[]) log_debug(("ether_send() - begin\n")); u_char *source = (u_char *)NativeAligned2FromLAddr(args[1]); - int byteCount = 2 * LispIntToCInt(args[0]); /* words to bytes */ + int byteCount = BYTESPER_DLWORD * LispIntToCInt(args[0]); /* words to bytes */ log_debug((" source = %p , bytecount: %d bytes\n", (void *)source, byteCount)); diff --git a/src/ether_sunos.c b/src/ether_sunos.c index deb4afe..ba75cf1 100644 --- a/src/ether_sunos.c +++ b/src/ether_sunos.c @@ -366,7 +366,7 @@ LispPTR ether_get(LispPTR args[]) LispPTR MaxByteCount; sigset_t signals; - MaxByteCount = 2 * (0xFFFF & args[0]); /* words to bytes */ + MaxByteCount = BYTERSPER_DLWORD * (0xFFFF & args[0]); /* words to bytes */ DBPRINT(("Ether Get. ")); @@ -408,7 +408,7 @@ LispPTR ether_send(LispPTR args[]) LispPTR MaxByteCount; u_char *BufferAddr; /* buffer address pointer(in native address) */ - MaxByteCount = 2 * (0xFFFF & args[0]); /* words to bytes */ + MaxByteCount = BYTESPER_DLWORD * (0xFFFF & args[0]); /* words to bytes */ BufferAddr = (u_char *)NativeAligned2FromLAddr(args[1]); if (ether_fd > 0) { From 9960010129610dd44a6303e0001a87c508c5e569 Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Mon, 28 Jul 2025 16:09:10 -0700 Subject: [PATCH 10/11] Adds handling of strings with indirect headers for URaid object printing --- src/kprint.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/kprint.c b/src/kprint.c index 697c079..2865b4f 100644 --- a/src/kprint.c +++ b/src/kprint.c @@ -98,10 +98,12 @@ void prindatum(LispPTR x) { break; case TYPE_ONED_ARRAY: case TYPE_GENERAL_ARRAY: + /* this should probably use array.h's arrayheader */ newstring = (NEWSTRINGP *)NativeAligned4FromLAddr(x); if (newstring->stringp) { print_NEWstring(x); } + /* it would be useful to print non-string arrays, too */ break; default: dtd_base = (struct dtd *)GetDTD(typen); printf("{"); #ifdef BIGVM @@ -173,14 +175,20 @@ void print_string(LispPTR x) { void print_NEWstring(LispPTR x) { NEWSTRINGP *string_point; DLword st_length; + DLword st_offset; DLbyte *string_base; int i; string_point = (NEWSTRINGP *)NativeAligned4FromLAddr(x); st_length = string_point->fillpointer; + st_offset = string_point->offset; + if (string_point->indirectp) { + /* base points to another array header not the raw storage */ + string_point = (NEWSTRINGP *)NativeAligned4FromLAddr(string_point->base); + } string_base = (DLbyte *)NativeAligned2FromLAddr(string_point->base); - string_base += string_point->offset; + string_base += st_offset; printf("%c", DOUBLEQUOTE); /* print %" */ From c9e275966612d38f80ccdf644efb969267dc2277 Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Tue, 29 Jul 2025 19:59:03 -0700 Subject: [PATCH 11/11] Replaces magic number with value calculated from appropriate constant --- src/ldsout.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ldsout.c b/src/ldsout.c index 2db964d..0453e29 100644 --- a/src/ldsout.c +++ b/src/ldsout.c @@ -216,8 +216,8 @@ unsigned sysout_loader(const char *sysout_file_name, unsigned sys_size) { } if ((stat_buf.st_size & (BYTESPER_PAGE - 1)) != 0) - printf("CAUTION::not an integral number of pages. sysout & 0x1ff = 0x%x\n", - (int)(stat_buf.st_size & (BYTESPER_PAGE - 1))); + printf("CAUTION::not an integral number of pages. sysout & 0x%x = 0x%x\n", + BYTESPER_PAGE - 1, (int)(stat_buf.st_size & (BYTESPER_PAGE - 1))); if (ifpage.nactivepages != (sysout_size / 2)) { printf("sysout_loader:IFPAGE says sysout size is %d\n", ifpage.nactivepages);