]> git.sur5r.net Git - openldap/commitdiff
Fixed whitespace prefix checks. Added UTC Time and Generalized Time s
authorMark Valence <mrv@openldap.org>
Thu, 15 Jun 2000 07:58:04 +0000 (07:58 +0000)
committerMark Valence <mrv@openldap.org>
Thu, 15 Jun 2000 07:58:04 +0000 (07:58 +0000)
yntax validation and normalization routines.

servers/slapd/schema_init.c

index e604cf4a61057f45149bc050e1d71a63c5c66ecd..d9b95d194c8f835c5d840d77699b48845bdcf197 100644 (file)
@@ -453,8 +453,8 @@ IA5StringNormalize(
        p = val->bv_val;
 
        /* Ignore initial whitespace */
-       while ( isspace( *p++ ) ) {
-               /* EMPTY */  ;
+       while ( isspace( *p ) ) {
+               p++;
        }
 
        if( *p != '\0' ) {
@@ -470,8 +470,8 @@ IA5StringNormalize(
                        *q++ = *p++;
 
                        /* Ignore the extra whitespace */
-                       while ( isspace( *p++ ) ) {
-                               /* EMPTY */  ;
+                       while ( isspace( *p ) ) {
+                               p++;
                        }
                } else {
                        *q++ = *p++;
@@ -900,8 +900,8 @@ NumericStringNormalize(
        p = val->bv_val;
 
        /* Ignore initial whitespace */
-       while ( isspace( *p++ ) ) {
-               /* EMPTY */  ;
+       while ( isspace( *p ) ) {
+               p++;
        }
 
        if( *p != '\0' ) {
@@ -940,6 +940,244 @@ NumericStringNormalize(
        return LDAP_SUCCESS;
 }
 
+static int
+check_time_syntax (struct berval *val,
+       int start,
+       int *parts)
+{
+       static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 };
+       static int mdays[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+       char *p, *e;
+       int part, c, neg = 0;
+
+       if( val->bv_len == 0 )
+               return LDAP_INVALID_SYNTAX;
+
+       p = (char *)val->bv_val;
+       e = p + val->bv_len;
+
+       /* Ignore initial whitespace */
+       while ( ( p < e ) && isspace( *p ) ) {
+               p++;
+       }
+
+       if (e - p < 13 - (2 * start))
+               return LDAP_INVALID_SYNTAX;
+
+       for (part = 0; part < 9; part++)
+               parts[part] = 0;
+
+       for (part = start; part < 7; part++) {
+               c = *p;
+               if ((part == 6)
+                       && (c == 'Z'
+                               || c == '+'
+                               || c == '-'))
+               {
+                       part++;
+                       break;
+               }
+               p++;
+               c -= '0';
+               if (p == e)
+                       return LDAP_INVALID_SYNTAX;
+               if (c < 0 || c > 9)
+                       return LDAP_INVALID_SYNTAX;
+               parts[part] = c;
+
+               c = *p++ - '0';
+               if (p == e)
+                       return LDAP_INVALID_SYNTAX;
+               if (c < 0 || c > 9)
+                       return LDAP_INVALID_SYNTAX;
+               parts[part] *= 10;
+               parts[part] += c;
+
+               if (part == 2 || part == 3)
+                       parts[part]--;
+               if (parts[part] < 0)
+                       return LDAP_INVALID_SYNTAX;
+               if (parts[part] > ceiling[part])
+                       return LDAP_INVALID_SYNTAX;
+       }
+       if (parts[2] == 1) {
+               if (parts[3] > mdays[parts[2]])
+                       return LDAP_INVALID_SYNTAX;
+               if (parts[1] & 0x03) {
+                       /* FIXME:  This is an incomplete leap-year
+                        * check that fails in 2100, 2200, 2300,
+                        * 2500, 2600, 2700, ...
+                        */
+                       if (parts[3] > mdays[parts[2]] - 1)
+                               return LDAP_INVALID_SYNTAX;
+               }
+       }
+       c = *p++;
+       if (c == 'Z') {
+               /* all done */
+       } else if (c != '+' && c != '-') {
+               return LDAP_INVALID_SYNTAX;
+       } else {
+               if (c == '-')
+                       neg = 1;
+               if (p > e - 4)
+                       return LDAP_INVALID_SYNTAX;
+               for (part = 7; part < 9; part++) {
+                       c = *p++ - '0';
+                       if (c < 0 || c > 9)
+                               return LDAP_INVALID_SYNTAX;
+                       parts[part] = c;
+
+                       c = *p++ - '0';
+                       if (c < 0 || c > 9)
+                               return LDAP_INVALID_SYNTAX;
+                       parts[part] *= 10;
+                       parts[part] += c;
+                       if (parts[part] < 0 || parts[part] > ceiling[part])
+                               return LDAP_INVALID_SYNTAX;
+               }
+       }
+
+       /* Ignore trailing whitespace */
+       while ( ( p < e ) && isspace( *p ) ) {
+               p++;
+       }
+       if (p != e)
+               return LDAP_INVALID_SYNTAX;
+
+       if (neg == 0) {
+               parts[4] += parts[7];
+               parts[5] += parts[8];
+               for (part = 7; --part > 0; ) {
+                       if (part != 3)
+                               c = ceiling[part];
+                       else {
+                               /* FIXME:  This is an incomplete leap-year
+                                * check that fails in 2100, 2200, 2300,
+                                * 2500, 2600, 2700, ...
+                                */
+                               c = mdays[parts[2]];
+                               if (parts[2] == 1)
+                                       c--;
+                       }
+                       if (parts[part] > c) {
+                               parts[part] -= c + 1;
+                               parts[part - 1]++;
+                       }
+               }
+       } else {
+               parts[4] -= parts[7];
+               parts[5] -= parts[8];
+               for (part = 7; --part > 0; ) {
+                       if (part != 3)
+                               c = ceiling[part];
+                       else {
+                               /* FIXME:  This is an incomplete leap-year
+                                * check that fails in 2100, 2200, 2300,
+                                * 2500, 2600, 2700, ...
+                                */
+                               c = mdays[(parts[2] - 1) % 12];
+                               if (parts[2] == 2)
+                                       c--;
+                       }
+                       if (parts[part] < 0) {
+                               parts[part] += c + 1;
+                               parts[part - 1]--;
+                       }
+               }
+       }
+
+       return LDAP_SUCCESS;
+}
+
+static int
+utcTimeNormalize(
+       Syntax *syntax,
+       struct berval *val,
+       struct berval **normalized )
+{
+       struct berval *out;
+       int parts[9], rc;
+
+       rc = check_time_syntax(val, 1, parts);
+       if (rc != LDAP_SUCCESS) {
+               return rc;
+       }
+
+       *normalized = NULL;
+       out = ch_malloc( sizeof(struct berval) );
+       if( out == NULL )
+               return LBER_ERROR_MEMORY;
+
+       out->bv_val = ch_malloc( 14 );
+       if ( out->bv_val == NULL ) {
+               ch_free( out );
+               return LBER_ERROR_MEMORY;
+       }
+
+       sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ldZ",
+                               parts[1], parts[2] + 1, parts[3] + 1,
+                               parts[4], parts[5], parts[6] );
+       out->bv_len = 13;
+       *normalized = out;
+
+       return LDAP_SUCCESS;
+}
+
+static int
+utcTimeValidate(
+       Syntax *syntax,
+       struct berval *in )
+{
+       int parts[9];
+
+       return check_time_syntax(in, 1, parts);
+}
+
+static int
+generalizedTimeNormalize(
+       Syntax *syntax,
+       struct berval *val,
+       struct berval **normalized )
+{
+       struct berval *out;
+       int parts[9], rc;
+
+       rc = check_time_syntax(val, 0, parts);
+       if (rc != LDAP_SUCCESS) {
+               return rc;
+       }
+
+       *normalized = NULL;
+       out = ch_malloc( sizeof(struct berval) );
+       if( out == NULL )
+               return LBER_ERROR_MEMORY;
+
+       out->bv_val = ch_malloc( 16 );
+       if ( out->bv_val == NULL ) {
+               ch_free( out );
+               return LBER_ERROR_MEMORY;
+       }
+
+       sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ld%02ldZ",
+                               parts[0], parts[1], parts[2] + 1, parts[3] + 1,
+                               parts[4], parts[5], parts[6] );
+       out->bv_len = 15;
+       *normalized = out;
+
+       return LDAP_SUCCESS;
+}
+
+static int
+generalizedTimeValidate(
+       Syntax *syntax,
+       struct berval *in )
+{
+       int parts[9];
+
+       return check_time_syntax(in, 0, parts);
+}
+
 struct syntax_defs_rec {
        char *sd_desc;
        int sd_flags;
@@ -1005,7 +1243,7 @@ struct syntax_defs_rec syntax_defs[] = {
        {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
                SLAP_SYNTAX_BLOB, NULL, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
-               0, NULL, NULL, NULL},
+               0, generalizedTimeValidate, generalizedTimeNormalize, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
                0, NULL, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
@@ -1056,7 +1294,7 @@ struct syntax_defs_rec syntax_defs[] = {
        {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
                0, NULL, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
-               0, NULL, NULL, NULL},
+               0, utcTimeValidate, utcTimeNormalize, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
                0, NULL, NULL, NULL},
        {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",