|
@@ -333,6 +333,9 @@ int fetch_setting ( struct settings *settings, struct setting *setting,
|
333
|
333
|
struct settings *child;
|
334
|
334
|
int ret;
|
335
|
335
|
|
|
336
|
+ /* Avoid returning uninitialised data on error */
|
|
337
|
+ memset ( data, 0, len );
|
|
338
|
+
|
336
|
339
|
/* NULL settings implies starting at the global settings root */
|
337
|
340
|
if ( ! settings )
|
338
|
341
|
settings = &settings_root;
|
|
@@ -381,7 +384,6 @@ int fetch_setting_len ( struct settings *settings, struct setting *setting ) {
|
381
|
384
|
*/
|
382
|
385
|
int fetch_string_setting ( struct settings *settings, struct setting *setting,
|
383
|
386
|
char *data, size_t len ) {
|
384
|
|
- memset ( data, 0, len );
|
385
|
387
|
return fetch_setting ( settings, setting, data,
|
386
|
388
|
( ( len > 0 ) ? ( len - 1 ) : 0 ) );
|
387
|
389
|
}
|
|
@@ -417,20 +419,23 @@ int fetch_ipv4_setting ( struct settings *settings, struct setting *setting,
|
417
|
419
|
int fetch_int_setting ( struct settings *settings, struct setting *setting,
|
418
|
420
|
long *value ) {
|
419
|
421
|
union {
|
420
|
|
- long value;
|
421
|
422
|
uint8_t u8[ sizeof ( long ) ];
|
422
|
423
|
int8_t s8[ sizeof ( long ) ];
|
423
|
424
|
} buf;
|
424
|
425
|
int len;
|
425
|
426
|
int i;
|
426
|
427
|
|
427
|
|
- buf.value = 0;
|
|
428
|
+ /* Avoid returning uninitialised data on error */
|
|
429
|
+ *value = 0;
|
|
430
|
+
|
|
431
|
+ /* Fetch raw (network-ordered, variable-length) setting */
|
428
|
432
|
len = fetch_setting ( settings, setting, &buf, sizeof ( buf ) );
|
429
|
433
|
if ( len < 0 )
|
430
|
434
|
return len;
|
431
|
435
|
if ( len > ( int ) sizeof ( buf ) )
|
432
|
436
|
return -ERANGE;
|
433
|
437
|
|
|
438
|
+ /* Convert to host-ordered signed long */
|
434
|
439
|
*value = ( ( buf.s8[0] >= 0 ) ? 0 : -1L );
|
435
|
440
|
for ( i = 0 ; i < len ; i++ ) {
|
436
|
441
|
*value = ( ( *value << 8 ) | buf.u8[i] );
|
|
@@ -452,10 +457,15 @@ int fetch_uint_setting ( struct settings *settings, struct setting *setting,
|
452
|
457
|
long svalue;
|
453
|
458
|
int len;
|
454
|
459
|
|
|
460
|
+ /* Avoid returning uninitialised data on error */
|
|
461
|
+ *value = 0;
|
|
462
|
+
|
|
463
|
+ /* Fetch as a signed long */
|
455
|
464
|
len = fetch_int_setting ( settings, setting, &svalue );
|
456
|
465
|
if ( len < 0 )
|
457
|
466
|
return len;
|
458
|
467
|
|
|
468
|
+ /* Mask off sign-extended bits */
|
459
|
469
|
*value = ( svalue & ( -1UL >> ( sizeof ( long ) - len ) ) );
|
460
|
470
|
|
461
|
471
|
return len;
|
|
@@ -469,7 +479,7 @@ int fetch_uint_setting ( struct settings *settings, struct setting *setting,
|
469
|
479
|
* @ret value Setting value, or zero
|
470
|
480
|
*/
|
471
|
481
|
long fetch_intz_setting ( struct settings *settings, struct setting *setting ){
|
472
|
|
- long value = 0;
|
|
482
|
+ long value;
|
473
|
483
|
|
474
|
484
|
fetch_int_setting ( settings, setting, &value );
|
475
|
485
|
return value;
|
|
@@ -484,7 +494,7 @@ long fetch_intz_setting ( struct settings *settings, struct setting *setting ){
|
484
|
494
|
*/
|
485
|
495
|
unsigned long fetch_uintz_setting ( struct settings *settings,
|
486
|
496
|
struct setting *setting ) {
|
487
|
|
- unsigned long value = 0;
|
|
497
|
+ unsigned long value;
|
488
|
498
|
|
489
|
499
|
fetch_uint_setting ( settings, setting, &value );
|
490
|
500
|
return value;
|