X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/582250008b4d5552d73b0eb36a6776bd3b8622b5..9dd891bb28f6cc558b87905f1adc5e3d4180b6b3:/flist.c diff --git a/flist.c b/flist.c index b3e1a933..5d1a2590 100644 --- a/flist.c +++ b/flist.c @@ -375,7 +375,7 @@ static void receive_file_entry(struct file_struct **fptr, static gid_t last_gid; static char lastname[MAXPATHLEN]; char thisname[MAXPATHLEN]; - int l1=0,l2=0; + unsigned int l1=0,l2=0; char *p; struct file_struct *file; @@ -442,6 +442,10 @@ static void receive_file_entry(struct file_struct **fptr, if (preserve_links && S_ISLNK(file->mode)) { int l = read_int(f); + if (l < 0) { + rprintf(FERROR,"overflow: l=%d\n", l); + overflow("receive_file_entry"); + } file->link = (char *)malloc(l+1); if (!file->link) out_of_memory("receive_file_entry 2"); read_sbuf(f,file->link,l); @@ -1018,6 +1022,10 @@ oom: } +/* + * XXX: This is currently the hottest function while building the file + * list, because building f_name()s every time is expensive. + **/ int file_compare(struct file_struct **f1,struct file_struct **f2) { if (!(*f1)->basename && !(*f2)->basename) return 0; @@ -1179,6 +1187,10 @@ static void clean_flist(struct file_list *flist, int strip_root) /* * return the full filename of a flist entry + * + * This function is too expensive at the moment, because it copies + * strings when often we only want to compare them. In any case, + * using strlcat is silly because it will walk the string repeatedly. */ char *f_name(struct file_struct *f) { @@ -1191,9 +1203,11 @@ char *f_name(struct file_struct *f) n = (n+1)%10; if (f->dirname) { - strlcpy(p, f->dirname, MAXPATHLEN); - strlcat(p, "/", MAXPATHLEN); - strlcat(p, f->basename, MAXPATHLEN); + int off; + + off = strlcpy(p, f->dirname, MAXPATHLEN); + off += strlcpy(p+off, "/", MAXPATHLEN-off); + off += strlcpy(p+off, f->basename, MAXPATHLEN-off); } else { strlcpy(p, f->basename, MAXPATHLEN); }