|
|
@@ -43,6 +43,7 @@
|
|
|
|
|
|
#include <dpkg/dpkg.h>
|
|
|
#include <dpkg/dpkg-db.h>
|
|
|
+#include <dpkg/path.h>
|
|
|
#include <dpkg/buffer.h>
|
|
|
#include <dpkg/subproc.h>
|
|
|
#include <dpkg/tarfn.h>
|
|
|
@@ -63,64 +64,6 @@ static security_context_t scontext = NULL;
|
|
|
struct pkginfo *conflictor[MAXCONFLICTORS];
|
|
|
int cflict_index = 0;
|
|
|
|
|
|
-/* snprintf(3) doesn't work if format contains %.<nnn>s and an argument has
|
|
|
- * invalid char for locale, then it returns -1.
|
|
|
- * ohshite() is ok, but fd_fd_copy(), which is used in tarobject() in this
|
|
|
- * file, is not ok, because
|
|
|
- * - fd_fd_copy() == buffer_copy_setup() [include/dpkg.h]
|
|
|
- * - buffer_copy_setup() uses varbufvprintf(&v, desc, al); [lib/mlib.c]
|
|
|
- * - varbufvprintf() fails and memory exausted, because it call
|
|
|
- * fmt = "backend dpkg-deb during `%.255s'
|
|
|
- * arg may contain some invalid char, for example,
|
|
|
- * /usr/share/doc/console-tools/examples/unicode/\342\231\252\342\231\254
|
|
|
- * in console-tools.
|
|
|
- * In this case, if user uses some locale which doesn't support \342\231...,
|
|
|
- * vsnprintf() always returns -1 and varbufextend() get called again
|
|
|
- * and again until memory is exausted and it aborts.
|
|
|
- *
|
|
|
- * So, we need to escape invalid char, probably as in
|
|
|
- * tar-1.13.19/lib/quotearg.c: quotearg_buffer_restyled()
|
|
|
- * but here I escape all 8bit chars, in order to be simple.
|
|
|
- * - ukai@debian.or.jp
|
|
|
- */
|
|
|
-static char *
|
|
|
-quote_filename(char *buf, int size, char *s)
|
|
|
-{
|
|
|
- char *r = buf;
|
|
|
-
|
|
|
- while (size > 0) {
|
|
|
- switch (*s) {
|
|
|
- case '\0':
|
|
|
- *buf = '\0';
|
|
|
- return r;
|
|
|
- case '\\':
|
|
|
- *buf++ = '\\';
|
|
|
- *buf++ = '\\';
|
|
|
- size -= 2;
|
|
|
- break;
|
|
|
- default:
|
|
|
- if (((*s) & 0x80) == '\0') {
|
|
|
- *buf++ = *s++;
|
|
|
- --size;
|
|
|
- } else {
|
|
|
- if (size > 4) {
|
|
|
- sprintf(buf, "\\%03o", *(unsigned char *)s);
|
|
|
- size -= 4;
|
|
|
- buf += 4;
|
|
|
- s++;
|
|
|
- } else {
|
|
|
- /* buffer full */
|
|
|
- *buf = '\0'; /* XXX */
|
|
|
- return r;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- *buf = '\0'; /* XXX */
|
|
|
-
|
|
|
- return r;
|
|
|
-}
|
|
|
-
|
|
|
/* special routine to handle partial reads from the tarfile */
|
|
|
static int safe_read(int fd, void *buf, int len)
|
|
|
{
|
|
|
@@ -258,7 +201,7 @@ tarfile_skip_one_forward(struct TarInfo *ti,
|
|
|
|
|
|
fd_null_copy(tc->backendpipe, ti->Size,
|
|
|
_("skipped unpacking file '%.255s' (replaced or excluded?)"),
|
|
|
- quote_filename(fnamebuf, 256, ti->Name));
|
|
|
+ path_quote_filename(fnamebuf, 256, ti->Name));
|
|
|
r = ti->Size % TARBLKSZ;
|
|
|
if (r > 0)
|
|
|
r = safe_read(tc->backendpipe, databuf, TARBLKSZ - r);
|
|
|
@@ -694,7 +637,9 @@ int tarobject(struct TarInfo *ti) {
|
|
|
debug(dbg_eachfiledetail,"tarobject NormalFile[01] open size=%lu",
|
|
|
(unsigned long)ti->Size);
|
|
|
{ char fnamebuf[256];
|
|
|
- fd_fd_copy(tc->backendpipe, fd, ti->Size, _("backend dpkg-deb during `%.255s'"),quote_filename(fnamebuf,256,ti->Name));
|
|
|
+ fd_fd_copy(tc->backendpipe, fd, ti->Size,
|
|
|
+ _("backend dpkg-deb during `%.255s'"),
|
|
|
+ path_quote_filename(fnamebuf, 256, ti->Name));
|
|
|
}
|
|
|
r= ti->Size % TARBLKSZ;
|
|
|
if (r > 0) r= safe_read(tc->backendpipe,databuf,TARBLKSZ - r);
|