Blob Blame History Raw
diff -U0 pycups-1.9.63/ChangeLog.uris pycups-1.9.63/ChangeLog
diff -up pycups-1.9.63/cupsconnection.c.uris pycups-1.9.63/cupsconnection.c
--- pycups-1.9.63/cupsconnection.c.uris	2013-03-20 13:28:37.000000000 +0000
+++ pycups-1.9.63/cupsconnection.c	2013-04-11 15:27:49.036679360 +0100
@@ -138,6 +138,40 @@ UTF8_from_PyObj (char **const utf8, PyOb
   return NULL;
 }
 
+static void
+construct_uri (char *buffer, size_t buflen, const char *base, const char *value)
+{
+  char *d = buffer;
+  const unsigned char *s = (const unsigned char *) value;
+  if (strlen (base) < buflen) {
+    strcpy (buffer, base);
+    d += strlen (base);
+  } else {
+    strncpy (buffer, base, buflen);
+    d += buflen;
+  }
+
+  while (*s && d < buffer + buflen) {
+    if (isalpha (*s) || isdigit (*s) || *s == '-')
+      *d++ = *s++;
+    else if (*s == ' ') {
+      *d++ = '+';
+      s++;
+    } else {
+      if (d + 2 < buffer + buflen) {
+	*d++ = '%';
+	*d++ = "0123456789ABCDEF"[((*s) & 0xf0) >> 4];
+	*d++ = "0123456789ABCDEF"[((*s) & 0x0f)];
+	s++;
+      } else
+	break;
+    }
+  }
+
+  if (d < buffer + buflen)
+    *d = '\0';
+}
+
 ////////////////
 // Connection //
 ////////////////
