Skip to content

Commit

Permalink
Fix handling of overlapping strncpy() in QVMs
Browse files Browse the repository at this point in the history
macOS (targeting newer SDKs) and glibc 2.37 changes broke overlapping
strncpy() used by OpenArena 0.8.8 QVMs. (Technically it was undefined
behavior.)

Add Q_strncpy() by Eugene C. from Quake3e that allows overlapping dest
and src for QVM strncpy syscalls.

I made Q_strncpyz() use it for consistency and made QVMs remap the
Q_strncpy() call to the strncpy syscall in case there is a better idea
of how to handle strncpy in the future. Try to handle strncpy the same
in QVMs and DLLs.
  • Loading branch information
zturtleman committed May 16, 2024
1 parent b5243bf commit 75d844d
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 4 deletions.
1 change: 1 addition & 0 deletions code/cgame/cg_syscalls.asm
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ equ trap_FS_Seek -90
equ memset -101
equ memcpy -102
equ strncpy -103
equ Q_strncpy -103 ; alternate name
equ sin -104
equ cos -105
equ atan2 -106
Expand Down
2 changes: 1 addition & 1 deletion code/client/cl_cgame.c
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
Com_Memcpy( VMA(1), VMA(2), args[3] );
return 0;
case CG_STRNCPY:
strncpy( VMA(1), VMA(2), args[3] );
Q_strncpy( VMA(1), VMA(2), args[3] );
return args[1];
case CG_SIN:
return FloatAsInt( sin( VMF(1) ) );
Expand Down
2 changes: 1 addition & 1 deletion code/client/cl_ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,7 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
return 0;

case UI_STRNCPY:
strncpy( VMA(1), VMA(2), args[3] );
Q_strncpy( VMA(1), VMA(2), args[3] );
return args[1];

case UI_SIN:
Expand Down
1 change: 1 addition & 0 deletions code/game/g_syscalls.asm
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ equ trap_FS_Seek -46
equ memset -101
equ memcpy -102
equ strncpy -103
equ Q_strncpy -103 ; alternate name
equ sin -104
equ cos -105
equ atan2 -106
Expand Down
27 changes: 26 additions & 1 deletion code/qcommon/q_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,31 @@ int Q_vsnprintf(char *str, size_t size, const char *format, va_list ap)
}
#endif

#ifndef Q3_VM
/*
=============
Q_strncpy
strncpy that allows overlapping dest and src
QVMs uses the strncpy syscall to call this
=============
*/
char *Q_strncpy( char *dest, const char *src, int destsize ) {
char *start = dest;

while ( destsize > 0 && (*dest++ = *src++) != '\0' ) {
--destsize;
}

while ( --destsize > 0 ) {
*dest++ = '\0';
}

return start;
}
#endif

/*
=============
Q_strncpyz
Expand All @@ -820,7 +845,7 @@ void Q_strncpyz( char *dest, const char *src, int destsize ) {
Com_Error(ERR_FATAL,"Q_strncpyz: destsize < 1" );
}

strncpy( dest, src, destsize-1 );
Q_strncpy( dest, src, destsize-1 );
dest[destsize-1] = 0;
}

Expand Down
5 changes: 5 additions & 0 deletions code/qcommon/q_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,11 @@ char *Q_strlwr( char *s1 );
char *Q_strupr( char *s1 );
const char *Q_stristr( const char *s, const char *find);

#ifndef Q3_VM
// allows overlapping dest and src
char *Q_strncpy( char *dest, const char *src, int destsize );
#endif

// buffer size safe library replacements
void Q_strncpyz( char *dest, const char *src, int destsize );
void Q_strcat( char *dest, int size, const char *src );
Expand Down
2 changes: 1 addition & 1 deletion code/server/sv_game.c
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
return 0;

case TRAP_STRNCPY:
strncpy( VMA(1), VMA(2), args[3] );
Q_strncpy( VMA(1), VMA(2), args[3] );
return args[1];

case TRAP_SIN:
Expand Down
1 change: 1 addition & 0 deletions code/ui/ui_syscalls.asm
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ equ trap_SetPbClStatus -88
equ memset -101
equ memcpy -102
equ strncpy -103
equ Q_strncpy -103 ; alternate name
equ sin -104
equ cos -105
equ atan2 -106
Expand Down

0 comments on commit 75d844d

Please sign in to comment.