Merge branch 'master' of git://git.libdivecomputer.org/libdivecomputer into Subsurface-branch
Merge with upstream. This is Dirk's Coverity patches, just gone through Jef to avoid unnecessary merge issues. * git://git.libdivecomputer.org/libdivecomputer: Cleanup: remove confusing NULL check Cleanup: bail on error Cleanup: consistently check return value of iostream functions Cleanup: check return value of ioctl() Cleanup: remove dead code and return the correct return code Cleanup: avoid undefined shift operation Cleanup: ensure string is 0 terminated Cleanup: avoid memory leak Cleanup: avoid memory leak Cleanup: avoid memory leaks Cleanup: correctly handle upper bound of array
This commit is contained in:
commit
70ad30bed3
@ -159,7 +159,11 @@ citizen_aqualand_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
|
||||
return DC_STATUS_NOMEMORY;
|
||||
}
|
||||
|
||||
dc_iostream_set_dtr (device->iostream, 1);
|
||||
status = dc_iostream_set_dtr (device->iostream, 1);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to set the DTR line.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Send the init byte.
|
||||
const unsigned char init[] = {0x7F};
|
||||
@ -201,7 +205,11 @@ citizen_aqualand_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
|
||||
break;
|
||||
}
|
||||
|
||||
dc_iostream_set_dtr (device->iostream, 0);
|
||||
status = dc_iostream_set_dtr (device->iostream, 0);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to clear the DTR line.");
|
||||
return status;
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -477,6 +477,7 @@ divesystem_idive_device_foreach (dc_device_t *abstract, dc_dive_callback_t callb
|
||||
WARNING(abstract->context, "Skipped unreadable dive!");
|
||||
continue;
|
||||
} else {
|
||||
dc_buffer_free(buffer);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@ -500,8 +501,10 @@ divesystem_idive_device_foreach (dc_device_t *abstract, dc_dive_callback_t callb
|
||||
(idx ) & 0xFF,
|
||||
(idx >> 8) & 0xFF};
|
||||
rc = divesystem_idive_transfer (device, cmd_sample, sizeof(cmd_sample), packet, commands->sample.size * commands->nsamples, &errcode);
|
||||
if (rc != DC_STATUS_SUCCESS)
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
dc_buffer_free(buffer);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// If the number of samples is not an exact multiple of the
|
||||
// number of samples per packet, then the last packet
|
||||
|
||||
@ -905,7 +905,12 @@ hw_ostc_device_fwupdate (dc_device_t *abstract, const char *filename)
|
||||
// bootloader needs to be send repeatedly, until the response packet is
|
||||
// received. Thus the time between each two attempts is directly controlled
|
||||
// by the timeout value.
|
||||
dc_iostream_set_timeout (device->iostream, 300);
|
||||
rc = dc_iostream_set_timeout (device->iostream, 300);
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
ERROR (context, "Failed to set the timeout.");
|
||||
free (firmware);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Setup the bootloader.
|
||||
const unsigned int baudrates[] = {19200, 115200};
|
||||
@ -931,7 +936,12 @@ hw_ostc_device_fwupdate (dc_device_t *abstract, const char *filename)
|
||||
}
|
||||
|
||||
// Increase the timeout again.
|
||||
dc_iostream_set_timeout (device->iostream, 1000);
|
||||
rc = dc_iostream_set_timeout (device->iostream, 1000);
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
ERROR (context, "Failed to set the timeout.");
|
||||
free (firmware);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Enable progress notifications.
|
||||
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
|
||||
|
||||
20
src/irda.c
20
src/irda.c
@ -221,18 +221,22 @@ dc_irda_connect_name (dc_iostream_t *abstract, unsigned int address, const char
|
||||
peer.irdaDeviceID[1] = (address >> 8) & 0xFF;
|
||||
peer.irdaDeviceID[2] = (address >> 16) & 0xFF;
|
||||
peer.irdaDeviceID[3] = (address >> 24) & 0xFF;
|
||||
if (name)
|
||||
strncpy (peer.irdaServiceName, name, 25);
|
||||
else
|
||||
memset (peer.irdaServiceName, 0x00, 25);
|
||||
if (name) {
|
||||
strncpy (peer.irdaServiceName, name, sizeof(peer.irdaServiceName) - 1);
|
||||
peer.irdaServiceName[sizeof(peer.irdaServiceName) - 1] = '\0';
|
||||
} else {
|
||||
memset (peer.irdaServiceName, 0x00, sizeof(peer.irdaServiceName));
|
||||
}
|
||||
#else
|
||||
struct sockaddr_irda peer;
|
||||
peer.sir_family = AF_IRDA;
|
||||
peer.sir_addr = address;
|
||||
if (name)
|
||||
strncpy (peer.sir_name, name, 25);
|
||||
else
|
||||
memset (peer.sir_name, 0x00, 25);
|
||||
if (name) {
|
||||
strncpy (peer.sir_name, name, sizeof(peer.sir_name) - 1);
|
||||
peer.sir_name[sizeof(peer.sir_name) - 1] = '\0';
|
||||
} else {
|
||||
memset (peer.sir_name, 0x00, sizeof(peer.sir_name));
|
||||
}
|
||||
#endif
|
||||
|
||||
return dc_socket_connect (&device->base, (struct sockaddr *) &peer, sizeof (peer));
|
||||
|
||||
@ -331,7 +331,7 @@ mares_darwin_extract_dives (dc_device_t *abstract, const unsigned char data[], u
|
||||
current -= length;
|
||||
}
|
||||
|
||||
if (device && memcmp (buffer, device->fingerprint, sizeof (device->fingerprint)) == 0) {
|
||||
if (memcmp (buffer, device->fingerprint, sizeof (device->fingerprint)) == 0) {
|
||||
free (buffer);
|
||||
return DC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -620,7 +620,7 @@ mares_iconhd_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback,
|
||||
break;
|
||||
|
||||
unsigned char *fp = buffer + offset + length - headersize + fingerprint;
|
||||
if (device && memcmp (fp, device->fingerprint, sizeof (device->fingerprint)) == 0) {
|
||||
if (memcmp (fp, device->fingerprint, sizeof (device->fingerprint)) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -630,8 +630,16 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char
|
||||
dc_iostream_sleep (device->iostream, 100);
|
||||
|
||||
// Set the DTR/RTS lines.
|
||||
dc_iostream_set_dtr(device->iostream, 1);
|
||||
dc_iostream_set_rts(device->iostream, 1);
|
||||
status = dc_iostream_set_dtr(device->iostream, 1);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (context, "Failed to set the DTR line.");
|
||||
return status;
|
||||
}
|
||||
status = dc_iostream_set_rts(device->iostream, 1);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (context, "Failed to set the DTR line.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Make sure everything is in a sane state.
|
||||
dc_iostream_purge (device->iostream, DC_DIRECTION_ALL);
|
||||
|
||||
@ -269,9 +269,13 @@ oceanic_vtpro_calibrate (oceanic_vtpro_device_t *device)
|
||||
// device needs approximately 6 seconds to respond.
|
||||
unsigned char answer[2] = {0};
|
||||
unsigned char command[2] = {0x18, 0x00};
|
||||
dc_iostream_set_timeout (device->iostream, 9000);
|
||||
dc_status_t rc = oceanic_vtpro_transfer (device, command, sizeof (command), answer, sizeof (answer));
|
||||
dc_iostream_set_timeout (device->iostream, 3000);
|
||||
dc_status_t rc = dc_iostream_set_timeout (device->iostream, 9000);
|
||||
if (rc != DC_STATUS_SUCCESS)
|
||||
return rc;
|
||||
rc = oceanic_vtpro_transfer (device, command, sizeof (command), answer, sizeof (answer));
|
||||
if (rc != DC_STATUS_SUCCESS)
|
||||
return rc;
|
||||
rc = dc_iostream_set_timeout (device->iostream, 3000);
|
||||
if (rc != DC_STATUS_SUCCESS)
|
||||
return rc;
|
||||
|
||||
|
||||
@ -182,7 +182,11 @@ reefnet_sensuspro_handshake (reefnet_sensuspro_device_t *device)
|
||||
dc_device_t *abstract = (dc_device_t *) device;
|
||||
|
||||
// Assert a break condition.
|
||||
dc_iostream_set_break (device->iostream, 1);
|
||||
status = dc_iostream_set_break (device->iostream, 1);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to set break.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Receive the handshake from the dive computer.
|
||||
unsigned char handshake[SZ_HANDSHAKE + 2] = {0};
|
||||
@ -193,7 +197,11 @@ reefnet_sensuspro_handshake (reefnet_sensuspro_device_t *device)
|
||||
}
|
||||
|
||||
// Clear the break condition again.
|
||||
dc_iostream_set_break (device->iostream, 0);
|
||||
status = dc_iostream_set_break (device->iostream, 0);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to clear break.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Verify the checksum of the handshake packet.
|
||||
unsigned short crc = array_uint16_le (handshake + SZ_HANDSHAKE);
|
||||
|
||||
@ -716,6 +716,7 @@ reefnet_sensusultra_device_foreach (dc_device_t *abstract, dc_dive_callback_t ca
|
||||
|
||||
// Prepend the packet to the buffer.
|
||||
if (!dc_buffer_prepend (buffer, packet + 2, SZ_PACKET)) {
|
||||
dc_buffer_free (buffer);
|
||||
ERROR (abstract->context, "Insufficient buffer space available.");
|
||||
return DC_STATUS_NOMEMORY;
|
||||
}
|
||||
|
||||
@ -262,7 +262,11 @@ dc_serial_close (dc_iostream_t *abstract)
|
||||
|
||||
#ifndef ENABLE_PTY
|
||||
// Disable exclusive access mode.
|
||||
ioctl (device->fd, TIOCNXCL, NULL);
|
||||
if (ioctl (device->fd, TIOCNXCL, NULL)) {
|
||||
int errcode = errno;
|
||||
SYSERROR (abstract->context, errcode);
|
||||
dc_status_set_error(&status, syserror (errcode));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Close the device.
|
||||
|
||||
@ -240,7 +240,11 @@ suunto_d9_device_packet (dc_device_t *abstract, const unsigned char command[], u
|
||||
return DC_STATUS_CANCELLED;
|
||||
|
||||
// Clear RTS to send the command.
|
||||
dc_iostream_set_rts (device->iostream, 0);
|
||||
status = dc_iostream_set_rts (device->iostream, 0);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to clear RTS.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Send the command to the dive computer.
|
||||
status = dc_iostream_write (device->iostream, command, csize, NULL);
|
||||
@ -265,7 +269,11 @@ suunto_d9_device_packet (dc_device_t *abstract, const unsigned char command[], u
|
||||
}
|
||||
|
||||
// Set RTS to receive the reply.
|
||||
dc_iostream_set_rts (device->iostream, 1);
|
||||
status = dc_iostream_set_rts (device->iostream, 1);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to set RTS.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Receive the answer of the dive computer.
|
||||
status = dc_iostream_read (device->iostream, answer, asize, NULL);
|
||||
|
||||
@ -671,6 +671,7 @@ static int get_file_list(suunto_eonsteel_device_t *eon, struct directory_entry *
|
||||
sizeof(result), result);
|
||||
if (rc < 0) {
|
||||
ERROR(eon->base.context, "cmd DIR_LOOKUP failed");
|
||||
return -1;
|
||||
}
|
||||
HEXDUMP(eon->base.context, DC_LOGLEVEL_DEBUG, "DIR_LOOKUP", result, rc);
|
||||
|
||||
|
||||
@ -217,7 +217,7 @@ static int fill_in_group_details(suunto_eonsteel_parser_t *eon, struct type_desc
|
||||
long index;
|
||||
|
||||
index = strtol(grp, &end, 10);
|
||||
if (index < 0 || index > MAXTYPE || end == grp) {
|
||||
if (index < 0 || index >= MAXTYPE || end == grp) {
|
||||
ERROR(eon->base.context, "Group type descriptor '%s' does not parse", desc->desc);
|
||||
break;
|
||||
}
|
||||
@ -344,7 +344,7 @@ static int record_type(suunto_eonsteel_parser_t *eon, unsigned short type, const
|
||||
}
|
||||
} while ((name = next) != NULL);
|
||||
|
||||
if (type > MAXTYPE) {
|
||||
if (type >= MAXTYPE) {
|
||||
ERROR(eon->base.context, "Type out of range (%04x: '%s' '%s' '%s')",
|
||||
type,
|
||||
desc.desc ? desc.desc : "",
|
||||
@ -413,7 +413,7 @@ static int traverse_entry(suunto_eonsteel_parser_t *eon, const unsigned char *p,
|
||||
end += 4;
|
||||
}
|
||||
|
||||
if (type > MAXTYPE || !eon->type_desc[type].desc) {
|
||||
if (type >= MAXTYPE || !eon->type_desc[type].desc) {
|
||||
HEXDUMP(eon->base.context, DC_LOGLEVEL_DEBUG, "last", last, 16);
|
||||
HEXDUMP(eon->base.context, DC_LOGLEVEL_DEBUG, "this", begin, 16);
|
||||
} else {
|
||||
@ -776,10 +776,12 @@ static void sample_setpoint_type(const struct type_desc *desc, struct sample_dat
|
||||
sample.ppo2 = info->eon->cache.customsetpoint;
|
||||
else {
|
||||
DEBUG(info->eon->base.context, "sample_setpoint_type(%u) unknown type '%s'", value, type);
|
||||
free((void *)type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->callback) info->callback(DC_SAMPLE_SETPOINT, sample, info->userdata);
|
||||
free((void *)type);
|
||||
}
|
||||
|
||||
// uint32
|
||||
@ -1125,6 +1127,7 @@ static int add_gas_type(suunto_eonsteel_parser_t *eon, const struct type_desc *d
|
||||
|
||||
eon->cache.initialized |= 1 << DC_FIELD_GASMIX_COUNT;
|
||||
eon->cache.initialized |= 1 << DC_FIELD_TANK_COUNT;
|
||||
free((void *)name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -161,7 +161,11 @@ suunto_solution_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
|
||||
unsigned char answer[3] = {0};
|
||||
|
||||
// Assert DTR
|
||||
dc_iostream_set_dtr (device->iostream, 1);
|
||||
status = dc_iostream_set_dtr(device->iostream, 1);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to set the DTR line.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Send: 0xFF
|
||||
command[0] = 0xFF;
|
||||
|
||||
@ -178,7 +178,11 @@ suunto_vyper_send (suunto_vyper_device_t *device, const unsigned char command[],
|
||||
dc_iostream_sleep (device->iostream, 500);
|
||||
|
||||
// Set RTS to send the command.
|
||||
dc_iostream_set_rts (device->iostream, 1);
|
||||
status = dc_iostream_set_rts (device->iostream, 1);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to set RTS.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Send the command to the dive computer.
|
||||
status = dc_iostream_write (device->iostream, command, csize, NULL);
|
||||
@ -202,7 +206,11 @@ suunto_vyper_send (suunto_vyper_device_t *device, const unsigned char command[],
|
||||
dc_iostream_purge (device->iostream, DC_DIRECTION_INPUT);
|
||||
|
||||
// Clear RTS to receive the reply.
|
||||
dc_iostream_set_rts (device->iostream, 0);
|
||||
status = dc_iostream_set_rts (device->iostream, 0);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to clear RTS.");
|
||||
return status;
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -127,10 +127,18 @@ suunto_vyper2_device_open (dc_device_t **out, dc_context_t *context, const char
|
||||
dc_iostream_sleep (device->iostream, 100);
|
||||
|
||||
// Make sure everything is in a sane state.
|
||||
dc_iostream_purge (device->iostream, DC_DIRECTION_ALL);
|
||||
status = dc_iostream_purge (device->iostream, DC_DIRECTION_ALL);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (context, "Failed to reset IO state.");
|
||||
goto error_close;
|
||||
}
|
||||
|
||||
// Enable half-duplex emulation.
|
||||
dc_iostream_set_halfduplex (device->iostream, 1);
|
||||
status = dc_iostream_set_halfduplex (device->iostream, 1);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (context, "Failed to set half duplex.");
|
||||
goto error_close;
|
||||
}
|
||||
|
||||
// Read the version info.
|
||||
status = suunto_common2_device_version ((dc_device_t *) device, device->base.version, sizeof (device->base.version));
|
||||
@ -187,7 +195,11 @@ suunto_vyper2_device_packet (dc_device_t *abstract, const unsigned char command[
|
||||
dc_iostream_sleep (device->iostream, 600);
|
||||
|
||||
// Set RTS to send the command.
|
||||
dc_iostream_set_rts (device->iostream, 1);
|
||||
status = dc_iostream_set_rts (device->iostream, 1);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to set the RTS line.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Send the command to the dive computer.
|
||||
status = dc_iostream_write (device->iostream, command, csize, NULL);
|
||||
@ -197,7 +209,11 @@ suunto_vyper2_device_packet (dc_device_t *abstract, const unsigned char command[
|
||||
}
|
||||
|
||||
// Clear RTS to receive the reply.
|
||||
dc_iostream_set_rts (device->iostream, 0);
|
||||
status = dc_iostream_set_rts (device->iostream, 0);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to set the RTS line.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Receive the answer of the dive computer.
|
||||
status = dc_iostream_read (device->iostream, answer, asize, NULL);
|
||||
|
||||
@ -213,17 +213,10 @@ error_free:
|
||||
static dc_status_t
|
||||
uwatec_smart_device_close (dc_device_t *abstract)
|
||||
{
|
||||
dc_status_t status = DC_STATUS_SUCCESS;
|
||||
uwatec_smart_device_t *device = (uwatec_smart_device_t*) abstract;
|
||||
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||
|
||||
// Close the device.
|
||||
rc = dc_iostream_close (device->iostream);
|
||||
if (status != DC_STATUS_SUCCESS) {
|
||||
dc_status_set_error(&status, rc);
|
||||
}
|
||||
|
||||
return status;
|
||||
// Close the device and pass up the return code.
|
||||
return dc_iostream_close (device->iostream);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -886,15 +886,15 @@ uwatec_smart_fixsignbit (unsigned int x, unsigned int n)
|
||||
return 0;
|
||||
|
||||
unsigned int signbit = (1 << (n - 1));
|
||||
unsigned int mask = (0xFFFFFFFF << n);
|
||||
unsigned int mask = (signbit - 1);
|
||||
|
||||
// When turning a two's-complement number with a certain number
|
||||
// of bits into one with more bits, the sign bit must be repeated
|
||||
// in all the extra bits.
|
||||
if ((x & signbit) == signbit)
|
||||
return x | mask;
|
||||
return x | ~mask;
|
||||
else
|
||||
return x & ~mask;
|
||||
return x & mask;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user