]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
The LPD mini-daemon now detects invalid UTF-8 sequences in job, document, and
authorMichael R Sweet <michaelrsweet@gmail.com>
Thu, 24 Mar 2016 22:55:20 +0000 (18:55 -0400)
committerMichael R Sweet <michaelrsweet@gmail.com>
Thu, 24 Mar 2016 22:55:20 +0000 (18:55 -0400)
user names (Issue #4748)

CHANGES.txt
scheduler/cups-lpd.c

index 7c1fac33c59867601a48e15f031ba343bfa330be..b9fe4ff8656fed4c3ab52a6dbb36235d8f79c4af 100644 (file)
@@ -1,8 +1,10 @@
-CHANGES.txt - 2.2b1 - 2016-03-10
+CHANGES.txt - 2.2b1 - 2016-03-24
 --------------------------------
 
 CHANGES IN CUPS V2.2b1
 
+       - The LPD mini-daemon now detects invalid UTF-8 sequences in job,
+         document, and user names (Issue #4748)
        - The IPP backend now continues on to the next job when the remote
          server/printer puts the job on hold (<rdar://problem/24858548>)
        - The scheduler did not cancel multi-document jobs immediately
index 3a67e1ce24d9c80efc68531bafe25bcba624b9ee..e1d4919018ceb4eb298970ac3f292fae55e23d81 100644 (file)
@@ -73,6 +73,7 @@ static int    remove_jobs(const char *name, const char *agent,
 static int     send_state(const char *name, const char *list,
                           int longstatus);
 static char    *smart_gets(char *s, int len, FILE *fp);
+static void    smart_strlcpy(char *dst, const char *src, size_t dstsize);
 
 
 /*
@@ -1055,15 +1056,15 @@ recv_print_job(
        switch (line[0])
        {
          case 'J' : /* Job name */
-             strlcpy(title, line + 1, sizeof(title));
+             smart_strlcpy(title, line + 1, sizeof(title));
              break;
 
           case 'N' : /* Document name */
-              strlcpy(docname, line + 1, sizeof(docname));
+              smart_strlcpy(docname, line + 1, sizeof(docname));
               break;
 
          case 'P' : /* User identification */
-             strlcpy(user, line + 1, sizeof(user));
+             smart_strlcpy(user, line + 1, sizeof(user));
              break;
 
          case 'L' : /* Print banner page */
@@ -1148,7 +1149,7 @@ recv_print_job(
          switch (line[0])
          {
            case 'N' : /* Document name */
-               strlcpy(docname, line + 1, sizeof(docname));
+               smart_strlcpy(docname, line + 1, sizeof(docname));
                break;
 
            case 'c' : /* Plot CIF file */
@@ -1619,3 +1620,82 @@ smart_gets(char *s,                      /* I - Pointer to line buffer */
   else
     return (s);
 }
+
+
+/*
+ * 'smart_strlcpy()' - Copy a string and convert from ISO-8859-1 to UTF-8 as needed.
+ */
+
+static void
+smart_strlcpy(char       *dst,         /* I - Output buffer */
+              const char *src,         /* I - Input string */
+              size_t     dstsize)      /* I - Size of output buffer */
+{
+  const unsigned char  *srcptr;        /* Pointer into input string */
+  unsigned char                *dstptr,        /* Pointer into output buffer */
+                       *dstend;        /* End of output buffer */
+  int                  saw_8859 = 0;   /* Saw an extended character that was not UTF-8? */
+
+
+  for (srcptr = (unsigned char *)src, dstptr = (unsigned char *)dst, dstend = dstptr + dstsize - 1; *srcptr;)
+  {
+    if (*srcptr < 0x80)
+      *dstptr++ = *srcptr++;           /* ASCII */
+    else if (saw_8859)
+    {
+     /*
+      * Map ISO-8859-1 (most likely character set for legacy LPD clients) to
+      * UTF-8...
+      */
+
+      if (dstptr > (dstend - 2))
+        break;
+
+      *dstptr++ = 0xc0 | (*srcptr >> 6);
+      *dstptr++ = 0x80 | (*srcptr++ & 0x3f);
+    }
+    else if ((*srcptr & 0xe0) == 0xc0)
+    {
+      if (dstptr > (dstend - 2))
+        break;
+
+      *dstptr++ = *srcptr++;
+      *dstptr++ = *srcptr++;
+    }
+    else if ((*srcptr & 0xf0) == 0xe0)
+    {
+      if (dstptr > (dstend - 3))
+        break;
+
+      *dstptr++ = *srcptr++;
+      *dstptr++ = *srcptr++;
+      *dstptr++ = *srcptr++;
+    }
+    else if ((*srcptr & 0xf8) == 0xf0)
+    {
+      if (dstptr > (dstend - 4))
+        break;
+
+      *dstptr++ = *srcptr++;
+      *dstptr++ = *srcptr++;
+      *dstptr++ = *srcptr++;
+      *dstptr++ = *srcptr++;
+    }
+    else
+    {
+     /*
+      * Orphan UTF-8 sequence, this must be an ISO-8859-1 string...
+      */
+
+      saw_8859 = 1;
+
+      if (dstptr > (dstend - 2))
+        break;
+
+      *dstptr++ = 0xc0 | (*srcptr >> 6);
+      *dstptr++ = 0x80 | (*srcptr++ & 0x3f);
+    }
+  }
+
+  *dstptr = '\0';
+}