changeset 78:45c967939b39

PR597: Fix special character handling for applet tags
author Deepak Bhole <dbhole@redhat.com>
date Wed, 08 Dec 2010 16:08:35 -0500
parents 964617719f05
children e9150d5accf6
files ChangeLog NEWS plugin/icedteanp/IcedTeaNPPlugin.cc plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
diffstat 4 files changed, 118 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Dec 08 14:06:22 2010 -0500
+++ b/ChangeLog	Wed Dec 08 16:08:35 2010 -0500
@@ -1,3 +1,19 @@
+2010-12-08  Deepak Bhole <dbhole@redhat.com>
+
+	PR597: Entities are parsed incorrectly in PARAM tag in applet plugin
+	* plugin/icedteanp/IcedTeaNPPlugin.cc
+	(encode_string): New function. Takes a string and replaces certain special
+	characters with html escapes.
+	(plugin_create_applet_tag): Use the new encode_string function to encode
+	argn and argv right away, rather than encoding the whole tag.
+	* plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
+	(handleMessage): Move decoding out so that it is done after parsing.
+	(decodeString): New function. Decodes the given string such that html
+	escapes are replaced by the original special characters.
+	(scanTag): Decode parameter name and value before adding it to attribute
+	array.
+	* NEWS: Updated.
+
 2010-12-08  Omair Majid  <omajid@redhat.com>
 
 	* configure.ac: Add check for sun.misc.HexDumpEncoder
--- a/NEWS	Wed Dec 08 14:06:22 2010 -0500
+++ b/NEWS	Wed Dec 08 16:08:35 2010 -0500
@@ -21,6 +21,7 @@
   - PR557: Applet opens in a separate window if tab is closed when the applet loads
   - PR565: UIDefaults.getUI fails with jgoodies:looks 2.3.1
   - PR593: Increment of invalidated iterator in IcedTeaPluginUtils (patch from barbara.xxx1975@libero.it)
+  - PR597: Entities are parsed incorrectly in PARAM tag in applet plugin
   - Applets are now double-buffered to eliminate flicker in ones that do heavy drawing
 * NetX
   - Add a new option -Xclearcache
--- a/plugin/icedteanp/IcedTeaNPPlugin.cc	Wed Dec 08 14:06:22 2010 -0500
+++ b/plugin/icedteanp/IcedTeaNPPlugin.cc	Wed Dec 08 16:08:35 2010 -0500
@@ -1617,6 +1617,56 @@
   return error;
 }
 
+/*
+ * Replaces certain characters (\r, \n, etc) with HTML escape equivalents.
+ *
+ * Return string is allocated on the heap. Caller assumes responsibility 
+ * for freeing the memory via free()
+ */
+static char*
+encode_string(char* to_encode)
+{
+
+  // Do nothing for an empty string
+  if (to_encode == '\0')
+      return to_encode;
+
+  // worst case scenario -> all characters are newlines or
+  // returns, each of which translates to 5 substitutions
+  char* encoded = (char*) calloc(((strlen(to_encode)*5)+1), sizeof(char));
+
+  strcpy(encoded, "");
+
+  for (int i=0; i < strlen(to_encode); i++)
+  {
+      if (to_encode[i] == '\r')
+          encoded = strcat(encoded, "&#13;");
+      else if (to_encode[i] == '\n')
+          encoded = strcat(encoded, "&#10;");
+      else if (to_encode[i] == '>')
+          encoded = strcat(encoded, "&gt;");
+      else if (to_encode[i] == '<')
+          encoded = strcat(encoded, "&lt;");
+      else if (to_encode[i] == '&')
+          encoded = strcat(encoded, "&amp;");
+      else if (to_encode[i] == '"')
+          encoded = strcat(encoded, "&quot;");
+      else
+      {
+           char* orig_char = (char*) calloc(2, sizeof(char));
+           orig_char[0] = to_encode[i];
+           orig_char[1] = '\0';
+ 
+           strcat(encoded, orig_char);
+ 
+           free(orig_char);
+           orig_char = NULL;
+      }
+  }
+
+  return encoded;
+}
+
 // Build up the applet tag string that we'll send to the applet
 // viewer.
 static gchar*
