From 7211daa8374b3ab207bba506055a01bdb16988a6 Mon Sep 17 00:00:00 2001 From: Mark Valence Date: Thu, 15 Jun 2000 07:58:04 +0000 Subject: [PATCH] Fixed whitespace prefix checks. Added UTC Time and Generalized Time s yntax validation and normalization routines. --- servers/slapd/schema_init.c | 254 ++++++++++++++++++++++++++++++++++-- 1 file changed, 246 insertions(+), 8 deletions(-) diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index e604cf4a61..d9b95d194c 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -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' )", -- 2.39.5