You are on page 1of 12

:

memset
:
: 23.07.2012
,
.
, . Copy-Paste,
, unsigned_integer < 0. .
MAME, memset().
MAME - ,
,
[1]. ".c",
NAME ++.
110 .
MAME PVS-Studio , Windows
MinGW. MinGW GNU
Compiler Collection (GCC) Microsoft Windows [2]. , PVS-Studio
GCC .
MinGW PVS-Studio, 4.70. ,
.
MAME.
. , .
,
. , , .
. ,
, . ,
" ".
.


, MAME ,
memset. .
:
UINT32 m_pstars_regs[16];
static DRIVER_INIT( pstar )
{
...

memset(state->m_pstars_regs, 0, 16);
...
}
PVS-Studio: V512 A call of the 'memset' function will lead to underflow of the buffer 'state>m_pstars_regs'. pgm.c 4458
16 "m_pstars_regs". memset
. ,
.
:
memset(state->m_pstars_regs, 0, 16 * sizeof(UINT32));
. ,
(. [3]). .
.
, ? . 8 ,
:

V512 A call of the 'memset' function will lead to underflow of the buffer 'state->m_kb_regs'.
pgm.c 4975
V512 A call of the 'memset' function will lead to underflow of the buffer 'state->m_kb_regs'.
pgm.c 4996
V512 A call of the 'memset' function will lead to underflow of the buffer 'state->m_kb_regs'.
pgm.c 5056
V512 A call of the 'memset' function will lead to underflow of the buffer 'state>m_oldsplus_ram'. pgm.c 5780
V512 A call of the 'memset' function will lead to underflow of the buffer 'state>m_oldsplus_regs'. pgm.c 5781
V512 A call of the 'memset' function will lead to underflow of the buffer 'state->m_sysreg'.
rungun.c 399
V512 A call of the 'memset' function will lead to underflow of the buffer 'state->m_ttl_vram'.
rungun.c 400
V512 A call of the 'memset' function will lead to underflow of the buffer 'state>m_playfield_code'. malzak.c 392

, .
. , . ,
.
UINT16

m_control_0[8];

#define ARRAY_LENGTH(x)

(sizeof(x) / sizeof(x[0]))

static MACHINE_RESET( tumbleb )

{
...
memset(state->m_control_0, 0,
ARRAY_LENGTH(state->m_control_0));
}
PVS-Studio: V512 A call of the 'memset' function will lead to underflow of the buffer 'state>m_control_0'. tumbleb.c 2065
ARRAY_LENGTH.
. , .
.
:
memset(state->m_control_0, 0, sizeof(state->m_control_0));
:
memset(state->m_control_0, 0,
ARRAY_LENGTH(state->m_control_0) * sizeof(UINT16));

, :

V512 A call of the 'memset' function will lead to underflow of the buffer 'state->m_pmac_read'.
megadriv.c 7156
V512 A call of the 'memset' function will lead to underflow of the buffer 'state->m_pmac_write'.
megadriv.c 7157
V512 A call of the 'memset' function will lead to underflow of the buffer 'state>m_cart_is_genesis'. megatech.c 426
V512 A call of the 'memset' function will lead to underflow of the buffer 'state->m_vol_ctrl'.
nycaptor.c 841
V512 A call of the 'memset' function will lead to underflow of the buffer 'state->m_rotate_ctrl'.
wgp.c 949
V512 A call of the 'memset' function will lead to underflow of the buffer 'state->m_vreg'.
othldrby.c 237

memset() . ,
. memcpy().

memcpy()
, :

#define CHD_SHA1_BYTES

20

#define CHD_V4_HEADER_SIZE
#define CHD_MAX_HEADER_SIZE

108
CHD_V4_HEADER_SIZE

static chd_error header_read(...., chd_header *header)


{
UINT8 rawheader[CHD_MAX_HEADER_SIZE];
...
memcpy(header->parentsha1, &rawheader[100], CHD_SHA1_BYTES);
...
}
PVS-Studio: V512 A call of the 'memcpy' function will lead to the '& rawheader[100]' buffer becoming
out of range. chd.c 1870
'rawheader' 108 . ,
100. , .
8 . 20 . , , ,
.

