LCOV - code coverage report
Current view: top level - src/plugins/validation - validation.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 70 86 81.4 %
Date: 2019-09-12 12:28:41 Functions: 4 5 80.0 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  */
       8             : 
       9             : #ifndef HAVE_KDBCONFIG
      10             : #include "kdbconfig.h"
      11             : #endif
      12             : 
      13             : #include <ctype.h>
      14             : #include <stdio.h>
      15             : #include <stdlib.h>
      16             : #include <string.h>
      17             : 
      18             : #include "validation.h"
      19             : 
      20             : static int validateKey (Key *, Key *);
      21             : 
      22          61 : int elektraValidationGet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey ELEKTRA_UNUSED)
      23             : {
      24             :         KeySet * n;
      25          61 :         ksAppend (returned,
      26          61 :                   n = ksNew (30,
      27             :                              keyNew ("system/elektra/modules/validation", KEY_VALUE, "validation plugin waits for your orders", KEY_END),
      28             :                              keyNew ("system/elektra/modules/validation/exports", KEY_END),
      29             :                              keyNew ("system/elektra/modules/validation/exports/get", KEY_FUNC, elektraValidationGet, KEY_END),
      30             :                              keyNew ("system/elektra/modules/validation/exports/set", KEY_FUNC, elektraValidationSet, KEY_END),
      31             :                              keyNew ("system/elektra/modules/validation/exports/ksLookupRE", KEY_FUNC, ksLookupRE, KEY_END),
      32             :                              keyNew ("system/elektra/modules/validation/exports/validateKey", KEY_FUNC, validateKey, KEY_END),
      33             : #include "readme_validation.c"
      34             :                              keyNew ("system/elektra/modules/validation/infos/version", KEY_VALUE, PLUGINVERSION, KEY_END), KS_END));
      35          61 :         ksDel (n);
      36          61 :         return 1;
      37             : }
      38             : 
      39          36 : static int validateKey (Key * key, Key * parentKey)
      40             : {
      41          36 :         const Key * regexMeta = keyGetMeta (key, "check/validation");
      42             : 
      43          36 :         const Key * icaseMeta = keyGetMeta (key, "check/validation/ignorecase");
      44          36 :         const Key * matchMeta = keyGetMeta (key, "check/validation/match");
      45          36 :         const Key * invertMeta = keyGetMeta (key, "check/validation/invert");
      46          36 :         const Key * typeMeta = keyGetMeta (key, "check/validation/type");
      47             : 
      48          36 :         int lineValidation = 0;
      49          36 :         int wordValidation = 0;
      50          36 :         int icaseValidation = 0;
      51          36 :         int invertValidation = 0;
      52             : 
      53          36 :         if (icaseMeta) icaseValidation = 1;
      54          36 :         if (invertMeta) invertValidation = 1;
      55          36 :         if (matchMeta)
      56             :         {
      57          32 :                 char * matchCopy = elektraStrDup (keyString (matchMeta));
      58          32 :                 char * ptr = matchCopy;
      59         192 :                 while (*ptr)
      60             :                 {
      61         128 :                         *ptr = toupper (*ptr);
      62         128 :                         ++ptr;
      63             :                 }
      64          32 :                 if (!strcmp (matchCopy, "LINE")) lineValidation = 1;
      65          32 :                 if (!strcmp (matchCopy, "WORD")) wordValidation = 1;
      66          32 :                 if (!strcmp (matchCopy, "ANY"))
      67             :                 {
      68           0 :                         lineValidation = 0;
      69           0 :                         wordValidation = 0;
      70             :                 }
      71          32 :                 elektraFree (matchCopy);
      72             :         }
      73             : 
      74          36 :         int cflags = REG_NOSUB | REG_EXTENDED;
      75          36 :         if (icaseValidation) cflags |= REG_ICASE;
      76          36 :         if (lineValidation) cflags |= REG_NEWLINE;
      77          36 :         if (typeMeta)
      78             :         {
      79           0 :                 char * typeCopy = elektraStrDup (keyString (typeMeta));
      80           0 :                 char * ptr = typeCopy;
      81           0 :                 while (*ptr)
      82             :                 {
      83           0 :                         *ptr = toupper (*ptr);
      84           0 :                         ++ptr;
      85             :                 }
      86           0 :                 if (!strcmp (typeCopy, "ERE"))
      87           0 :                         cflags |= REG_EXTENDED;
      88           0 :                 else if (!strcmp (typeCopy, "BRE"))
      89           0 :                         cflags &= REG_EXTENDED;
      90           0 :                 elektraFree (typeCopy);
      91             :         }
      92             : 
      93          36 :         char * regexString = NULL;
      94          36 :         int freeString = 0;
      95          36 :         if (lineValidation || wordValidation)
      96             :         {
      97          32 :                 regexString = elektraMalloc (keyGetValueSize (regexMeta) + 2);
      98          32 :                 freeString = 1;
      99          32 :                 sprintf (regexString, "^%s$", keyString (regexMeta));
     100             :         }
     101             :         else
     102             :         {
     103           4 :                 regexString = (char *) keyString (regexMeta);
     104             :         }
     105             : 
     106             :         regex_t regex;
     107             :         regmatch_t offsets;
     108          36 :         int ret = regcomp (&regex, regexString, cflags);
     109             : 
     110          36 :         if (ret != 0)
     111             :         {
     112             :                 char buffer[1000];
     113           0 :                 regerror (ret, &regex, buffer, 999);
     114           0 :                 ELEKTRA_SET_VALIDATION_SYNTACTIC_ERRORF (parentKey, "Could not compile regex. Reason: %s", buffer);
     115           0 :                 regfree (&regex);
     116           0 :                 if (freeString) elektraFree (regexString);
     117             :                 return 0;
     118             :         }
     119          36 :         int match = 0;
     120          36 :         if (!wordValidation)
     121             :         {
     122          20 :                 ret = regexec (&regex, keyString (key), 1, &offsets, 0);
     123          20 :                 if (ret == 0) match = 1;
     124             :         }
     125             :         else
     126             :         {
     127             :                 char * savePtr;
     128             :                 char * token;
     129          16 :                 char * string = (char *) keyString (key);
     130          52 :                 while ((token = strtok_r (string, " \t\n", &savePtr)) != NULL)
     131             :                 {
     132          28 :                         ret = regexec (&regex, token, 1, &offsets, 0);
     133          28 :                         if (ret == 0)
     134             :                         {
     135             :                                 match = 1;
     136             :                                 break;
     137             :                         }
     138             :                         string = NULL;
     139             :                 }
     140             :         }
     141          36 :         if (invertValidation) match = !match;
     142             : 
     143          36 :         if (!match)
     144             :         {
     145          14 :                 const Key * msg = keyGetMeta (key, "check/validation/message");
     146          14 :                 if (msg)
     147             :                 {
     148           2 :                         ELEKTRA_SET_VALIDATION_SYNTACTIC_ERRORF (parentKey, "Key value failed to validate. Reason: %s", keyString (msg));
     149           2 :                         regfree (&regex);
     150           2 :                         if (freeString) elektraFree (regexString);
     151             :                         return 0;
     152             :                 }
     153             :                 else
     154             :                 {
     155             :                         char buffer[1000];
     156          12 :                         regerror (ret, &regex, buffer, 999);
     157          12 :                         ELEKTRA_SET_VALIDATION_SYNTACTIC_ERRORF (parentKey, "Key value failed to validate. Reason: %s", buffer);
     158          12 :                         regfree (&regex);
     159          12 :                         if (freeString) elektraFree (regexString);
     160             :                         return 0;
     161             :                 }
     162             :         }
     163             : 
     164          22 :         regfree (&regex);
     165          22 :         if (freeString) elektraFree (regexString);
     166             :         return 1;
     167             : }
     168             : 
     169          37 : int elektraValidationSet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey)
     170             : {
     171          37 :         Key * cur = 0;
     172             : 
     173          97 :         while ((cur = ksNext (returned)) != 0)
     174             :         {
     175          37 :                 const Key * regexMeta = keyGetMeta (cur, "check/validation");
     176             : 
     177          37 :                 if (!regexMeta) continue;
     178          36 :                 int rc = validateKey (cur, parentKey);
     179          36 :                 if (!rc) return -1;
     180             :         }
     181             : 
     182             :         return 1; /* success */
     183             : }
     184             : 
     185         161 : Plugin * ELEKTRA_PLUGIN_EXPORT
     186             : {
     187             :         // clang-format off
     188         161 :         return elektraPluginExport("validation",
     189             :                         ELEKTRA_PLUGIN_GET,     &elektraValidationGet,
     190             :                         ELEKTRA_PLUGIN_SET,     &elektraValidationSet,
     191             :                         ELEKTRA_PLUGIN_END);
     192             : }
     193             : 

Generated by: LCOV version 1.13