Преглед изворни кода

Fix overflow of raw values < 0

- Rewrite of all clamp operations
- Get rid of unreachable code (the 'else' in the last chunk)
Abdullah ibn Nadjo пре 6 година
родитељ
комит
fa2fba14a6
3 измењених фајлова са 43 додато и 35 уклоњено
  1. 7
    2
      include/helpers.h
  2. 17
    4
      src/helpers.c
  3. 19
    29
      src/light.c

+ 7
- 2
include/helpers.h Прегледај датотеку

@@ -84,8 +84,13 @@ LIGHT_BOOL light_isWritable(char const * filename);
84 84
 /* Returns TRUE if file is readable, FALSE otherwise */
85 85
 LIGHT_BOOL light_isReadable(char const * filename);
86 86
 
87
-double light_logInfClamp(double x);
87
+/* Clamps the `percent` value between 0% and 100% */
88
+double light_clampPercent(double percent);
88 89
 
89
-double light_logSupClamp(double x);
90
+/* Prints a notice about a value which was below `x` and was adjusted to it */
91
+unsigned long light_logInfClamp(unsigned long x);
92
+
93
+/* Prints a notice about a value which was above `x` and was adjusted to it */
94
+unsigned long light_logSupClamp(unsigned long x);
90 95
 
91 96
 #endif /* LIGHT_HELPERS_H */

+ 17
- 4
src/helpers.c Прегледај датотеку

@@ -208,14 +208,27 @@ LIGHT_BOOL light_isReadable(char const * filename)
208 208
   return TRUE;
209 209
 }
210 210
 
211
-double light_logInfClamp(double x)
211
+unsigned long light_logInfClamp(unsigned long x)
212 212
 {
213
-  LIGHT_NOTE_FMT("specified value is inferior to %g, so adjusting it to this mininum value", x);
213
+  LIGHT_NOTE_FMT("specified value is inferior to %lu (raw), so adjusting it to this mininum value", x);
214 214
   return x;
215 215
 }
216 216
 
217
-double light_logSupClamp(double x)
217
+unsigned long light_logSupClamp(unsigned long x)
218 218
 {
219
-  LIGHT_NOTE_FMT("specified value is superior to %g, so adjusting it to this maximum value", x);
219
+  LIGHT_NOTE_FMT("specified value is superior to %lu (raw), so adjusting it to this maximum value", x);
220 220
   return x;
221 221
 }
222
+
223
+double light_clampPercent(double p)
224
+{
225
+  if(p < 0.0)
226
+  {
227
+    LIGHT_WARN_FMT("specified value %g%% is not valid, adjusting it to 0%%", p);
228
+    return 0.0;
229
+  }else if(p > 100.0){
230
+    LIGHT_WARN_FMT("specified value %g%% is not valid, adjusting it to 100%%", p);
231
+    return 100.0;
232
+  }
233
+  return p;
234
+}

+ 19
- 29
src/light.c Прегледај датотеку

@@ -227,7 +227,7 @@ LIGHT_BOOL light_parseArguments(int argc, char** argv)
227 227
         light_printHelp();
228 228
         return FALSE;
229 229
       }
230
-      light_Configuration.specifiedValuePercent = LIGHT_CLAMP(light_Configuration.specifiedValuePercent, 0.00, 100.00);
230
+      light_Configuration.specifiedValuePercent = light_clampPercent(light_Configuration.specifiedValuePercent);
231 231
     }else{
232 232
       if(sscanf(argv[optind], "%lu", &light_Configuration.specifiedValueRaw) != 1){
233 233
         fprintf(stderr, "<value> is not specified in a recognizable format.\n\n");
@@ -423,7 +423,6 @@ LIGHT_BOOL light_execute()
423 423
   unsigned long   minCap; /* The minimum cap, in raw units */
424 424
   double   percentMinCap; /* The minimum cap, in percent */
425 425
   LIGHT_BOOL   hasMinCap; /* If we have a minimum cap     */
426
-  unsigned long writeVal;
427 426
 
428 427
   LIGHT_VAL_MODE valueMode;
429 428
 
@@ -432,16 +431,14 @@ LIGHT_BOOL light_execute()
432 431
     return TRUE;
433 432
   }
434 433
 
435
-  /* -- First, get the current, min and max values directly from controller/configuration (raw values) */
436 434
   if(!light_initExecution(&rawCurr, &rawMax, &hasMinCap, &minCap))
437 435
   {
438 436
     return FALSE;
439 437
   }
440 438
 
441
-  /* -- Secondly, calculate the rest of the values (Clamp them here as well!) */
442 439
   valueMode = light_Configuration.valueMode;
443
-  percentCurr = LIGHT_CLAMP( ((double)rawCurr) /  ((double)rawMax) * 100 , 0.00, 100.00 );
444
-  percentMinCap = LIGHT_CLAMP( ((double)minCap) / ((double)rawMax) * 100 , 0.00, 100.00 );
440
+  percentCurr =   light_clampPercent(((double)rawCurr) / ((double)rawMax) * 100);
441
+  percentMinCap = light_clampPercent(((double)minCap)  / ((double)rawMax) * 100);
445 442
 
446 443
   LIGHT_NOTE_FMT("executing light on '%s' controller", light_Configuration.specifiedController);
447 444
 
@@ -489,14 +486,14 @@ LIGHT_BOOL light_execute()
489 486
      light_Configuration.operationMode == LIGHT_ADD ||
490 487
      light_Configuration.operationMode == LIGHT_SUB)
