Skip to content

Commit c98ec01

Browse files
core: use size-limited string formatting functions
1 parent 94bca35 commit c98ec01

8 files changed

Lines changed: 62 additions & 26 deletions

File tree

libretro/libretro.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <stdarg.h>
55
#include <ctype.h>
66

7+
#include <compat/strl.h>
8+
79
#ifdef _MSC_VER
810
#include <compat/msvc.h>
911
#endif
@@ -1865,8 +1867,8 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) {
18651867
return;
18661868
}
18671869

1868-
sprintf(name, "N/A");
1869-
strcpy(temp, code);
1870+
strlcpy(name, "N/A", sizeof(name));
1871+
strlcpy(temp, code, sizeof(temp));
18701872
codepart = strtok(temp, "+,;._ ");
18711873

18721874
while (codepart) {

libretro/libretro_dipswitch.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,10 +1109,22 @@ static void make_core_options(struct retro_core_option_v2_definition *vs_core_op
11091109
memset(&vs_core_options[i], 0,
11101110
sizeof(struct retro_core_option_v2_definition));
11111111

1112-
/* Set core key and sanitize string */
1113-
sprintf(key, "fceumm_next_dipswitch_%s-%s", game_name, option_name);
1114-
core_key[i] = calloc(strlen(key) + 1, sizeof(char));
1115-
strcpy(core_key[i], key);
1112+
/* Set core key and sanitize string. Build "fceumm_dipswitch_<game>-<option>"
1113+
* with strlcpy/strlcat instead of snprintf, since snprintf isn't
1114+
* available on pre-MSVC2015 unless compat_snprintf.c is linked
1115+
* (some build configurations omit it). strlcpy/strlcat truncate
1116+
* safely if the inputs together would overflow key[]. */
1117+
strlcpy(key, "fceumm_dipswitch_", sizeof(key));
1118+
strlcat(key, game_name, sizeof(key));
1119+
strlcat(key, "-", sizeof(key));
1120+
strlcat(key, option_name, sizeof(key));
1121+
{
1122+
size_t key_size = strlen(key) + 1;
1123+
core_key[i] = calloc(key_size, sizeof(char));
1124+
if (!core_key[i])
1125+
continue;
1126+
strlcpy(core_key[i], key, key_size);
1127+
}
11161128
vs_core_options[i].key = str_to_corekey(core_key[i]);
11171129

11181130
/* Set desc */

src/cheat.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <string.h>
2424
#include <ctype.h>
2525

26+
#include <compat/strl.h>
27+
2628
#include "fceu-types.h"
2729
#include "x6502.h"
2830
#include "cheat.h"
@@ -202,12 +204,13 @@ void FCEU_ResetCheats(void)
202204

203205
int FCEUI_AddCheat(const char *name, uint32_t addr, uint8_t val, int compare, int type) {
204206
char *t;
207+
size_t n = strlen(name) + 1;
205208

206209
if (!(t = (char*)malloc(strlen(name) + 1))) {
207210
CheatMemErr();
208211
return(0);
209212
}
210-
strcpy(t, name);
213+
strlcpy(t, name, n);
211214
if (!AddCheatEntry(t, addr, val, compare, 1, type)) {
212215
free(t);
213216
return(0);
@@ -423,10 +426,11 @@ int FCEUI_SetCheat(uint32_t which, const char *name, int32_t a, int32_t v, int c
423426
if (x == which) {
424427
if (name) {
425428
char *t;
429+
size_t n = strlen(name) + 1;
426430

427-
if ((t = (char*)realloc(next->name, strlen(name) + 1))) {
431+
if ((t = (char*)realloc(next->name, n))) {
428432
next->name = t;
429-
strcpy(next->name, name);
433+
strlcpy(next->name, name, n);
430434
} else
431435
return(0);
432436
}

src/general.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include <string.h>
2323
#include <stdarg.h>
2424

25+
#include <compat/strl.h>
26+
2527
#include <sys/types.h>
2628
#include <sys/stat.h>
2729
#ifdef _WIN32
@@ -45,13 +47,13 @@
4547
static char BaseDirectory[2048] = { 0 };
4648

4749
void FCEUI_SetBaseDirectory(const char *dir) {
48-
strncpy(BaseDirectory, dir, 2047);
49-
BaseDirectory[2047] = 0;
50+
strlcpy(BaseDirectory, dir, sizeof(BaseDirectory));
5051
}
5152

5253
char *FCEU_MakeFName(int type, int id1, char *cd1) {
5354
char tmp[4096 + 512] = { 0 }; /* +512 for no reason :D */
5455
char *ret = 0;
56+
size_t len;
5557

5658
switch (type) {
5759
case FCEUMKF_GGROM:
@@ -72,8 +74,10 @@ char *FCEU_MakeFName(int type, int id1, char *cd1) {
7274

7375
FCEU_printf(" FCEU_MakeFName: %s\n", tmp);
7476

75-
ret = (char *)FCEU_malloc(strlen(tmp) * sizeof(char) + 1);
76-
strcpy(ret, tmp);
77+
len = strlen(tmp) + 1;
78+
ret = (char *)malloc(len);
79+
if (!ret) return NULL;
80+
strlcpy(ret, tmp, len);
7781

7882
return (ret);
7983
}

src/input/bworld.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,19 @@ static void Write(uint8_t V) {
4848

4949
static void Update(void *data, int arg) {
5050
if (*(uint8_t*)data) {
51+
size_t i;
52+
const uint8_t *src = (uint8_t*)data + 1;
5153
*(uint8_t*)data = 0;
5254
seq = ptr = 0;
5355
have = 1;
54-
strcpy((char*)bdata, (const char*)((uint8_t*)data + 1));
56+
/* bdata is 20 bytes total; bytes 13..19 are filled by the
57+
* memcpy below. Copy at most 13 bytes from `src`, ensuring
58+
* NUL termination at index 13 or earlier. */
59+
for (i = 0; i < 13; i++) {
60+
if (!src[i]) break;
61+
bdata[i] = src[i];
62+
}
63+
bdata[i] = 0;
5564
memcpy((char*)&bdata[13], "SUNSOFT", 7);
5665
}
5766
}

src/nsf.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <string.h>
2424
#include <math.h>
2525

26+
#include <compat/strl.h>
27+
2628
#include "fceu-types.h"
2729
#include "x6502.h"
2830
#include "fceu.h"
@@ -166,9 +168,9 @@ static int LoadNSF(FCEUFILE *fp) {
166168
/* NULL-terminate strings just in case. */
167169
NSFHeader.GameName[31] = NSFHeader.Artist[31] = NSFHeader.Copyright[31] = 0;
168170

169-
sprintf((char *)NSFInfo->SongName, "%s", (const char *)NSFHeader.GameName);
170-
sprintf((char *)NSFInfo->Artist, "%s", (const char *)NSFHeader.Artist);
171-
sprintf((char *)NSFInfo->Copyright, "%s", (const char *)NSFHeader.Copyright);
171+
snprintf((char *)NSFInfo->SongName, sizeof(NSFInfo->SongName), "%s", (const char *)NSFHeader.GameName);
172+
snprintf((char *)NSFInfo->Artist, sizeof(NSFInfo->Artist), "%s", (const char *)NSFHeader.Artist);
173+
snprintf((char *)NSFInfo->Copyright, sizeof(NSFInfo->Copyright), "%s", (const char *)NSFHeader.Copyright);
172174

173175
NSFInfo->LoadAddr = NSFHeader.LoadAddressLow | (NSFHeader.LoadAddressHigh << 8);
174176
NSFInfo->InitAddr = NSFHeader.InitAddressLow | (NSFHeader.InitAddressHigh << 8);
@@ -785,7 +787,7 @@ void DrawNSF(uint8_t *target) {
785787
} else {
786788
DrawTextTrans(target + 70 * 256 + 4 + (((31 - strlen("Song:")) << 2)), 256, (uint8_t *)"Song:", textColor);
787789
}
788-
sprintf(snbuf, "<%d/%d>", NSFInfo->CurrentSong + 1, NSFInfo->TotalSongs);
790+
snprintf(snbuf, sizeof(snbuf), "<%d/%d>", NSFInfo->CurrentSong + 1, NSFInfo->TotalSongs);
789791
DrawTextTrans(target + 82 * 256 + 4 + (((31 - strlen(snbuf)) << 2)), 256, (uint8_t *)snbuf, textColor);
790792
}
791793

@@ -852,8 +854,8 @@ int FCEUI_NSFChange(int amount) {
852854

853855
/* Returns total songs */
854856
int FCEUI_NSFGetInfo(uint8_t *name, uint8_t *artist, uint8_t *copyright, int maxlen) {
855-
strncpy((char *)name, (const char *)NSFInfo->SongName, (size_t)maxlen);
856-
strncpy((char *)artist, (const char *)NSFInfo->Artist, (size_t)maxlen);
857-
strncpy((char *)copyright, (const char *)NSFInfo->Copyright, (size_t)maxlen);
857+
strlcpy((char *)name, (const char *)NSFInfo->SongName, (size_t)maxlen);
858+
strlcpy((char *)artist, (const char *)NSFInfo->Artist, (size_t)maxlen);
859+
strlcpy((char *)copyright, (const char *)NSFInfo->Copyright, (size_t)maxlen);
858860
return (NSFInfo->TotalSongs);
859861
}

src/unif.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <string.h>
2727

2828
#include <file/file_path.h>
29+
#include <compat/strl.h>
2930

3031
#include "fceu-types.h"
3132
#include "fceu.h"
@@ -209,12 +210,12 @@ static uint8_t unif_NAME(FCEUFILE *fp) {
209210
}
210211

211212
namebuf[index] = 0;
212-
FCEU_printf(" Name: %s\n", namebuf);
213-
214213
if (!GameInfo->name) {
215-
GameInfo->name = FCEU_malloc(strlen(namebuf) + 1);
216-
strcpy((char *)GameInfo->name, namebuf);
214+
size_t n = strlen(namebuf) + 1;
215+
GameInfo->name = FCEU_malloc(n);
216+
strlcpy((char *)GameInfo->name, namebuf, n);
217217
}
218+
FCEU_printf(" Name: %s\n", GameInfo->name);
218219
return (1);
219220
}
220221

src/vsuni.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#include <string.h>
2222

23+
#include <compat/strl.h>
24+
2325
#include "fceu-types.h"
2426
#include "x6502.h"
2527
#include "fceu.h"
@@ -386,7 +388,7 @@ void FCEU_VSUniCheck(uint64_t md5partial, int *MapperNo, int *Mirroring) {
386388
GameInfo->input[1] = SI_GAMEPAD;
387389
}
388390

389-
strcpy(name, vs->name);
391+
strlcpy(name, vs->name, sizeof(name));
390392

391393
if (tofix) {
392394
FCEU_PrintError(" Incorrect VS-Uni header information!\n");

0 commit comments

Comments
 (0)