memset() . ,
memcpy() , -
. :
UINT16 m_spriteram16[0x1000];
UINT16 m_spriteram16_buffered[0x1000];

static WRITE32_HANDLER( deco32_buffer_spriteram_w )


{
deco32_state *state =
space->machine().driver_data<deco32_state>();
memcpy(state->m_spriteram16_buffered,
state->m_spriteram16, 0x1000);
}

PVS-Studio: V512 A call of the 'memcpy' function will lead to underflow of the buffer 'state>m_spriteram16_buffered'. deco32.c 706
. . , ,
sizeof(UINT16).
:
memcpy(state->m_spriteram16_buffered,
state->m_spriteram16,
0x1000 * sizeof(UINT16));
:
V512 A call of the 'memcpy' function will lead to underflow of the buffer 'state>m_spriteram16_2_buffered'. deco32.c 726

Copy-Paste
, -
Copy-Paste. - , - . MAME
, - . .
static WRITE8_HANDLER( tms70x0_pf_w )
{
...
if( ((cpustate->pf[0x03] & 0x80) == 0) &&
((data & 0x80) == 0x80 ) )
{
...
}
else if( ((data & 0x80) == 0x80 ) &&
((cpustate->pf[0x03] & 0x80) == 0) )
{
...
}
...
}

PVS-Studio: V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of
logical error presence. Check lines: 577, 584. tms7000.c 577
, , .
, .
.
class device_debug
{
device_disasm_interface *m_disasm;
...
int min_opcode_bytes() const
{
return (m_disasm != NULL) ?
m_disasm->max_opcode_bytes() : 1;
}
int max_opcode_bytes() const
{
return (m_disasm != NULL) ?
m_disasm->max_opcode_bytes() : 1;
}
}
PVS-Studio: V524 It is odd that the body of 'max_opcode_bytes' function is fully equivalent to the body
of 'min_opcode_bytes' function (debugcpu.h, line 150). debugcpu.h 151
max_opcode_bytes() min_opcode_bytes().
. , min_opcode_bytes() :
int min_opcode_bytes() const
{
return (m_disasm != NULL) ?
m_disasm->min_opcode_bytes() : 1;
}
, :

V583 The '?:' operator, regardless of its conditional expression, always returns one and the same
value: ",(%d,". 9900dasm.c 670
V517 The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a probability of logical
error presence. Check lines: 549, 579. cdrom.c 549
V501 There are identical sub-expressions 'offset != (0x370 >> 1)' to the left and to the right of
the '&&' operator. decoprot.c 118
V501 There are identical sub-expressions 'offset != (0x3c0 >> 1)' to the left and to the right of
the '&&' operator. decoprot.c 118
V501 There are identical sub-expressions 'offset != 0x2c / 2' to the left and to the right of the
'&&' operator. decoprot.c 240
V501 There are identical sub-expressions 'offset != 0xe' to the left and to the right of the '&&'
operator. decoprot.c 447

Undefined behavior
, PVS-Studio, .
undefined behavior. , ,
.
. , ,
. : " ,
. ." [4].
, . :
#define ATARIRLE_PRIORITY_SHIFT

12

#define ATARIRLE_PRIORITY_MASK \
((~0 << ATARIRLE_PRIORITY_SHIFT) & 0xffff)
PVS-Studio: V610 Undefined behavior. Check the shift operator '<<. The left operand '~0' is negative.
atarig42.c 220
, ATARIRLE_PRIORITY_MASK
. .
:
#define ATARIRLE_PRIORITY_MASK \
((~(0u) << ATARIRLE_PRIORITY_SHIFT) & 0xffff)

