summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2015-10-29 15:24:44 +0100
committerSimon Rettberg2015-10-29 15:24:44 +0100
commitf391fa6ce2ea6ca669e093dca888f3855417a775 (patch)
tree313a3bf490565541c6a7eda7ef59ecdaa86d94c1
parent[pwgui] Fix compiler warning (diff)
downloadprintergui-f391fa6ce2ea6ca669e093dca888f3855417a775.tar.gz
printergui-f391fa6ce2ea6ca669e093dca888f3855417a775.tar.xz
printergui-f391fa6ce2ea6ca669e093dca888f3855417a775.zip
[printergui] Sanitize job names (ASCII only to be extra safe)
-rw-r--r--src/maingui/printergui.cpp281
1 files changed, 279 insertions, 2 deletions
diff --git a/src/maingui/printergui.cpp b/src/maingui/printergui.cpp
index 2467dcc..e235007 100644
--- a/src/maingui/printergui.cpp
+++ b/src/maingui/printergui.cpp
@@ -12,6 +12,10 @@ static QStringList knownColorOptions = QStringList() << "ColorModel" << "XRXColo
static QStringList knownDuplexOptions = QStringList() << "Duplex";
static QStringList knownPageSizeOptions = QStringList() << "PageSize";
+static int isUtf8(const char *s);
+static void toLatin1(char *s);
+static char* cleanCupsString(const char* in);
+
// ____________________________________________________________________________
PrinterGui::PrinterGui(char *argv[], QWidget *parent) :
QDialog(parent),
@@ -293,7 +297,7 @@ void PrinterGui::on_buttonPrint_clicked()
}
cupsSetUser(this->user);
- char jobtitle[200];
+ char jobtitle[250];
const char *docName;
docName = getenv("J");
if (docName == NULL) {
@@ -302,7 +306,11 @@ void PrinterGui::on_buttonPrint_clicked()
if (docName == NULL) {
docName = "Untitled";
}
- snprintf(jobtitle, sizeof(jobtitle), "gui-%d-%s (%s)", (int)getpid(), this->user, docName);
+ char *cleanUser = cleanCupsString(this->user);
+ char *cleanTitle = cleanCupsString(docName);
+ snprintf(jobtitle, sizeof(jobtitle), "gui-%d-%s (%s)", (int)getpid(), cleanUser, cleanTitle);
+ free(cleanUser);
+ free(cleanTitle);
// Drucken
jobId = cupsPrintFile(dest->name,
@@ -337,3 +345,272 @@ void PrinterGui::bgTimer_timeout()
}
}
+/**
+ * Checks if the given c string is UTF-8.
+ * Using as bool-function:
+ * Return value != 0 means (potentially) UTF-8,
+ * that is, it can be processed by UTF-8 functions without error.
+ * Using for in-detail detection:
+ * Return value 0 = not valid UTF-8
+ * Return value 1 = valid ASCII (which is a subset of UTF-8)
+ * Return value 2 = valid UTF-8, but not valid ASCII.
+ */
+static int isUtf8(const char *s)
+{
+ bool isAscii = true;
+ while (*s != '\0') {
+ if ((s[0] & 248) == 240 &&
+ (s[1] & 192) == 128 &&
+ (s[2] & 192) == 128 &&
+ (s[3] & 192) == 128) {
+ s += 4;
+ isAscii = false;
+ } else if ((s[0] & 240) == 224 &&
+ (s[1] & 192) == 128 &&
+ (s[2] & 192) == 128) {
+ s += 3;
+ isAscii = false;
+ } else if ((s[0] & 224) == 192 &&
+ (s[1] & 192) == 128) {
+ s += 2;
+ isAscii = false;
+ } else if ((s[0] & 128) != 0) {
+ // Invalid UTF-8 sequence, so no ASCII either
+ return 0;
+ } else {
+ s+= 1;
+ }
+ }
+ return isAscii ? 1 : 2;
+}
+
+static void toLatin1(char *s)
+{
+ char *d = s;
+ while (*s != '\0') {
+ if ((s[0] & 248) == 240 &&
+ (s[1] & 192) == 128 &&
+ (s[2] & 192) == 128 &&
+ (s[3] & 192) == 128) {
+ d[0] = '_';
+ s += 4;
+ } else if ((s[0] & 240) == 224 &&
+ (s[1] & 192) == 128 &&
+ (s[2] & 192) == 128) {
+ d[0] = '_';
+ s += 3;
+ } else if ((s[0] & 224) == 192 &&
+ (s[1] & 192) == 128) {
+ int c = ((s[0] & 31) << 6) | (s[1] & 63);
+ if (c > 255) {
+ d[0] = '_';
+ } else {
+ d[0] = (char)c;
+ }
+ s += 2;
+ } else if ((s[0] & 128) != 0) {
+ // Invalid UTF-8 sequence!?
+ d[0] = '_';
+ s+= 1;
+ } else {
+ d[0] = s[0];
+ s+= 1;
+ }
+ d += 1;
+ }
+ *d = '\0';
+}
+
+static char* cleanCupsString(const char* in)
+{
+ int enc = isUtf8(in);
+ char *out = strdup(in);
+ if (enc == 2) {
+ // UTF-8, turn to Latin-1
+ toLatin1(out);
+ }
+ // Try to convert umlauts etc., remove non-printing chars
+ unsigned char *tmp = (unsigned char*)out;
+ while (*tmp != '\0') {
+ if (*tmp < 0x20 || *tmp > 0x7E) {
+ switch (*tmp) {
+ case 0x84: // „
+ case 0x93: // “
+ case 0x94: // ”
+ case 0xAB: // «
+ case 0xBB: // »
+ *tmp = '"';
+ break;
+ case 0x91: // ‘
+ case 0x92: // ’
+ case 0xB4: // ´
+ *tmp = '\'';
+ break;
+ case 0xB7: // ·
+ *tmp = '*';
+ break;
+ case 0xF7: // ÷
+ *tmp = '/';
+ break;
+ case 0x82: // ‚
+ case 0xB8: // ¸
+ *tmp = ',';
+ break;
+ case 0x96: // –
+ case 0x97: // —
+ case 0xAC: // ¬
+ *tmp = '-';
+ break;
+ case 0xAF: // ¯
+ case 0xB0: // °
+ *tmp = '^';
+ break;
+ case 0x98: // ˜
+ *tmp = '~';
+ break;
+ case 0xB9: // ¹
+ *tmp = '1';
+ break;
+ case 0xB2: // ²
+ *tmp = '2';
+ break;
+ case 0xB3: // ³
+ *tmp = '3';
+ break;
+ case 0xC0: // À
+ case 0xC1: // Á
+ case 0xC2: // Â
+ case 0xC3: // Ã
+ case 0xC4: // Ä
+ case 0xC5: // Å
+ case 0xC6: // Æ
+ *tmp = 'A';
+ break;
+ case 0xAA: // ª
+ case 0xE0: // à
+ case 0xE1: // á
+ case 0xE2: // â
+ case 0xE3: // ã
+ case 0xE4: // ä
+ case 0xE5: // å
+ case 0xE6: // æ
+ *tmp = 'a';
+ break;
+ case 0xA9: // ©
+ case 0xC7: // Ç
+ *tmp = 'C';
+ break;
+ case 0xA2: // ¢
+ case 0xE7: // ç
+ *tmp = 'c';
+ break;
+ case 0xD0: // Ð
+ *tmp = 'D';
+ break;
+ case 0xF0: // ð
+ *tmp = 'd';
+ break;
+ case 0xC8: // È
+ case 0xC9: // É
+ case 0xCA: // Ê
+ case 0xCB: // Ë
+ *tmp = 'E';
+ break;
+ case 0xE8: // è
+ case 0xE9: // é
+ case 0xEA: // ê
+ case 0xEB: // ë
+ *tmp = 'e';
+ break;
+ case 0x83: // ƒ
+ *tmp = 'f';
+ break;
+ case 0xCC: // Ì
+ case 0xCD: // Í
+ case 0xCE: // Î
+ case 0xCF: // Ï
+ *tmp = 'I';
+ break;
+ case 0xA1: // ¡
+ case 0xEC: // ì
+ case 0xED: // í
+ case 0xEE: // î
+ case 0xEF: // ï
+ *tmp = 'i';
+ break;
+ case 0xD1: // Ñ
+ *tmp = 'N';
+ break;
+ case 0xF1: // ñ
+ *tmp = 'n';
+ break;
+ case 0xD2: // Ò
+ case 0xD3: // Ó
+ case 0xD4: // Ô
+ case 0xD5: // Õ
+ case 0xD6: // Ö
+ case 0xD8: // Ø
+ *tmp = 'O';
+ break;
+ case 0xF2: // ò
+ case 0xF3: // ó
+ case 0xF4: // ô
+ case 0xF5: // õ
+ case 0xF6: // ö
+ case 0xF8: // ø
+ *tmp ='o';
+ break;
+ case 0xA3: // £
+ case 0xA7: // §
+ *tmp = 'P';
+ break;
+ case 0xAE: // ®
+ *tmp = 'R';
+ break;
+ case 0x8A: // Š
+ *tmp = 'S';
+ break;
+ case 0x9A: // š
+ case 0xDF: // ß
+ *tmp = 's';
+ break;
+ case 0xDE: // Þ
+ *tmp = 'T';
+ break;
+ case 0xFE: // þ
+ *tmp = 't';
+ break;
+ case 0xD9: // Ù
+ case 0xDA: // Ú
+ case 0xDB: // Û
+ case 0xDC: // Ü
+ *tmp = 'U';
+ break;
+ case 0xB5: // µ
+ case 0xF9: // ù
+ case 0xFA: // ú
+ case 0xFB: // û
+ case 0xFC: // ü
+ *tmp = 'u';
+ break;
+ case 0xD7: // ×
+ *tmp = 'x';
+ break;
+ case 0xA5: // ¥
+ case 0xDD: // Ý
+ *tmp = 'Y';
+ break;
+ case 0xFD: // ý
+ case 0xFF: // ÿ
+ *tmp = 'y';
+ break;
+ default:
+ *tmp = '.';
+ break;
+ }
+ }
+ tmp++;
+ }
+ return out;
+}
+