Skip to content

Commit 790deeb

Browse files
authored
Silence GCC 14 warning [-Warray-bounds=] (libretro#17110)
* Silence GCC 14 warning [-Warray-bounds=] GCC reports a couple of warnings like this example: libretro-common/cdrom/cdrom.c:395:14: warning: array subscript 6 is outside array bounds of 'unsigned char[6]' [-Warray-bounds=] 395 | cmd[6] = cmd[3]; | ~~~~~~~^~~~~~~~ libretro-common/cdrom/cdrom.c: In function 'cdrom_unlock': libretro-common/cdrom/cdrom.c:1268:18: note: at offset 6 into object 'cdb' of size 6 1268 | unsigned char cdb[] = {0x1E, 0, 0, 0, 0x2, 0}; The static analysis heuristic doesn't consider the fact that the writes to cmd[6] and later only happen under the condition that `if (cmd[0] == 0xBE || cmd[0] == 0xB9)` and that in all of those cases the array passed is wide enough. So this is a false positive. Nevertheless, there seems to be an easy way to silence the warning without disabling it: just require all arrays passed to be at least 9 bytes long and explicitly set the size of those arrays that have been shorter to 9. * Work around the requirement of C89 I used a C99 construct, but this is easy to work around with a run-time check. * Restore the check for non-null cmd It was obsoleted in a previous version, but is needed back now. --------- Co-authored-by: pstef <[email protected]>
1 parent fd9f242 commit 790deeb

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

libretro-common/cdrom/cdrom.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
#define CDROM_CUE_TRACK_BYTES 107
6363
#define CDROM_MAX_SENSE_BYTES 16
6464
#define CDROM_MAX_RETRIES 10
65+
#define CDROM_MIN_BUFSIZE 9
6566

6667
typedef enum
6768
{
@@ -383,7 +384,7 @@ static int cdrom_send_command(libretro_vfs_implementation_file *stream, CDROM_CM
383384
size_t copied_bytes = 0;
384385
bool read_cd = false;
385386

386-
if (!cmd || cmd_len == 0)
387+
if (!cmd || cmd_len == 0 || cmd_len < CDROM_MIN_BUFSIZE)
387388
return 1;
388389

389390
if (cmd[0] == 0xBE || cmd[0] == 0xB9)
@@ -665,7 +666,7 @@ static const char* get_profile(unsigned short profile)
665666

666667
int cdrom_get_sense(libretro_vfs_implementation_file *stream, unsigned char *sense, size_t len)
667668
{
668-
unsigned char cdb[] = {0x3, 0, 0, 0, 0xFC, 0};
669+
unsigned char cdb[CDROM_MIN_BUFSIZE] = {0x3, 0, 0, 0, 0xFC, 0};
669670
unsigned char buf[0xFC] = {0};
670671
int rv = cdrom_send_command(stream, DIRECTION_IN, buf, sizeof(buf), cdb, sizeof(cdb), 0);
671672

@@ -1161,7 +1162,7 @@ int cdrom_write_cue(libretro_vfs_implementation_file *stream, char **out_buf, si
11611162
int cdrom_get_inquiry(libretro_vfs_implementation_file *stream, char *model, int len, bool *is_cdrom)
11621163
{
11631164
/* MMC Command: INQUIRY */
1164-
unsigned char cdb[] = {0x12, 0, 0, 0, 0xff, 0};
1165+
unsigned char cdb[CDROM_MIN_BUFSIZE] = {0x12, 0, 0, 0, 0xff, 0};
11651166
unsigned char buf[256] = {0};
11661167
int rv = cdrom_send_command(stream, DIRECTION_IN, buf, sizeof(buf), cdb, sizeof(cdb), 0);
11671168
bool cdrom = false;
@@ -1248,7 +1249,7 @@ int cdrom_read(libretro_vfs_implementation_file *stream, cdrom_group_timeouts_t
12481249
int cdrom_stop(libretro_vfs_implementation_file *stream)
12491250
{
12501251
/* MMC Command: START STOP UNIT */
1251-
unsigned char cdb[] = {0x1B, 0, 0, 0, 0x0, 0};
1252+
unsigned char cdb[CDROM_MIN_BUFSIZE] = {0x1B, 0, 0, 0, 0x0, 0};
12521253
int rv = cdrom_send_command(stream, DIRECTION_NONE, NULL, 0, cdb, sizeof(cdb), 0);
12531254

12541255
#ifdef CDROM_DEBUG
@@ -1265,7 +1266,7 @@ int cdrom_stop(libretro_vfs_implementation_file *stream)
12651266
int cdrom_unlock(libretro_vfs_implementation_file *stream)
12661267
{
12671268
/* MMC Command: PREVENT ALLOW MEDIUM REMOVAL */
1268-
unsigned char cdb[] = {0x1E, 0, 0, 0, 0x2, 0};
1269+
unsigned char cdb[CDROM_MIN_BUFSIZE] = {0x1E, 0, 0, 0, 0x2, 0};
12691270
int rv = cdrom_send_command(stream, DIRECTION_NONE, NULL, 0, cdb, sizeof(cdb), 0);
12701271

12711272
#ifdef CDROM_DEBUG
@@ -1294,7 +1295,7 @@ int cdrom_unlock(libretro_vfs_implementation_file *stream)
12941295
int cdrom_open_tray(libretro_vfs_implementation_file *stream)
12951296
{
12961297
/* MMC Command: START STOP UNIT */
1297-
unsigned char cdb[] = {0x1B, 0, 0, 0, 0x2, 0};
1298+
unsigned char cdb[CDROM_MIN_BUFSIZE] = {0x1B, 0, 0, 0, 0x2, 0};
12981299
int rv;
12991300

13001301
cdrom_unlock(stream);
@@ -1316,7 +1317,7 @@ int cdrom_open_tray(libretro_vfs_implementation_file *stream)
13161317
int cdrom_close_tray(libretro_vfs_implementation_file *stream)
13171318
{
13181319
/* MMC Command: START STOP UNIT */
1319-
unsigned char cdb[] = {0x1B, 0, 0, 0, 0x3, 0};
1320+
unsigned char cdb[CDROM_MIN_BUFSIZE] = {0x1B, 0, 0, 0, 0x3, 0};
13201321
int rv = cdrom_send_command(stream, DIRECTION_NONE, NULL, 0, cdb, sizeof(cdb), 0);
13211322

13221323
#ifdef CDROM_DEBUG
@@ -1495,7 +1496,7 @@ struct string_list* cdrom_get_available_drives(void)
14951496
bool cdrom_is_media_inserted(libretro_vfs_implementation_file *stream)
14961497
{
14971498
/* MMC Command: TEST UNIT READY */
1498-
unsigned char cdb[] = {0x00, 0, 0, 0, 0, 0};
1499+
unsigned char cdb[CDROM_MIN_BUFSIZE] = {0x00, 0, 0, 0, 0, 0};
14991500
int rv = cdrom_send_command(stream, DIRECTION_NONE, NULL, 0, cdb, sizeof(cdb), 0);
15001501

15011502
#ifdef CDROM_DEBUG

0 commit comments

Comments
 (0)