@@ -446,7 +480,7 @@ do_printer_request (Connection *self, Py
   debugprintf ("-> do_printer_request(op:%d, name:%s)\n", (int) op, name);
 
   request = ippNewRequest (op);
-  snprintf (uri, sizeof (uri), "ipp://localhost/printers/%s", name);
+  construct_uri (uri, sizeof (uri), "ipp://localhost/printers/", name);
   free (name);
 
   ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
@@ -1749,7 +1783,8 @@ Connection_cancelAllJobs (Connection *se
   debugprintf ("-> Connection_cancelAllJobs(%s, my_jobs=%d, purge_jobs=%d)\n",
 	       nameobj ? name : uri, my_jobs, purge_jobs);
   if (nameobj) {
-    snprintf (consuri, sizeof (consuri), "ipp://localhost/printers/%s", name);
+    construct_uri (consuri, sizeof (consuri),
+		   "ipp://localhost/printers/", name);
     uri = consuri;
   }
 
@@ -1776,7 +1811,8 @@ Connection_cancelAllJobs (Connection *se
 	break;
 
       // Perhaps it's a class, not a printer.
-      snprintf (consuri, sizeof (consuri), "ipp://localhost/classes/%s", name);
+      construct_uri (consuri, sizeof (consuri),
+		     "ipp://localhost/classes/", name);
     } else break;
   }
 
@@ -2125,7 +2161,7 @@ add_modify_printer_request (const char *
 {
   char uri[HTTP_MAX_URI];
   ipp_t *request = ippNewRequest (CUPS_ADD_MODIFY_PRINTER);
-  snprintf (uri, sizeof (uri), "ipp://localhost/printers/%s", name);
+  construct_uri (uri, sizeof (uri), "ipp://localhost/printers/", name);
   ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
 		"printer-uri", NULL, uri);
   return request;
@@ -2136,7 +2172,7 @@ add_modify_class_request (const char *na
 {
   char uri[HTTP_MAX_URI];
   ipp_t *request = ippNewRequest (CUPS_ADD_MODIFY_CLASS);
-  snprintf (uri, sizeof (uri), "ipp://localhost/classes/%s", name);
+  construct_uri (uri, sizeof (uri), "ipp://localhost/classes/", name);
   ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
 		"printer-uri", NULL, uri);
   return request;
@@ -3012,7 +3048,8 @@ Connection_getPrinterAttributes (Connect
 	       nameobj ? name : uri);
 
   if (nameobj) {
-    snprintf (consuri, sizeof (consuri), "ipp://localhost/printers/%s", name);
+    construct_uri (consuri, sizeof (consuri),
+		   "ipp://localhost/printers/", name);
     uri = consuri;
   }
 
@@ -3034,7 +3071,8 @@ Connection_getPrinterAttributes (Connect
 	break;
 
       // Perhaps it's a class, not a printer.
-      snprintf (consuri, sizeof (consuri), "ipp://localhost/classes/%s", name);
+      construct_uri (consuri, sizeof (consuri),
+		     "ipp://localhost/classes/", name);
     } else break;
   }
 
@@ -3179,8 +3217,9 @@ Connection_addPrinterToClass (Connection
 
   // Does the class exist, and is the printer already in it?
   request = ippNewRequest (IPP_GET_PRINTER_ATTRIBUTES);
-  snprintf (classuri, sizeof (classuri),
-	    "ipp://localhost/classes/%s", classname);
+  construct_uri (classuri, sizeof (classuri),
+		 "ipp://localhost/classes/", classname);
+	    
   free (classname);
   ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
 		"printer-uri", NULL, classuri);
@@ -3206,8 +3245,8 @@ Connection_addPrinterToClass (Connection
   request = ippNewRequest (CUPS_ADD_CLASS);
   ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
 		"printer-uri", NULL, classuri);
-  snprintf (printeruri, sizeof (printeruri),
-	    "ipp://localhost/printers/%s", printername);
+  construct_uri (printeruri, sizeof (printeruri),
+		 "ipp://localhost/printers/", printername);
   free (printername);
   if (answer) {
     ipp_attribute_t *printers;
@@ -3283,8 +3322,8 @@ Connection_deletePrinterFromClass (Conne
 
   // Does the class exist, and is the printer in it?
   request = ippNewRequest (IPP_GET_PRINTER_ATTRIBUTES);
-  snprintf (classuri, sizeof (classuri),
-	    "ipp://localhost/classes/%s", classname);
+  construct_uri (classuri, sizeof (classuri),
+		 "ipp://localhost/classes/", classname);
   free (classname);
   ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
 		"printer-uri", NULL, classuri);
@@ -3379,8 +3418,8 @@ Connection_deleteClass (Connection *self
     return NULL;
 
   request = ippNewRequest (CUPS_DELETE_CLASS);
-  snprintf (classuri, sizeof (classuri),
-	    "ipp://localhost/classes/%s", classname);
+  construct_uri (classuri, sizeof (classuri),
+		 "ipp://localhost/classes/", classname);
   free (classname);
   ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
 		"printer-uri", NULL, classuri);
@@ -3659,7 +3698,8 @@ Connection_printTestPage (Connection *se
   if (!userobj)
 	  user = (char *) cupsUser();
 
-  snprintf (uri, sizeof (uri), "ipp://localhost/printers/%s", printer);
+  construct_uri (uri, sizeof (uri),
+		 "ipp://localhost/printers/", printer);
   resource = uri + strlen ("ipp://localhost");
   for (i = 0; i < 2; i++) {
     request = ippNewRequest (IPP_PRINT_JOB);
@@ -3679,7 +3719,8 @@ Connection_printTestPage (Connection *se
     if (answer && ippGetStatusCode (answer) == IPP_NOT_POSSIBLE) {
       ippDelete (answer);
       // Perhaps it's a class, not a printer.
-      snprintf (uri, sizeof (uri), "ipp://localhost/classes/%s", printer);
+      construct_uri (uri, sizeof (uri),
+		     "ipp://localhost/classes/", printer);
     } else break;
   }