491 488
   {
489
+    unsigned long specValueRaw = valueMode == LIGHT_RAW ?
490
+      light_Configuration.specifiedValueRaw :
491
+      (unsigned long) ( (light_Configuration.specifiedValuePercent * ((double)rawMax)) / 100.0);
492
+
492 493
     if(light_Configuration.field == LIGHT_MIN_CAP)
493 494
     {
494 495
       /* Handle minimum cap files */
495
-      writeVal = valueMode == LIGHT_RAW ?
496
-        LIGHT_CLAMP( light_Configuration.specifiedValueRaw, 0, rawMax ) :
497
-        LIGHT_CLAMP(((unsigned long) (light_Configuration.specifiedValuePercent * ((double)rawMax) ) / 100), 0, rawMax);
498
-
499
-      if(!light_setMinCap(light_Configuration.specifiedController, writeVal))
496
+      if(!light_setMinCap(light_Configuration.specifiedController, LIGHT_CLAMP(specValueRaw, 0, rawMax)))
500 497
       {
501 498
         LIGHT_ERR("could not set minimum cap");
502 499
         return FALSE;
@@ -507,27 +504,25 @@ LIGHT_BOOL light_execute()
507 504
 
508 505
     }else if(light_Configuration.field == LIGHT_BRIGHTNESS){
509 506
       /* Handle brightness writing */
507
+      unsigned long writeVal;
510 508
 
511 509
       switch(light_Configuration.operationMode)
512 510
       {
513 511
         case LIGHT_SET:
514
-          writeVal = valueMode == LIGHT_RAW ?
515
-            LIGHT_CLAMP( light_Configuration.specifiedValueRaw , minCap, rawMax ) :
516
-            LIGHT_CLAMP( ((unsigned long) (light_Configuration.specifiedValuePercent * ((double)rawMax) ) / 100) , minCap, rawMax );
512
+          writeVal = LIGHT_CLAMP(specValueRaw, minCap, rawMax);
517 513
           break;
518 514
         case LIGHT_ADD:
519
-          writeVal = valueMode == LIGHT_RAW ?
520
-            LIGHT_CLAMP( rawCurr + light_Configuration.specifiedValueRaw , minCap, rawMax ) :
521
-            LIGHT_CLAMP( ((unsigned long) ( (percentCurr + light_Configuration.specifiedValuePercent) * ((double)rawMax)) / 100) , minCap, rawMax );
515
+          writeVal = LIGHT_CLAMP(rawCurr + specValueRaw, minCap, rawMax);
522 516
           break;
523 517
         case LIGHT_SUB:
524
-         if(light_Configuration.specifiedValueRaw > rawCurr){
525
-           writeVal = LIGHT_CLAMP(0, minCap, rawMax);
526
-         }else{
527
-          writeVal = valueMode == LIGHT_RAW ?
528
-            LIGHT_CLAMP( rawCurr - light_Configuration.specifiedValueRaw , minCap, rawMax ):
529
-            LIGHT_CLAMP( ((unsigned long) ( (percentCurr - light_Configuration.specifiedValuePercent) * ((double)rawMax)) / 100) , minCap, rawMax );
530
-         }
518
+          /* check if we're going below 0, which wouldn't work with unsigned values */
519
+          if(rawCurr < specValueRaw)
520
+          {
521
+            light_logInfClamp(minCap);
522
+            writeVal = minCap;
523
+            break;
524
+          }
525
+          writeVal = LIGHT_CLAMP(rawCurr - specValueRaw, minCap, rawMax);
531 526
          break;
532 527
         /* we have already taken other possibilities, so we shouldn't get here */
533 528
         default:
@@ -543,11 +538,6 @@ LIGHT_BOOL light_execute()
543 538
 
544 539
       /* All good? return true. */
545 540
       return TRUE;
546
-
547
-    }else{
548
-      /* If we didn't provide a valid field for write operations, fail. */
549
-      fprintf(stderr, "set/add/subtract operations are only available for brightness and minimum cap files.\n");
550
-      return FALSE;
551 541
     }
552 542
   }
553 543