diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc
index 6735f5d..7b845d6 100644
--- a/utils/pdftohtml.cc
+++ b/utils/pdftohtml.cc
@@ -94,6 +94,7 @@ static GBool printVersion = gFalse;
 
 static GooString* getInfoString(Dict *infoDict, const char *key);
 static GooString* getInfoDate(Dict *infoDict, const char *key);
+static GooString* shellEscape(const char *p);
 
 static char textEncName[128] = "";
 
@@ -470,29 +471,35 @@ int main(int argc, char *argv[]) {
       /*sprintf(buf, "%s -sDEVICE=png16m -dBATCH -dNOPROMPT -dNOPAUSE -r%d -sOutputFile=%s%%03d.png -g%dx%d -q %s", GHOSTSCRIPT, resolution, htmlFileName->getCString(), w, h,
       psFileName->getCString());*/
 
+      GooString *gsDeviceEsc = shellEscape( gsDevice );
+      GooString *gsOutputFile = new GooString( htmlFileName );
+      gsOutputFile->append( "%03d." );
+      gsOutputFile->append( extension );
+      GooString *gsOutputFileEsc = shellEscape( gsOutputFile->getCString() );
+      delete gsOutputFile;
+      GooString *psFileNameEsc = shellEscape( psFileName->getCString() );
+
       GooString *gsCmd = new GooString(GHOSTSCRIPT);
       GooString *tw, *th, *sc;
+
       gsCmd->append(" -sDEVICE=");
-      gsCmd->append(gsDevice);
+      gsCmd->append(gsDeviceEsc);
       gsCmd->append(" -dBATCH -dNOPROMPT -dNOPAUSE -r");
       sc = GooString::fromInt(static_cast<int>(72*scale));
       gsCmd->append(sc);
       gsCmd->append(" -sOutputFile=");
-      gsCmd->append("\"");
-      gsCmd->append(htmlFileName);
-      gsCmd->append("%03d.");
-      gsCmd->append(extension);
-      gsCmd->append("\" -g");
+      gsCmd->append( gsOutputFileEsc );
+      gsCmd->append(" -g");
       tw = GooString::fromInt(static_cast<int>(scale*w));
       gsCmd->append(tw);
       gsCmd->append("x");
       th = GooString::fromInt(static_cast<int>(scale*h));
       th = GooString::fromInt(static_cast<int>(scale*h));
       gsCmd->append(th);
-      gsCmd->append(" -q \"");
-      gsCmd->append(psFileName);
-      gsCmd->append("\"");
-      //    printf("running: %s\n", gsCmd->getCString());
+      gsCmd->append(" -q ");
+      gsCmd->append(psFileNameEsc);
+
+      //    printf("running: [%s]\n", gsCmd->getCString());
       if( !executeCommand(gsCmd->getCString()) && !errQuiet) {
         error(errIO, -1, "Failed to launch Ghostscript!\n");
       }
@@ -501,6 +508,9 @@ int main(int argc, char *argv[]) {
       delete th;
       delete sc;
       delete gsCmd;
+      delete gsDeviceEsc;
+      delete gsOutputFileEsc;
+      delete psFileNameEsc;
       delete psFileName;
     }
   }
@@ -523,6 +533,64 @@ int main(int argc, char *argv[]) {
   return 0;
 }
 
+static GooString* shellEscape(const char *p)
+{
+  GooString *out = new GooString();
+#if defined(_WIN32)
+  // DOS: quote using double quotes
+  if (p == NULL || *p == 0) {
+	  out->append("\"\"", 2);
+	  return out;
+  }
+
+  // start double quote quotation
+  out->append('"');
+  while (*p) {
+    switch(*p) {
+    case '&':
+    case '^':
+      // ampersand is a command separator and has to be escaped with '^'
+      // same with the '^' itself
+      out->append( '^' );
+      out->append( *p );
+      break;
+    default:
+      out->append( *p );
+      break;
+    }
+    p++;
+  }
+  // stop doule quote quotation
+  out->append('"');
+#else
+  // *NIX: quote using single quotes
+  if (p == NULL || *p == 0) {
+	  out->append("''", 2);
+	  return out;
+  }
+
+  // start single quote quotation
+  out->append("'", 1);
+  while (*p) {
+    switch(*p) {
+    case '\'':
+      // one single quote to stop quotation
+      // one escaped single quote
+      // one single quote to start quotation
+      out->append( "'\\''", 4 );
+      break;
+    default:
+      out->append( p, 1 );
+      break;
+    }
+    p++;
+  }
+  // stop single quote quotation
+  out->append("'", 1);
+#endif
+  return out;
+}
+
 static GooString* getInfoString(Dict *infoDict, const char *key) {
   Object obj;
   // Raw value as read from PDF (may be in pdfDocEncoding or UCS2)
