Skip to content

Commit fe8c991

Browse files
committed
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.
1 parent 5343b12 commit fe8c991

File tree

1 file changed

+56
-66
lines changed

1 file changed

+56
-66
lines changed

inc/locfile.h

Lines changed: 56 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -78,66 +78,57 @@
7878
/* */
7979
/************************************************************************/
8080
#ifndef BYTESWAP
81-
#define LispStringToCString(Lisp, C, MaxLen) \
82-
do { \
83-
OneDArray *lf_arrayp; \
84-
char *lf_base, *lf_dp; \
85-
short *lf_sbase; \
86-
size_t lf_length; \
87-
lf_arrayp = (OneDArray *)NativeAligned4FromLAddr(Lisp); \
88-
lf_length = min(MaxLen, lf_arrayp->fillpointer); \
89-
switch(lf_arrayp->typenumber) \
90-
{ \
91-
case THIN_CHAR_TYPENUMBER: \
92-
lf_base = ((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) \
93-
+ ((int)(lf_arrayp->offset)); \
94-
strncpy(C, lf_base, lf_length); \
95-
(C)[lf_length] = '\0'; \
96-
break; \
97-
\
98-
case FAT_CHAR_TYPENUMBER: \
99-
lf_sbase = ((short *)(NativeAligned2FromLAddr(lf_arrayp->base))) \
100-
+ ((int)(lf_arrayp->offset)); \
101-
lf_dp = C; \
102-
for(size_t lf_i=0;lf_i<(lf_length);lf_i++) \
103-
*lf_dp++ = (char)(*lf_sbase++); \
104-
*lf_dp = '\0'; \
105-
break; \
106-
default: \
107-
error("LispStringToCString: Not a character array.\n"); \
108-
} \
109-
} while (0)
81+
#define LispStringToCString(Lisp, C, MaxLen) \
82+
do { \
83+
OneDArray *lf_arrayp; \
84+
char *lf_base, *lf_dp; \
85+
short *lf_sbase; \
86+
size_t lf_length; \
87+
lf_arrayp = (OneDArray *)NativeAligned4FromLAddr(Lisp); \
88+
lf_length = min(MaxLen - 1, lf_arrayp->fillpointer); \
89+
lf_dp = (C); \
90+
switch (lf_arrayp->typenumber) { \
91+
case THIN_CHAR_TYPENUMBER: \
92+
lf_base = \
93+
((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); \
94+
strncpy(lf_dp, lf_base, lf_length); \
95+
lf_dp[lf_length] = '\0'; \
96+
break; \
97+
\
98+
case FAT_CHAR_TYPENUMBER: \
99+
lf_sbase = \
100+
((short *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); \
101+
for (size_t lf_i = 0; lf_i < (lf_length); lf_i++) *lf_dp++ = (char)(*lf_sbase++); \
102+
*lf_dp = '\0'; \
103+
break; \
104+
default: error("LispStringToCString: Not a character array.\n"); \
105+
} \
106+
} while (0)
110107
#else /* BYTESWAP == T CHANGED-BY-TAKE */
111-
#define LispStringToCString(Lisp, C, MaxLen) \
112-
do { \
113-
OneDArray *lf_arrayp; \
114-
char *lf_base, *lf_dp; \
115-
short *lf_sbase; \
116-
size_t lf_length; \
117-
lf_arrayp = (OneDArray *)(NativeAligned4FromLAddr(Lisp)); \
118-
lf_length = min(MaxLen, lf_arrayp->fillpointer); \
119-
switch(lf_arrayp->typenumber) \
120-
{ \
121-
case THIN_CHAR_TYPENUMBER: \
122-
lf_base = ((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) \
123-
+ ((int)(lf_arrayp->offset)); \
124-
lf_dp = C; \
125-
for (size_t lf_i = 0; lf_i < lf_length; lf_i++) \
126-
*lf_dp++ = GETBYTE(lf_base++); \
127-
*lf_dp = '\0'; \
128-
break; \
129-
\
130-
case FAT_CHAR_TYPENUMBER: \
131-
lf_sbase = ((short *)(NativeAligned2FromLAddr(lf_arrayp->base))) \
132-
+ ((int)(lf_arrayp->offset)); \
133-
lf_dp = C; \
134-
for(size_t lf_ii=0;lf_ii<(lf_length);lf_ii++,lf_sbase++) \
135-
*lf_dp++ = (char)(GETWORD(lf_sbase)); \
136-
*lf_dp = '\0'; \
137-
break; \
138-
default: \
139-
error("LispStringToCString: Not a character array.\n"); \
140-
} \
108+
#define LispStringToCString(Lisp, C, MaxLen) \
109+
do { \
110+
OneDArray *lf_arrayp; \
111+
char *lf_base, *lf_dp; \
112+
short *lf_sbase; \
113+
size_t lf_length; \
114+
lf_arrayp = (OneDArray *)(NativeAligned4FromLAddr(Lisp)); \
115+
lf_length = min(MaxLen - 1, lf_arrayp->fillpointer); \
116+
lf_dp = (C); \
117+
switch (lf_arrayp->typenumber) { \
118+
case THIN_CHAR_TYPENUMBER: \
119+
lf_base = \
120+
((char *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); \
121+
for (size_t lf_i = 0; lf_i < lf_length; lf_i++) *lf_dp++ = GETBYTE(lf_base++); \
122+
break; \
123+
\
124+
case FAT_CHAR_TYPENUMBER: \
125+
lf_sbase = \
126+
((short *)(NativeAligned2FromLAddr(lf_arrayp->base))) + ((int)(lf_arrayp->offset)); \
127+
for (size_t lf_ii = 0; lf_ii < lf_length; lf_ii++) *lf_dp++ = (char)(GETWORD(lf_sbase++)); \
128+
break; \
129+
default: error("LispStringToCString: Not a character array.\n"); \
130+
} \
131+
*lf_dp = '\0'; \
141132
} while (0)
142133

143134
#endif /* BYTESWAP */
@@ -300,7 +291,7 @@ do { \
300291
* Argument: char *pathname
301292
* Xerox Lisp syntax pathname.
302293
*
303-
* Value: If succeed, returns 1, otherwise 0.
294+
* Value: On success returns 1, otherwise 0.
304295
*
305296
* Side Effect: The version part of pathname is destructively modified.
306297
*
@@ -313,7 +304,7 @@ do { \
313304
* code.
314305
* This macro should be called at the top of the routines which accept the
315306
* file name from lisp before converting it into UNIX file name, because
316-
* locating the version part, the informations about quoted characters are needed.
307+
* locating the version part, the information about quoted characters are needed.
317308
* They might be lost in the course of the conversion.
318309
*
319310
*/
@@ -338,19 +329,18 @@ do { \
338329
* If 0, versionless file is converted to version 1.
339330
* Otherwise, remains as versionless.
340331
*
341-
* Value: If succeed, returns 1, otherwise 0.
332+
* Value: On success returns 1, otherwise 0.
342333
*
343334
* Side Effect: The version part of pathname is destructively modified.
344335
*
345336
* Description:
346337
*
347-
* Destructively modify the version part of pathname which is following the
338+
* Destructively modifies the version part of pathname which is following the
348339
* UNIX file naming convention to Xerox Lisp one.
349340
* This macro should be called, in the routines which convert the UNIX pathname
350341
* to Lisp one, just before it returns the result to Lisp, because converting
351-
* version field will append a semicolon and it might make the routine be
352-
* confused.
353-
* The file which has not a valid version field, that is ".~##~" form, is
342+
* version field will append a semicolon which may confuse the routine
343+
* The file which does not have a valid version field, that is ".~##~" form, is
354344
* dealt with as version 1.
355345
*/
356346

0 commit comments

Comments
 (0)