@@ -271,7 +271,7 @@ static int _apc_modbus_double_to_nut(const apc_modbus_value_t *value, char *outp
271
271
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
272
272
#pragma GCC diagnostic pop
273
273
#endif
274
- if (res < 0 || (size_t )res > output_len ) {
274
+ if (res < 0 || (size_t )res >= output_len ) {
275
275
return 0 ;
276
276
}
277
277
@@ -314,7 +314,7 @@ static int _apc_modbus_power_to_nut(const apc_modbus_value_t *value, char *outpu
314
314
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
315
315
#pragma GCC diagnostic pop
316
316
#endif
317
- if (res < 0 || (size_t )res > output_len ) {
317
+ if (res < 0 || (size_t )res >= output_len ) {
318
318
return 0 ;
319
319
}
320
320
@@ -325,6 +325,8 @@ static apc_modbus_converter_t _apc_modbus_power_conversion = { _apc_modbus_power
325
325
326
326
static int _apc_modbus_voltage_to_nut (const apc_modbus_value_t * value , char * output , size_t output_len )
327
327
{
328
+ int res ;
329
+
328
330
if (value == NULL || output == NULL || output_len == 0 ) {
329
331
/* Invalid parameters */
330
332
return 0 ;
@@ -336,7 +338,10 @@ static int _apc_modbus_voltage_to_nut(const apc_modbus_value_t *value, char *out
336
338
337
339
if (value -> data .uint_value == 0xffff ) {
338
340
/* Not applicable */
339
- strncpy (output , "NA" , output_len );
341
+ res = snprintf (output , output_len , "NA" );
342
+ if (res < 0 || (size_t )res >= output_len ) {
343
+ return 0 ;
344
+ }
340
345
return 1 ;
341
346
}
342
347
@@ -348,6 +353,7 @@ static apc_modbus_converter_t _apc_modbus_voltage_conversion = { _apc_modbus_vol
348
353
static int _apc_modbus_efficiency_to_nut (const apc_modbus_value_t * value , char * output , size_t output_len )
349
354
{
350
355
char * cause ;
356
+ int res ;
351
357
352
358
if (value == NULL || output == NULL || output_len == 0 ) {
353
359
/* Invalid parameters */
@@ -387,7 +393,10 @@ static int _apc_modbus_efficiency_to_nut(const apc_modbus_value_t *value, char *
387
393
return _apc_modbus_double_to_nut (value , output , output_len );
388
394
}
389
395
390
- strncpy (output , cause , output_len );
396
+ res = snprintf (output , output_len , "%s" , cause );
397
+ if (res < 0 || (size_t )res >= output_len ) {
398
+ return 0 ;
399
+ }
391
400
392
401
return 1 ;
393
402
}
@@ -397,6 +406,7 @@ static apc_modbus_converter_t _apc_modbus_efficiency_conversion = { _apc_modbus_
397
406
static int _apc_modbus_status_change_cause_to_nut (const apc_modbus_value_t * value , char * output , size_t output_len )
398
407
{
399
408
char * cause ;
409
+ int res ;
400
410
401
411
if (value == NULL || output == NULL || output_len == 0 ) {
402
412
/* Invalid parameters */
@@ -506,7 +516,10 @@ static int _apc_modbus_status_change_cause_to_nut(const apc_modbus_value_t *valu
506
516
break ;
507
517
}
508
518
509
- strncpy (output , cause , output_len );
519
+ res = snprintf (output , output_len , "%s" , cause );
520
+ if (res < 0 || (size_t )res >= output_len ) {
521
+ return 0 ;
522
+ }
510
523
511
524
return 1 ;
512
525
}
@@ -1014,6 +1027,7 @@ static void _apc_modbus_usb_lib_to_nut(const modbus_usb_device_t *device, USBDev
1014
1027
/* This makes a USBDevice_t from modbus_usb_device_t so we can use our matchers */
1015
1028
1016
1029
static char bus_buf [4 ], device_buf [4 ], bus_port_buf [4 ];
1030
+ int res ;
1017
1031
1018
1032
assert (device != NULL );
1019
1033
assert (out != NULL );
@@ -1027,14 +1041,23 @@ static void _apc_modbus_usb_lib_to_nut(const modbus_usb_device_t *device, USBDev
1027
1041
out -> Serial = device -> serial_str ;
1028
1042
out -> bcdDevice = device -> bcd_device ;
1029
1043
1030
- snprintf (bus_buf , sizeof (bus_buf ), "%03u" , device -> bus );
1044
+ res = snprintf (bus_buf , sizeof (bus_buf ), "%03u" , device -> bus );
1045
+ if (res < 0 || (size_t )res >= sizeof (bus_buf )) {
1046
+ fatalx (EXIT_FAILURE , "failed to convert USB bus to string" );
1047
+ }
1031
1048
out -> Bus = bus_buf ;
1032
1049
1033
- snprintf (device_buf , sizeof (device_buf ), "%03u" , device -> device_address );
1050
+ res = snprintf (device_buf , sizeof (device_buf ), "%03u" , device -> device_address );
1051
+ if (res < 0 || (size_t )res >= sizeof (device_buf )) {
1052
+ fatalx (EXIT_FAILURE , "failed to convert USB device address to string" );
1053
+ }
1034
1054
out -> Device = device_buf ;
1035
1055
1036
1056
#if (defined WITH_USB_BUSPORT ) && (WITH_USB_BUSPORT )
1037
- snprintf (bus_port_buf , sizeof (bus_port_buf ), "%03u" , device -> bus_port );
1057
+ res = snprintf (bus_port_buf , sizeof (bus_port_buf ), "%03u" , device -> bus_port );
1058
+ if (res < 0 || (size_t )res >= sizeof (bus_port_buf )) {
1059
+ fatalx (EXIT_FAILURE , "failed to convert USB bus port to string" );
1060
+ }
1038
1061
out -> BusPort = bus_port_buf ;
1039
1062
#endif
1040
1063
}
@@ -1118,7 +1141,7 @@ static int _apc_modbus_usb_callback(const modbus_usb_device_t *device)
1118
1141
static int _apc_modbus_parse_host_port (const char * input , char * host , size_t host_buf_size , char * port , size_t port_buf_size , const uint16_t default_port ) {
1119
1142
const char * start = input ;
1120
1143
const char * end = input ;
1121
- int port_int ;
1144
+ int port_int , r ;
1122
1145
size_t host_size , port_size ;
1123
1146
1124
1147
if (* start == '[' ) {
@@ -1134,21 +1157,30 @@ static int _apc_modbus_parse_host_port(const char *input, char *host, size_t hos
1134
1157
1135
1158
if (!end ) {
1136
1159
/* Port is missing, use the default port */
1137
- strncpy (host , start , host_buf_size );
1138
- snprintf (port , port_buf_size , "%u" , default_port );
1139
- return 0 ;
1160
+ r = snprintf (host , host_buf_size , "%s" , start );
1161
+ if (r < 0 || (size_t )r >= host_buf_size ) {
1162
+ upslogx (LOG_ERR , "%s: Buffer size too small or encoding error" , __func__ );
1163
+ return 0 ;
1164
+ }
1165
+ r = snprintf (port , port_buf_size , "%u" , default_port );
1166
+ if (r < 0 || (size_t )r >= port_buf_size ) {
1167
+ upslogx (LOG_ERR , "%s: Buffer size too small or encoding error" , __func__ );
1168
+ return 0 ;
1169
+ }
1170
+ return 1 ;
1140
1171
}
1141
1172
1142
- host_size = (size_t )(end - start );
1143
- port_size = strlen (end + 1 );
1173
+ /* +1 for zero termination */
1174
+ host_size = (size_t )(end - start ) + 1 ;
1175
+ port_size = strlen (end + 1 ) + 1 ;
1144
1176
1145
- if (host_size >= host_buf_size || port_size >= port_buf_size ) {
1177
+ if (host_size > host_buf_size || port_size > port_buf_size ) {
1146
1178
upslogx (LOG_ERR , "%s: Buffer size too small" , __func__ );
1147
1179
return 0 ;
1148
1180
}
1149
1181
1150
- strncpy (host , start , host_size );
1151
- strncpy (port , end + 1 , port_size );
1182
+ snprintf (host , host_size , "%s" , start );
1183
+ snprintf (port , port_size , "%s" , end + 1 );
1152
1184
1153
1185
port_int = atoi (port );
1154
1186
if (port_int < 0 || port_int > 65535 ) {
@@ -1221,6 +1253,7 @@ void upsdrv_initups(void)
1221
1253
for (i = 0 ; i < sizeof (regex_array ) / sizeof (regex_array [0 ]); i ++ ) {
1222
1254
if (regex_array [i ] != NULL ) {
1223
1255
has_nonzero_regex = 1 ;
1256
+ break ;
1224
1257
}
1225
1258
}
1226
1259
0 commit comments