, :
UINT32 m_color1_mask;
#define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0]))
PALETTE_INIT( montecar )
{

static const UINT8 colortable_source[] =


{
0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03,
0x03, 0x03, 0x03, 0x02, 0x03, 0x01, 0x03, 0x00,
0x00, 0x00, 0x02, 0x00, 0x02, 0x01, 0x02, 0x02,
0x00, 0x10, 0x20, 0x30, 0x00, 0x04, 0x08, 0x0c,
0x00, 0x44, 0x48, 0x4c, 0x00, 0x84, 0x88, 0x8c,
0x00, 0xc4, 0xc8, 0xcc
};
...
for (i = 0; i < ARRAY_LENGTH(colortable_source); i++)
{
UINT8 color = colortable_source[i];
if (color == 1)
state->m_color1_mask |= 1 << i;
...
}
...
}
PVS-Studio: V610 Undefined behavior. Check the shift operator '<<. The right operand ('i' = [0..43]) is
greater than or equal to the length in bits of the promoted left operand. firetrk.c 111
'colortable_source' 44 . , 'i'
0 43. '1' int. 31 .
, , Undefined behavior.
, , .
, : mame-shift-ub.txt.


memset() memcpy(), memcmp(). .
MAME , .
static const char *apr_magic = "ACT Apricot disk image\x1a\x04";

FLOPPY_IDENTIFY( apridisk_identify )
{
UINT8 header[APR_HEADER_SIZE];
floppy_image_read(floppy, &header, 0, sizeof(header));
if (memcmp(header, apr_magic, sizeof(apr_magic)) == 0)
...
}
PVS-Studio: V579 The memcmp function receives the pointer and its size as arguments. It is possibly a
mistake. Inspect the third argument. apridisk.c 128
sizeof() , . ,
. ,
'apr_magic' :
static const char apr_magic[] = "ACT Apricot disk image\x1a\x04";

, :
int m_led_extender;
#define CARD_A

#define NO_EXTENDER

static WRITE8_DEVICE_HANDLER( pia_ic5_porta_w )


{
...
else if ((state->m_led_extender != CARD_A)||
(state->m_led_extender != NO_EXTENDER))
...
}
PVS-Studio: V547 Expression is always true. Probably the '&&' operator should be used here. mpu4.c
934
"X != 1 || X != 0" . , '||'
'&&'.

. .
V595, . ,
. :
static void stv_vdp2_drawgfxzoom(...,
const gfx_element *gfx, ...)
{
...
if (gfx->pen_usage &&
transparency == STV_TRANSPARENCY_PEN)
{
...
}

if( gfx )
{
...
}
...
}
PVS-Studio: V595 The 'gfx' pointer was utilized before it was verified against nullptr. Check lines: 2457,
2483. stvvdp2.c 2457

, ,
. , Copy-Paste. ,
. :
static DEVICE_START( deco16ic )
{
...
if (intf->split)
deco16ic->pf2_tilemap_16x16 =
tilemap_create_device(device, get_pf2_tile_info,
deco16_scan_rows, 16, 16, fullwidth ?

64 : 32, fullheight ? 64 : 32);


else
deco16ic->pf2_tilemap_16x16 =
tilemap_create_device(device, get_pf2_tile_info,
deco16_scan_rows, 16, 16, fullwidth ?
64 : 32, fullheight ? 64 : 32);
...
}
PVS-Studio: V523 The 'then' statement is equivalent to the 'else' statement. deco16ic.c 943
.
:
int compute_res_net(int inputs, int channel, const res_net_info *di)
{
...
if (OpenCol)
{
rTotal += 1.0 / di->rgb[channel].R[i];
v += vOL / di->rgb[channel].R[i];
}
else
{
rTotal += 1.0 / di->rgb[channel].R[i];
v += vOL / di->rgb[channel].R[i];
}
...
}
PVS-Studio: V523 The 'then' statement is equivalent to the 'else' statement. resnet.c 628

, , , ,
MAME PVS-Studio. , PVS-Studio

. make-,
. ,
, MinGW.
P.S. Visual Studio,
. . ,
,
, Visual Studio.


1. Wikipedia. MAME. http://www.viva64.com/go.php?url=842
2. Wikipedia. MinGW. http://www.viva64.com/go.php?url=892
3. .
. http://www.viva64.com/ru/b/0116/
4. , . . http://www.viva64.com/ru/b/0142/