You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
djbdns/230-tinydns-data-semantic-e...

195 lines
5.1 KiB
Diff

--- a/tinydns-data.c
+++ b/tinydns-data.c
@@ -25,6 +25,14 @@
#define FATAL "tinydns-data: fatal: "
+void die_semantic2(const char * s1, const char * s2)
+{
+ strerr_die3x(111,FATAL,s1,s2) ;
+}
+void die_semantic4(const char * s1, const char * s2,const char * s3, const char * s4)
+{
+ strerr_die5x(111,FATAL,s1,s2,s3,s4) ;
+}
void die_datatmp(void)
{
strerr_die2sys(111,FATAL,"unable to create data.cdb.tmp: ");
@@ -34,20 +42,39 @@ void nomem(void)
strerr_die1sys(111,FATAL);
}
+void ttlparse(stralloc *sa,unsigned long * ttl, unsigned long defttl, const char * ltype)
+{
+ int ttllen ;
+
+ if (sa->len > 0) {
+ if (!stralloc_0(sa)) nomem();
+ ttllen = scan_ulong(sa->s,ttl) ;
+ if (ttllen + 1 != sa->len)
+ die_semantic4("unparseable TTL in ",ltype," line: ", sa->s) ;
+ } else
+ *ttl = defttl;
+}
+
void ttdparse(stralloc *sa,char ttd[8])
{
unsigned int i;
char ch;
byte_zero(ttd,8);
- for (i = 0;(i < 16) && (i < sa->len);++i) {
+ for (i = 0;i < sa->len;++i) {
+ if (i >= 16) {
+ if (!stralloc_0(sa)) nomem() ;
+ die_semantic2("timestamp is too long: ", sa->s) ;
+ }
ch = sa->s[i];
if ((ch >= '0') && (ch <= '9'))
ch -= '0';
else if ((ch >= 'a') && (ch <= 'f'))
ch -= 'a' - 10;
- else
- ch = 0;
+ else {
+ if (!stralloc_0(sa)) nomem() ;
+ die_semantic2("timestamp contains an invalid character: ", sa->s) ;
+ }
if (!(i & 1)) ch <<= 4;
ttd[i >> 1] |= ch;
}
@@ -55,6 +82,10 @@ void ttdparse(stralloc *sa,char ttd[8])
void locparse(stralloc *sa,char loc[2])
{
+ if (sa->len > 2) {
+ if (!stralloc_0(sa)) nomem() ;
+ die_semantic2("location code longer than two characters: ", sa->s) ;
+ }
loc[0] = (sa->len > 0) ? sa->s[0] : 0;
loc[1] = (sa->len > 1) ? sa->s[1] : 0;
}
@@ -187,6 +218,7 @@ int main()
int i;
int j;
int k;
+ int iplen ;
char ch;
unsigned long ttl;
char ttd[8];
@@ -267,8 +299,7 @@ int main()
if (!scan_ulong(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u);
uint32_pack_big(soa + 16,u);
- if (!stralloc_0(&f[8])) nomem();
- if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE;
+ ttlparse(&f[8],&ttl,TTL_NEGATIVE,"Z");
ttdparse(&f[9],ttd);
locparse(&f[10],loc);
@@ -283,8 +314,7 @@ int main()
case '.': case '&':
if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
- if (!stralloc_0(&f[3])) nomem();
- if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS;
+ ttlparse(&f[3],&ttl,TTL_NS,". or &");
ttdparse(&f[4],ttd);
locparse(&f[5],loc);
@@ -309,24 +339,26 @@ int main()
rr_addname(d2);
rr_finish(d1);
- if (ip4_scan(f[1].s,ip)) {
+ iplen = ip4_scan(f[1].s,ip) ;
+ if (iplen != 0 && iplen + 1 == f[1].len) {
rr_start(DNS_T_A,ttl,ttd,loc);
rr_add(ip,4);
rr_finish(d2);
- }
+ } else if (f[1].len > 1)
+ die_semantic4("unparseable IP address in ","& or ."," line: ", f[1].s) ;
break;
case '+': case '=':
if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
- if (!stralloc_0(&f[2])) nomem();
- if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
+ ttlparse(&f[2],&ttl,TTL_POSITIVE,"+ or =");
ttdparse(&f[3],ttd);
locparse(&f[4],loc);
if (!stralloc_0(&f[1])) nomem();
- if (ip4_scan(f[1].s,ip)) {
+ iplen = ip4_scan(f[1].s,ip) ;
+ if (iplen != 0 && iplen + 1 == f[1].len) {
rr_start(DNS_T_A,ttl,ttd,loc);
rr_add(ip,4);
rr_finish(d1);
@@ -337,13 +369,15 @@ int main()
rr_addname(d1);
rr_finish(dptr);
}
- }
+ } else if (f[1].len > 1)
+ die_semantic4("unparseable IP address in ","+ or ="," line: ", f[1].s) ;
+ else
+ die_semantic4("missing IP address in ","+ or ="," line: ", f[1].s) ;
break;
case '@':
if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
- if (!stralloc_0(&f[4])) nomem();
- if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE;
+ ttlparse(&f[4],&ttl,TTL_POSITIVE,"@");
ttdparse(&f[5],ttd);
locparse(&f[6],loc);
@@ -401,18 +435,19 @@ int main()
rr_addname(d2);
rr_finish(d1);
- if (ip4_scan(f[1].s,ip)) {
+ iplen = ip4_scan(f[1].s,ip) ;
+ if (iplen != 0 && iplen + 1 == f[1].len) {
rr_start(DNS_T_A,ttl,ttd,loc);
rr_add(ip,4);
rr_finish(d2);
- }
+ } else if (f[1].len > 1)
+ die_semantic4("unparseable IP address in ","@"," line: ", f[1].s) ;
break;
case '^': case 'C':
if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
- if (!stralloc_0(&f[2])) nomem();
- if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
+ ttlparse(&f[2],&ttl,TTL_POSITIVE,"^ or C");
ttdparse(&f[3],ttd);
locparse(&f[4],loc);
@@ -426,8 +461,7 @@ int main()
case '\'':
if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
- if (!stralloc_0(&f[2])) nomem();
- if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
+ ttlparse(&f[2],&ttl,TTL_POSITIVE,"\'");
ttdparse(&f[3],ttd);
locparse(&f[4],loc);
@@ -449,8 +483,7 @@ int main()
case ':':
if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
- if (!stralloc_0(&f[3])) nomem();
- if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_POSITIVE;
+ ttlparse(&f[3],&ttl,TTL_POSITIVE,":");
ttdparse(&f[4],ttd);
locparse(&f[5],loc);