X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=tar.c;h=af7f2141f8a4614ce3d795d2dc570637e34fd17c;hb=537d34cbb40c3babaa12ef59cfbb292416ff5c30;hp=c73657d5d85afd01664dab2a269ece4a5c5ed8c2;hpb=def03712042d935b1238542b15d62f5121b9d5d2;p=debian%2Fpax diff --git a/tar.c b/tar.c index c73657d..af7f214 100644 --- a/tar.c +++ b/tar.c @@ -47,6 +47,7 @@ static char rcsid[] = "$OpenBSD: tar.c,v 1.13 1998/09/26 21:29:41 millert Exp $" #endif /* not lint */ #include +#include #include #include #include @@ -841,15 +842,21 @@ ustar_rd(arcn, buf) /* * see if the filename is split into two parts. if, so joint the parts. * we copy the prefix first and add a / between the prefix and name. + * + * the length passed to l_strncpy must be the length of the field + * being copied *from*, since these fields are NOT null terminated + * when full. the destination buffer is plenty big enough to hold + * the longest supported ustar path length, so there's no need + * to check against that. */ dest = arcn->name; if (*(hd->prefix) != '\0') { - cnt = l_strncpy(dest, hd->prefix, sizeof(arcn->name) - 2); + cnt = l_strncpy(dest, hd->prefix, sizeof(hd->prefix)); dest += cnt; *dest++ = '/'; cnt++; } - arcn->nlen = cnt + l_strncpy(dest, hd->name, sizeof(arcn->name) - cnt); + arcn->nlen = cnt + l_strncpy(dest, hd->name, sizeof(hd->name)); arcn->name[arcn->nlen] = '\0'; /* @@ -936,9 +943,12 @@ ustar_rd(arcn, buf) } /* * copy the link name + * + * see comment above (for hd->name) regarding the length + * passed to l_strncpy */ arcn->ln_nlen = l_strncpy(arcn->ln_name, hd->linkname, - sizeof(arcn->ln_name) - 1); + sizeof(hd->linkname)); arcn->ln_name[arcn->ln_nlen] = '\0'; break; case CONTTYPE: @@ -1020,7 +1030,7 @@ ustar_wr(arcn) * occur, we remove the / and copy the first part to the prefix */ *pt = '\0'; - l_strncpy(hd->prefix, arcn->name, sizeof(hd->prefix) - 1); + l_strncpy(hd->prefix, arcn->name, sizeof(hd->prefix)); *pt++ = '/'; } else memset(hd->prefix, 0, sizeof(hd->prefix)); @@ -1029,8 +1039,7 @@ ustar_wr(arcn) * copy the name part. this may be the whole path or the part after * the prefix */ - l_strncpy(hd->name, pt, sizeof(hd->name) - 1); - hd->name[sizeof(hd->name) - 1] = '\0'; + l_strncpy(hd->name, pt, sizeof(hd->name)); /* * set the fields in the header that are type dependent @@ -1040,7 +1049,9 @@ ustar_wr(arcn) hd->typeflag = DIRTYPE; memset(hd->linkname, 0, sizeof(hd->linkname)); memset(hd->devmajor, 0, sizeof(hd->devmajor)); + hd->devmajor[0] = '0'; memset(hd->devminor, 0, sizeof(hd->devminor)); + hd->devminor[0] = '0'; if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) goto out; break; @@ -1062,7 +1073,9 @@ ustar_wr(arcn) hd->typeflag = FIFOTYPE; memset(hd->linkname, 0, sizeof(hd->linkname)); memset(hd->devmajor, 0, sizeof(hd->devmajor)); + hd->devmajor[0] = '0'; memset(hd->devminor, 0, sizeof(hd->devminor)); + hd->devminor[0] = '0'; if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) goto out; break; @@ -1073,10 +1086,11 @@ ustar_wr(arcn) hd->typeflag = SYMTYPE; else hd->typeflag = LNKTYPE; - l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname) - 1); - hd->linkname[sizeof(hd->linkname) - 1] = '\0'; + l_strncpy(hd->linkname,arcn->ln_name, sizeof(hd->linkname)); memset(hd->devmajor, 0, sizeof(hd->devmajor)); + hd->devmajor[0] = '0'; memset(hd->devminor, 0, sizeof(hd->devminor)); + hd->devminor[0] = '0'; if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 3)) goto out; break; @@ -1092,7 +1106,9 @@ ustar_wr(arcn) hd->typeflag = REGTYPE; memset(hd->linkname, 0, sizeof(hd->linkname)); memset(hd->devmajor, 0, sizeof(hd->devmajor)); + hd->devmajor[0] = '0'; memset(hd->devminor, 0, sizeof(hd->devminor)); + hd->devminor[0] = '0'; arcn->pad = TAR_PAD(arcn->sb.st_size); # ifdef NET2_STAT if (ul_oct((u_long)arcn->sb.st_size, hd->size, @@ -1174,7 +1190,7 @@ name_split(name, len) * check to see if the file name is small enough to fit in the name * field. if so just return a pointer to the name. */ - if (len < TNMSZ) + if (len <= TNMSZ) return(name); if (len > (TPFSZ + TNMSZ + 1)) return(NULL);