Commit 7211daa8 authored by Mark Valence's avatar Mark Valence
Browse files

Fixed whitespace prefix checks. Added UTC Time and Generalized Time s

yntax validation and normalization routines.
parent 9c7127cd
......@@ -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' )",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment