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;
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)