@@ -1629,65 +1679,68 @@
 
   for (int16_t i = 0; i < argc; i++)
     {
-      if (!g_ascii_strcasecmp (argn[i], "code"))
+      gchar* argn_escaped = encode_string(argn[i]);
+      gchar* argv_escaped = encode_string(argv[i]);
+
+      if (!g_ascii_strcasecmp (argn_escaped, "code"))
         {
-          gchar* code = g_strdup_printf ("CODE=\"%s\" ", argv[i]);
+          gchar* code = g_strdup_printf ("CODE=\"%s\" ", argv_escaped);
           applet_tag = g_strconcat (applet_tag, code, NULL);
           g_free (code);
           code = NULL;
     }
-      else if (!g_ascii_strcasecmp (argn[i], "java_code"))
+      else if (!g_ascii_strcasecmp (argn_escaped, "java_code"))
     {
-          gchar* java_code = g_strdup_printf ("JAVA_CODE=\"%s\" ", argv[i]);
+          gchar* java_code = g_strdup_printf ("JAVA_CODE=\"%s\" ", argv_escaped);
           applet_tag = g_strconcat (applet_tag, java_code, NULL);
           g_free (java_code);
           java_code = NULL;
     }
-      else if (!g_ascii_strcasecmp (argn[i], "codebase"))
+      else if (!g_ascii_strcasecmp (argn_escaped, "codebase"))
     {
-          gchar* codebase = g_strdup_printf ("CODEBASE=\"%s\" ", argv[i]);
+          gchar* codebase = g_strdup_printf ("CODEBASE=\"%s\" ", argv_escaped);
           applet_tag = g_strconcat (applet_tag, codebase, NULL);
           g_free (codebase);
           codebase = NULL;
     }
-      else if (!g_ascii_strcasecmp (argn[i], "java_codebase"))
+      else if (!g_ascii_strcasecmp (argn_escaped, "java_codebase"))
     {
-          gchar* java_codebase = g_strdup_printf ("JAVA_CODEBASE=\"%s\" ", argv[i]);
+          gchar* java_codebase = g_strdup_printf ("JAVA_CODEBASE=\"%s\" ", argv_escaped);
           applet_tag = g_strconcat (applet_tag, java_codebase, NULL);
           g_free (java_codebase);
           java_codebase = NULL;
     }
-      else if (!g_ascii_strcasecmp (argn[i], "classid"))
+      else if (!g_ascii_strcasecmp (argn_escaped, "classid"))
     {
-          gchar* classid = g_strdup_printf ("CLASSID=\"%s\" ", argv[i]);
+          gchar* classid = g_strdup_printf ("CLASSID=\"%s\" ", argv_escaped);
           applet_tag = g_strconcat (applet_tag, classid, NULL);
           g_free (classid);
           classid = NULL;
     }
-      else if (!g_ascii_strcasecmp (argn[i], "archive"))
+      else if (!g_ascii_strcasecmp (argn_escaped, "archive"))
     {
-          gchar* archive = g_strdup_printf ("ARCHIVE=\"%s\" ", argv[i]);
+          gchar* archive = g_strdup_printf ("ARCHIVE=\"%s\" ", argv_escaped);
           applet_tag = g_strconcat (applet_tag, archive, NULL);
           g_free (archive);
           archive = NULL;
     }
-      else if (!g_ascii_strcasecmp (argn[i], "java_archive"))
+      else if (!g_ascii_strcasecmp (argn_escaped, "java_archive"))
     {
-          gchar* java_archive = g_strdup_printf ("JAVA_ARCHIVE=\"%s\" ", argv[i]);
+          gchar* java_archive = g_strdup_printf ("JAVA_ARCHIVE=\"%s\" ", argv_escaped);
           applet_tag = g_strconcat (applet_tag, java_archive, NULL);
           g_free (java_archive);
           java_archive = NULL;
     }
-      else if (!g_ascii_strcasecmp (argn[i], "width"))
+      else if (!g_ascii_strcasecmp (argn_escaped, "width"))
     {
-          gchar* width = g_strdup_printf ("width=\"%s\" ", argv[i]);
+          gchar* width = g_strdup_printf ("width=\"%s\" ", argv_escaped);
           applet_tag = g_strconcat (applet_tag, width, NULL);
           g_free (width);
           width = NULL;
     }
-      else if (!g_ascii_strcasecmp (argn[i], "height"))
+      else if (!g_ascii_strcasecmp (argn_escaped, "height"))
     {
-          gchar* height = g_strdup_printf ("height=\"%s\" ", argv[i]);
+          gchar* height = g_strdup_printf ("height=\"%s\" ", argv_escaped);
           applet_tag = g_strconcat (applet_tag, height, NULL);
           g_free (height);
           height = NULL;
@@ -1695,58 +1748,28 @@
       else
         {
 
-          if (argv[i] != '\0')
+          if (argv_escaped != '\0')
             {
-              parameters = g_strconcat (parameters, "<PARAM NAME=\"", argn[i],
-                                        "\" VALUE=\"", argv[i], "\">", NULL);
+              parameters = g_strconcat (parameters, "<PARAM NAME=\"", argn_escaped,
+                                        "\" VALUE=\"", argv_escaped, "\">", NULL);
             }
         }
+
+      free(argn_escaped);
+      free(argv_escaped);
+
+      argn_escaped = NULL;
+      argv_escaped = NULL;
     }
 
   applet_tag = g_strconcat (applet_tag, ">", parameters, "</EMBED>", NULL);
 
-  // Escape the parameter value so that line termination
-  // characters will pass through the pipe.
-          
-  // worst case scenario -> all characters are newlines or
-  // returns, each of which translates to 5 substitutions
-  char* applet_tag_escaped = (char*) calloc(((strlen(applet_tag)*5)+1), sizeof(char));
-
-  strcpy(applet_tag_escaped, "");
-  for (int i=0; i < strlen(applet_tag); i++)
-  {
-      if (applet_tag[i] == '\r')
-          strcat(applet_tag_escaped, "&#13;");
-      else if (applet_tag[i] == '\n')
-          strcat(applet_tag_escaped, "&#10;");
-      else if (applet_tag[i] == '>')
-          strcat(applet_tag_escaped, "&gt;");
-      else if (applet_tag[i] == '<')
-          strcat(applet_tag_escaped, "&lt;");
-      else if (applet_tag[i] == '&')
-          strcat(applet_tag_escaped, "&amp;");
-      else
-      {
-          char* orig_char = (char*) calloc(2, sizeof(char));
-          orig_char[0] = applet_tag[i];
-          orig_char[1] = '\0';
-
-          strcat(applet_tag_escaped, orig_char);
-
-          free(orig_char);
-          orig_char = NULL;
-      }
-  }
-
-  free (applet_tag);
-  applet_tag = NULL;
-
   g_free (parameters);
   parameters = NULL;
 
   PLUGIN_DEBUG ("plugin_create_applet_tag return\n");
 
-  return applet_tag_escaped;
+  return applet_tag;
 }
 
 // plugin_send_message_to_appletviewer must be called while holding
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java	Wed Dec 08 14:06:22 2010 -0500
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java	Wed Dec 08 16:08:35 2010 -0500
@@ -514,14 +514,6 @@
                         UrlUtil.decode(message.substring("tag".length() + 1, spaceLocation));
                 String tag = message.substring(spaceLocation + 1);
 
