1
0
mirror of https://github.com/Interlisp/maiko.git synced 2026-03-03 18:06:23 +00:00

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.
This commit is contained in:
Nick Briggs
2025-07-26 11:33:14 -07:00
parent 5343b12991
commit fe8c991a11

View File

@@ -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.
*/