|
|
@@ -51,6 +51,64 @@
|
|
|
struct pkginfo *conflictor[20];
|
|
|
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]
|
|
|
+ * - varbufvpprintf() 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 return -1 and varbufextend() again and again
|
|
|
+ * and memory exausted and die.
|
|
|
+ *
|
|
|
+ * 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 s;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ *buf = '\0'; /* XXX */
|
|
|
+ return r;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
int filesavespackage(struct fileinlist *file, struct pkginfo *pkgtobesaved,
|
|
|
struct pkginfo *pkgbeinginstalled) {
|
|
|
struct pkginfo *divpkg, *thirdpkg;
|
|
|
@@ -406,7 +464,9 @@ int tarobject(struct TarInfo *ti) {
|
|
|
push_cleanup(cu_closefd,ehflag_bombout, 0,0, 1,(void*)fd);
|
|
|
debug(dbg_eachfiledetail,"tarobject NormalFile[01] open size=%lu",
|
|
|
(unsigned long)ti->Size);
|
|
|
- fd_fd_copy(tc->backendpipe, fd, ti->Size, _("backend dpkg-deb during `%.255s'"),ti->Name);
|
|
|
+ { char fnamebuf[256];
|
|
|
+ fd_fd_copy(tc->backendpipe, fd, ti->Size, _("backend dpkg-deb during `%.255s'"),quote_filename(fnamebuf,256,ti->Name));
|
|
|
+ }
|
|
|
r= ti->Size % TARBLKSZ;
|
|
|
if (r > 0) r= read(tc->backendpipe,databuf,TARBLKSZ - r);
|
|
|
if (nifd->namenode->statoverride)
|