libdisk: catch null bytes in proto file, fix memory leaks
This commit is contained in:
parent
5bb7240ee9
commit
292cce2ad1
1 changed files with 99 additions and 89 deletions
|
@ -64,6 +64,8 @@ static void domkfs(Mkaux *mkaux, File *me, int level);
|
||||||
|
|
||||||
static int copyfile(Mkaux*, File*, Dir*, int);
|
static int copyfile(Mkaux*, File*, Dir*, int);
|
||||||
static void freefile(File*);
|
static void freefile(File*);
|
||||||
|
static void freeoptptr(Opt*, void*);
|
||||||
|
static char* getline(Mkaux*);
|
||||||
static File* getfile(Mkaux*, File*);
|
static File* getfile(Mkaux*, File*);
|
||||||
static char* getmode(Mkaux*, char*, ulong*);
|
static char* getmode(Mkaux*, char*, ulong*);
|
||||||
static char* getname(Mkaux*, char*, char**);
|
static char* getname(Mkaux*, char*, char**);
|
||||||
|
@ -72,16 +74,11 @@ static int mkfile(Mkaux*, File*);
|
||||||
static char* mkpath(Mkaux*, char*, char*);
|
static char* mkpath(Mkaux*, char*, char*);
|
||||||
static void mktree(Mkaux*, File*, int);
|
static void mktree(Mkaux*, File*, int);
|
||||||
static void setname(Mkaux*, Name*, File*);
|
static void setname(Mkaux*, Name*, File*);
|
||||||
|
static void setopt(Mkaux*, char*, char*);
|
||||||
static void skipdir(Mkaux*);
|
static void skipdir(Mkaux*);
|
||||||
static void warn(Mkaux*, char *, ...);
|
static void warn(Mkaux*, char *, ...);
|
||||||
static void popopt(Mkaux *mkaux);
|
static void popopt(Mkaux *mkaux);
|
||||||
|
|
||||||
//static void
|
|
||||||
//mprint(char *new, char *old, Dir *d, void*)
|
|
||||||
//{
|
|
||||||
// print("%s %s %D\n", new, old, d);
|
|
||||||
//}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
rdproto(char *proto, char *root, Mkfsenum *mkenum, Mkfserr *mkerr, void *a)
|
rdproto(char *proto, char *root, Mkfsenum *mkenum, Mkfserr *mkerr, void *a)
|
||||||
{
|
{
|
||||||
|
@ -151,7 +148,7 @@ domkfs(Mkaux *mkaux, File *me, int level)
|
||||||
int rec;
|
int rec;
|
||||||
|
|
||||||
child = getfile(mkaux, me);
|
child = getfile(mkaux, me);
|
||||||
if(!child)
|
if(child == nil)
|
||||||
return;
|
return;
|
||||||
if((child->elem[0] == '+' || child->elem[0] == '*') && child->elem[1] == '\0'){
|
if((child->elem[0] == '+' || child->elem[0] == '*') && child->elem[1] == '\0'){
|
||||||
rec = child->elem[0] == '+';
|
rec = child->elem[0] == '+';
|
||||||
|
@ -162,13 +159,13 @@ domkfs(Mkaux *mkaux, File *me, int level)
|
||||||
freefile(child);
|
freefile(child);
|
||||||
child = getfile(mkaux, me);
|
child = getfile(mkaux, me);
|
||||||
}
|
}
|
||||||
while(child && mkaux->indent > level){
|
while(child != nil && mkaux->indent > level){
|
||||||
if(mkfile(mkaux, child))
|
if(mkfile(mkaux, child))
|
||||||
domkfs(mkaux, child, mkaux->indent);
|
domkfs(mkaux, child, mkaux->indent);
|
||||||
freefile(child);
|
freefile(child);
|
||||||
child = getfile(mkaux, me);
|
child = getfile(mkaux, me);
|
||||||
}
|
}
|
||||||
if(child){
|
if(child != nil){
|
||||||
freefile(child);
|
freefile(child);
|
||||||
Bseek(mkaux->b, -Blinelen(mkaux->b), 1);
|
Bseek(mkaux->b, -Blinelen(mkaux->b), 1);
|
||||||
mkaux->lineno--;
|
mkaux->lineno--;
|
||||||
|
@ -198,15 +195,14 @@ mktree(Mkaux *mkaux, File *me, int rec)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
child.new = mkpath(mkaux, me->new, d[i].name);
|
child.new = mkpath(mkaux, me->new, d[i].name);
|
||||||
if(me->old)
|
if(me->old != nil)
|
||||||
child.old = mkpath(mkaux, me->old, d[i].name);
|
child.old = mkpath(mkaux, me->old, d[i].name);
|
||||||
child.elem = d[i].name;
|
child.elem = d[i].name;
|
||||||
setname(mkaux, &mkaux->oldfile, &child);
|
setname(mkaux, &mkaux->oldfile, &child);
|
||||||
if((!(d[i].mode&DMDIR) || rec) && copyfile(mkaux, &child, &d[i], 1) && rec)
|
if((!(d[i].mode&DMDIR) || rec) && copyfile(mkaux, &child, &d[i], 1) && rec)
|
||||||
mktree(mkaux, &child, rec);
|
mktree(mkaux, &child, rec);
|
||||||
free(child.new);
|
free(child.new);
|
||||||
if(child.old)
|
free(child.old);
|
||||||
free(child.old);
|
|
||||||
}
|
}
|
||||||
free(d);
|
free(d);
|
||||||
}
|
}
|
||||||
|
@ -281,11 +277,11 @@ copyfile(Mkaux *mkaux, File *f, Dir *d, int permonly)
|
||||||
o = mkaux->opt;
|
o = mkaux->opt;
|
||||||
if(strcmp(f->uid, "-") != 0)
|
if(strcmp(f->uid, "-") != 0)
|
||||||
d->uid = f->uid;
|
d->uid = f->uid;
|
||||||
else if(o && o->uid)
|
else if(o != nil && o->uid != nil)
|
||||||
d->uid = o->uid;
|
d->uid = o->uid;
|
||||||
if(strcmp(f->gid, "-") != 0)
|
if(strcmp(f->gid, "-") != 0)
|
||||||
d->gid = f->gid;
|
d->gid = f->gid;
|
||||||
else if(o && o->gid)
|
else if(o != nil && o->gid != nil)
|
||||||
d->gid = o->gid;
|
d->gid = o->gid;
|
||||||
if(f->mode != ~0){
|
if(f->mode != ~0){
|
||||||
if(permonly)
|
if(permonly)
|
||||||
|
@ -294,10 +290,10 @@ copyfile(Mkaux *mkaux, File *f, Dir *d, int permonly)
|
||||||
warn(mkaux, "inconsistent mode for %s", f->new);
|
warn(mkaux, "inconsistent mode for %s", f->new);
|
||||||
else
|
else
|
||||||
d->mode = f->mode;
|
d->mode = f->mode;
|
||||||
} else if(o && o->mask)
|
} else if(o != nil && o->mask)
|
||||||
d->mode = (d->mode & ~o->mask) | (o->mode & o->mask);
|
d->mode = (d->mode & ~o->mask) | (o->mode & o->mask);
|
||||||
|
|
||||||
if(p = strrchr(f->new, '/'))
|
if((p = strrchr(f->new, '/')) != nil)
|
||||||
d->name = p+1;
|
d->name = p+1;
|
||||||
else
|
else
|
||||||
d->name = f->new;
|
d->name = f->new;
|
||||||
|
@ -415,28 +411,22 @@ setopt(Mkaux *mkaux, char *key, char *val)
|
||||||
o = mkaux->opt;
|
o = mkaux->opt;
|
||||||
if(o == nil || mkaux->indent > o->level){
|
if(o == nil || mkaux->indent > o->level){
|
||||||
o = emalloc(mkaux, sizeof(*o));
|
o = emalloc(mkaux, sizeof(*o));
|
||||||
if(o == nil)
|
if(mkaux->opt != nil)
|
||||||
longjmp(mkaux->jmp, 1);
|
|
||||||
if(mkaux->opt){
|
|
||||||
*o = *mkaux->opt;
|
*o = *mkaux->opt;
|
||||||
if(o->uid)
|
|
||||||
o->uid = estrdup(mkaux, o->uid);
|
|
||||||
if(o->gid)
|
|
||||||
o->gid = estrdup(mkaux, o->gid);
|
|
||||||
}else
|
|
||||||
memset(o, 0, sizeof(*o));
|
|
||||||
o->level = mkaux->indent;
|
o->level = mkaux->indent;
|
||||||
o->prev = mkaux->opt;
|
o->prev = mkaux->opt;
|
||||||
mkaux->opt = o;
|
mkaux->opt = o;
|
||||||
} else if(mkaux->indent < o->level)
|
} else if(mkaux->indent < o->level)
|
||||||
return;
|
return;
|
||||||
if(strcmp(key, "skip") == 0){
|
if(strcmp(key, "skip") == 0){
|
||||||
o->skip = regcomp(val);
|
freeoptptr(o, &o->skip);
|
||||||
|
if((o->skip = regcomp(val)) == nil)
|
||||||
|
warn(mkaux, "bad regular expression %s", val);
|
||||||
} else if(strcmp(key, "uid") == 0){
|
} else if(strcmp(key, "uid") == 0){
|
||||||
free(o->uid);
|
freeoptptr(o, &o->uid);
|
||||||
o->uid = *val ? estrdup(mkaux, val) : nil;
|
o->uid = *val ? estrdup(mkaux, val) : nil;
|
||||||
} else if(strcmp(key, "gid") == 0){
|
} else if(strcmp(key, "gid") == 0){
|
||||||
free(o->gid);
|
freeoptptr(o, &o->gid);
|
||||||
o->gid = *val ? estrdup(mkaux, val) : nil;
|
o->gid = *val ? estrdup(mkaux, val) : nil;
|
||||||
} else if(strcmp(key, "mode") == 0){
|
} else if(strcmp(key, "mode") == 0){
|
||||||
if(!parsemode(val, &o->mask, &o->mode))
|
if(!parsemode(val, &o->mask, &o->mode))
|
||||||
|
@ -451,23 +441,37 @@ popopt(Mkaux *mkaux)
|
||||||
{
|
{
|
||||||
Opt *o;
|
Opt *o;
|
||||||
|
|
||||||
while(o = mkaux->opt){
|
while((o = mkaux->opt) != nil){
|
||||||
if(o->level <= mkaux->indent)
|
if(o->level <= mkaux->indent)
|
||||||
break;
|
break;
|
||||||
mkaux->opt = o->prev;
|
mkaux->opt = o->prev;
|
||||||
free(o->uid);
|
freeoptptr(o, &o->skip);
|
||||||
free(o->gid);
|
freeoptptr(o, &o->uid);
|
||||||
|
freeoptptr(o, &o->gid);
|
||||||
free(o);
|
free(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
freeoptptr(Opt *o, void *p)
|
||||||
|
{
|
||||||
|
int x = (void**)p - (void**)o;
|
||||||
|
void *v = ((void**)o)[x];
|
||||||
|
if(v == nil)
|
||||||
|
return;
|
||||||
|
((void**)o)[x] = nil;
|
||||||
|
if((o = o->prev) != nil)
|
||||||
|
if(((void**)o)[x] == v)
|
||||||
|
return;
|
||||||
|
free(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
freefile(File *f)
|
freefile(File *f)
|
||||||
{
|
{
|
||||||
if(f->old)
|
free(f->old);
|
||||||
free(f->old);
|
free(f->new);
|
||||||
if(f->new)
|
|
||||||
free(f->new);
|
|
||||||
free(f);
|
free(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,27 +482,10 @@ freefile(File *f)
|
||||||
static void
|
static void
|
||||||
skipdir(Mkaux *mkaux)
|
skipdir(Mkaux *mkaux)
|
||||||
{
|
{
|
||||||
char *p, c;
|
|
||||||
int level;
|
int level;
|
||||||
|
|
||||||
if(mkaux->indent < 0)
|
|
||||||
return;
|
|
||||||
level = mkaux->indent;
|
level = mkaux->indent;
|
||||||
for(;;){
|
while(getline(mkaux) != nil){
|
||||||
mkaux->indent = 0;
|
|
||||||
p = Brdline(mkaux->b, '\n');
|
|
||||||
mkaux->lineno++;
|
|
||||||
if(!p){
|
|
||||||
mkaux->indent = -1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while((c = *p++) != '\n')
|
|
||||||
if(c == ' ')
|
|
||||||
mkaux->indent++;
|
|
||||||
else if(c == '\t')
|
|
||||||
mkaux->indent += 8;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
if(mkaux->indent <= level){
|
if(mkaux->indent <= level){
|
||||||
popopt(mkaux);
|
popopt(mkaux);
|
||||||
Bseek(mkaux->b, -Blinelen(mkaux->b), 1);
|
Bseek(mkaux->b, -Blinelen(mkaux->b), 1);
|
||||||
|
@ -508,23 +495,26 @@ skipdir(Mkaux *mkaux)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static File*
|
static char*
|
||||||
getfile(Mkaux *mkaux, File *old)
|
getline(Mkaux *mkaux)
|
||||||
{
|
{
|
||||||
File *f;
|
char *p;
|
||||||
char *elem;
|
|
||||||
char *p, *s;
|
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if(mkaux->indent < 0)
|
if(mkaux->indent < 0)
|
||||||
return 0;
|
return nil;
|
||||||
loop:
|
loop:
|
||||||
mkaux->indent = 0;
|
mkaux->indent = 0;
|
||||||
p = Brdline(mkaux->b, '\n');
|
p = Brdline(mkaux->b, '\n');
|
||||||
mkaux->lineno++;
|
mkaux->lineno++;
|
||||||
if(!p){
|
if(p == nil){
|
||||||
mkaux->indent = -1;
|
mkaux->indent = -1;
|
||||||
return 0;
|
return nil;
|
||||||
|
}
|
||||||
|
if(memchr(p, 0, Blinelen(mkaux->b)) != nil){
|
||||||
|
warn(mkaux, "null bytes in proto");
|
||||||
|
longjmp(mkaux->jmp, 1);
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
while((c = *p++) != '\n')
|
while((c = *p++) != '\n')
|
||||||
if(c == ' ')
|
if(c == ' ')
|
||||||
|
@ -535,41 +525,62 @@ loop:
|
||||||
break;
|
break;
|
||||||
if(c == '\n' || c == '#')
|
if(c == '\n' || c == '#')
|
||||||
goto loop;
|
goto loop;
|
||||||
p--;
|
return --p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static File*
|
||||||
|
getfile(Mkaux *mkaux, File *old)
|
||||||
|
{
|
||||||
|
File *f;
|
||||||
|
char *elem;
|
||||||
|
char *p, *s;
|
||||||
|
|
||||||
|
loop:
|
||||||
|
if((p = getline(mkaux)) == nil)
|
||||||
|
return nil;
|
||||||
popopt(mkaux);
|
popopt(mkaux);
|
||||||
|
|
||||||
*strchr(p, '\n') = 0;
|
*strchr(p, '\n') = 0;
|
||||||
if(s = strchr(p, '=')){
|
if((s = strchr(p, '=')) != nil){
|
||||||
*s++ = 0;
|
*s++ = 0;
|
||||||
setopt(mkaux, p, s);
|
setopt(mkaux, p, s);
|
||||||
goto loop;
|
goto loop;
|
||||||
}else
|
}else
|
||||||
p[strlen(p)] = '\n';
|
p[strlen(p)] = '\n';
|
||||||
f = emalloc(mkaux, sizeof *f);
|
|
||||||
p = getname(mkaux, p, &elem);
|
if((p = getname(mkaux, p, &elem)) == nil)
|
||||||
if(p == nil)
|
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
|
f = emalloc(mkaux, sizeof *f);
|
||||||
f->new = mkpath(mkaux, old->new, elem);
|
f->new = mkpath(mkaux, old->new, elem);
|
||||||
free(elem);
|
free(elem);
|
||||||
f->elem = utfrrune(f->new, L'/') + 1;
|
f->elem = utfrrune(f->new, L'/') + 1;
|
||||||
p = getmode(mkaux, p, &f->mode);
|
|
||||||
p = getname(mkaux, p, &f->uid); /* LEAK */
|
|
||||||
if(p == nil)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
if(!*f->uid)
|
if((p = getmode(mkaux, p, &f->mode)) == nil){
|
||||||
strcpy(f->uid, "-");
|
freefile(f);
|
||||||
p = getname(mkaux, p, &f->gid); /* LEAK */
|
|
||||||
if(p == nil)
|
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
if(!*f->gid)
|
|
||||||
strcpy(f->gid, "-");
|
|
||||||
f->old = getpath(mkaux, p);
|
|
||||||
if(f->old && strcmp(f->old, "-") == 0){
|
|
||||||
free(f->old);
|
|
||||||
f->old = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((p = getname(mkaux, p, &f->uid)) == nil){
|
||||||
|
freefile(f);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
if(*f->uid == 0)
|
||||||
|
strcpy(f->uid, "-");
|
||||||
|
|
||||||
|
if((p = getname(mkaux, p, &f->gid)) == nil){
|
||||||
|
freefile(f);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
if(*f->gid == 0)
|
||||||
|
strcpy(f->gid, "-");
|
||||||
|
|
||||||
|
f->old = getpath(mkaux, p);
|
||||||
|
if(f->old != nil && strcmp(f->old, "-") == 0){
|
||||||
|
free(f->old);
|
||||||
|
f->old = nil;
|
||||||
|
}
|
||||||
|
|
||||||
setname(mkaux, &mkaux->oldfile, f);
|
setname(mkaux, &mkaux->oldfile, f);
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
|
@ -587,7 +598,7 @@ getpath(Mkaux *mkaux, char *p)
|
||||||
while((c = *q) != '\n' && c != ' ' && c != '\t')
|
while((c = *q) != '\n' && c != ' ' && c != '\t')
|
||||||
q++;
|
q++;
|
||||||
if(q == p)
|
if(q == p)
|
||||||
return 0;
|
return nil;
|
||||||
n = q - p;
|
n = q - p;
|
||||||
new = emalloc(mkaux, n + 1);
|
new = emalloc(mkaux, n + 1);
|
||||||
memcpy(new, p, n);
|
memcpy(new, p, n);
|
||||||
|
@ -613,14 +624,14 @@ getname(Mkaux *mkaux, char *p, char **buf)
|
||||||
return nil;
|
return nil;
|
||||||
memmove(*buf, start, p-start);
|
memmove(*buf, start, p-start);
|
||||||
|
|
||||||
(*buf)[p-start] = '\0';
|
(*buf)[p-start] = 0;
|
||||||
|
|
||||||
if(**buf == '$'){
|
if(**buf == '$'){
|
||||||
s = getenv(*buf+1);
|
s = getenv(*buf+1);
|
||||||
if(s == 0){
|
if(s == nil){
|
||||||
warn(mkaux, "can't read environment variable %s", *buf+1);
|
warn(mkaux, "can't read environment variable %s", *buf+1);
|
||||||
skipdir(mkaux);
|
|
||||||
free(*buf);
|
free(*buf);
|
||||||
|
skipdir(mkaux);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
free(*buf);
|
free(*buf);
|
||||||
|
@ -636,12 +647,11 @@ getmode(Mkaux *mkaux, char *p, ulong *xmode)
|
||||||
ulong m;
|
ulong m;
|
||||||
|
|
||||||
*xmode = ~0;
|
*xmode = ~0;
|
||||||
p = getname(mkaux, p, &buf);
|
if((p = getname(mkaux, p, &buf)) == nil)
|
||||||
if(p == nil)
|
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
s = buf;
|
s = buf;
|
||||||
if(!*s || strcmp(s, "-") == 0)
|
if(*s == 0 || strcmp(s, "-") == 0)
|
||||||
return p;
|
return p;
|
||||||
m = 0;
|
m = 0;
|
||||||
if(*s == 'd'){
|
if(*s == 'd'){
|
||||||
|
@ -679,7 +689,7 @@ warn(Mkaux *mkaux, char *fmt, ...)
|
||||||
vseprint(buf, buf+sizeof(buf), fmt, va);
|
vseprint(buf, buf+sizeof(buf), fmt, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
|
||||||
if(mkaux->warn)
|
if(mkaux->warn != nil)
|
||||||
mkaux->warn(buf, mkaux->a);
|
mkaux->warn(buf, mkaux->a);
|
||||||
else
|
else
|
||||||
fprint(2, "warning: %s\n", buf);
|
fprint(2, "warning: %s\n", buf);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue