Browse Source

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 7 years ago
parent
commit
fa2fba14a6
3 changed files with 43 additions and 35 deletions
  1. 7
    2
      include/helpers.h
  2. 17
    4
      src/helpers.c
  3. 19
    29
      src/light.c

+ 7
- 2
include/helpers.h View File

84
 /* Returns TRUE if file is readable, FALSE otherwise */
84
 /* Returns TRUE if file is readable, FALSE otherwise */
85
 LIGHT_BOOL light_isReadable(char const * filename);
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
 #endif /* LIGHT_HELPERS_H */
96
 #endif /* LIGHT_HELPERS_H */

+ 17
- 4
src/helpers.c View File

208
   return TRUE;
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
   return x;
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
   return x;
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 View File

227
         light_printHelp();
227
         light_printHelp();
228
         return FALSE;
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
     }else{
231
     }else{
232
       if(sscanf(argv[optind], "%lu", &light_Configuration.specifiedValueRaw) != 1){
232
       if(sscanf(argv[optind], "%lu", &light_Configuration.specifiedValueRaw) != 1){
233
         fprintf(stderr, "<value> is not specified in a recognizable format.\n\n");
233
         fprintf(stderr, "<value> is not specified in a recognizable format.\n\n");
423
   unsigned long   minCap; /* The minimum cap, in raw units */
423
   unsigned long   minCap; /* The minimum cap, in raw units */
424
   double   percentMinCap; /* The minimum cap, in percent */
424
   double   percentMinCap; /* The minimum cap, in percent */
425
   LIGHT_BOOL   hasMinCap; /* If we have a minimum cap     */
425
   LIGHT_BOOL   hasMinCap; /* If we have a minimum cap     */
426
-  unsigned long writeVal;
427
 
426
 
428
   LIGHT_VAL_MODE valueMode;
427
   LIGHT_VAL_MODE valueMode;
429
 
428
 
432
     return TRUE;
431
     return TRUE;
433
   }
432
   }
434
 
433
 
435
-  /* -- First, get the current, min and max values directly from controller/configuration (raw values) */
436
   if(!light_initExecution(&rawCurr, &rawMax, &hasMinCap, &minCap))
434
   if(!light_initExecution(&rawCurr, &rawMax, &hasMinCap, &minCap))
437
   {
435
   {
438
     return FALSE;
436
     return FALSE;
439
   }
437
   }
440
 
438
 
441
-  /* -- Secondly, calculate the rest of the values (Clamp them here as well!) */
442
   valueMode = light_Configuration.valueMode;
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
   LIGHT_NOTE_FMT("executing light on '%s' controller", light_Configuration.specifiedController);
443
   LIGHT_NOTE_FMT("executing light on '%s' controller", light_Configuration.specifiedController);
447
 
444
 
489
      light_Configuration.operationMode == LIGHT_ADD ||
486
      light_Configuration.operationMode == LIGHT_ADD ||
490
      light_Configuration.operationMode == LIGHT_SUB)
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
     if(light_Configuration.field == LIGHT_MIN_CAP)
493
     if(light_Configuration.field == LIGHT_MIN_CAP)
493
     {
494
     {
494
       /* Handle minimum cap files */
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
         LIGHT_ERR("could not set minimum cap");
498
         LIGHT_ERR("could not set minimum cap");
502
         return FALSE;
499
         return FALSE;
507
 
504
 
508
     }else if(light_Configuration.field == LIGHT_BRIGHTNESS){
505
     }else if(light_Configuration.field == LIGHT_BRIGHTNESS){
509
       /* Handle brightness writing */
506
       /* Handle brightness writing */
507
+      unsigned long writeVal;
510
 
508
 
511
       switch(light_Configuration.operationMode)
509
       switch(light_Configuration.operationMode)
512
       {
510
       {
513
         case LIGHT_SET:
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
           break;
513
           break;
518
         case LIGHT_ADD:
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
           break;
516
           break;
523
         case LIGHT_SUB:
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
          break;
526
          break;
532
         /* we have already taken other possibilities, so we shouldn't get here */
527
         /* we have already taken other possibilities, so we shouldn't get here */
533
         default:
528
         default:
543
 
538
 
544
       /* All good? return true. */
539
       /* All good? return true. */
545
       return TRUE;
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