Skip to content

Commit 5e5e6e7

Browse files
committed
Workaround strncpy() in OpenArena QVMs
macOS (targeting newer SDKs) and glibc 2.37 changes broke overlapping dest and src in strncpy() used by OpenArena QVMs. (Technically it was undefined behavior.) In the QVM strncpy() syscall do not alter the dest if dest and src are equal. This fixes weapon barrel models for OpenArena 0.8.8.
1 parent fd0d65c commit 5e5e6e7

3 files changed

Lines changed: 24 additions & 3 deletions

File tree

code/client/cl_cgame.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,14 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
618618
Com_Memcpy( VMA(1), VMA(2), args[3] );
619619
return 0;
620620
case CG_STRNCPY:
621-
strncpy( VMA(1), VMA(2), args[3] );
621+
{
622+
char *dest = VMA(1);
623+
char *src = VMA(2);
624+
625+
if ( dest != src ) {
626+
strncpy( dest, src, args[3] );
627+
}
628+
}
622629
return args[1];
623630
case CG_SIN:
624631
return FloatAsInt( sin( VMF(1) ) );

code/client/cl_ui.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,14 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
10051005
return 0;
10061006

10071007
case UI_STRNCPY:
1008-
strncpy( VMA(1), VMA(2), args[3] );
1008+
{
1009+
char *dest = VMA(1);
1010+
char *src = VMA(2);
1011+
1012+
if ( dest != src ) {
1013+
strncpy( dest, src, args[3] );
1014+
}
1015+
}
10091016
return args[1];
10101017

10111018
case UI_SIN:

code/server/sv_game.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,14 @@ intptr_t SV_GameSystemCalls( intptr_t *args ) {
809809
return 0;
810810

811811
case TRAP_STRNCPY:
812-
strncpy( VMA(1), VMA(2), args[3] );
812+
{
813+
char *dest = VMA(1);
814+
char *src = VMA(2);
815+
816+
if ( dest != src ) {
817+
strncpy( dest, src, args[3] );
818+
}
819+
}
813820
return args[1];
814821

815822
case TRAP_SIN:

0 commit comments

Comments
 (0)