-                // Decode the tag
-                tag = tag.replace("&gt;", ">");
-                tag = tag.replace("&lt;", "<");
-                tag = tag.replace("&amp;", "&");
-                tag = tag.replace("&#10;", "\n");
-                tag = tag.replace("&#13;", "\r");
-                tag = tag.replace("&quot;", "\"");
-
                 PluginDebug.debug("Handle = " + handle + "\n" +
                                     "Width = " + width + "\n" +
                                     "Height = " + height + "\n" +
@@ -1454,6 +1446,24 @@
     }
 
     /**
+     * Decodes the string (converts html escapes into proper characters)
+     * 
+     * @param toDecode The string to decode
+     * @return The decoded string
+     */
+    public static String decodeString(String toDecode) {
+
+        toDecode = toDecode.replace("&gt;", ">");
+        toDecode = toDecode.replace("&lt;", "<");
+        toDecode = toDecode.replace("&amp;", "&");
+        toDecode = toDecode.replace("&#10;", "\n");
+        toDecode = toDecode.replace("&#13;", "\r");
+        toDecode = toDecode.replace("&quot;", "\"");
+
+        return toDecode;
+    }
+    
+    /**
      * System parameters.
      */
     static Hashtable<String, String> systemParam = new Hashtable<String, String>();
@@ -1752,7 +1762,7 @@
         Hashtable<String, String> atts = new Hashtable<String, String>();
         skipSpace(c, in);
         while (c[0] >= 0 && c[0] != '>') {
-            String att = scanIdentifier(c, in);
+            String att = decodeString(scanIdentifier(c, in));
             String val = "";
             skipSpace(c, in);
             if (c[0] == '=') {
@@ -1775,7 +1785,7 @@
                     c[0] = in.read();
                 }
                 skipSpace(c, in);
-                val = buf.toString();
+                val = decodeString(buf.toString());
             }
 
             PluginDebug.debug("PUT " + att + " = '" + val + "'");