diff options
author | Adam Domurad <[email protected]> | 2012-12-04 10:43:59 -0500 |
---|---|---|
committer | Adam Domurad <[email protected]> | 2012-12-04 10:43:59 -0500 |
commit | 1f595aba1e38b1a0113f45492288e22d3fa90799 (patch) | |
tree | 422a8d29652e3084915801fdc960c1c3099ae2a4 /plugin/icedteanp | |
parent | 7aff0a246448bef22d89859b07fef92c128e14e5 (diff) |
Remove redundant HTML-tag scanner from ITW. Do not reconstruct tags.
Diffstat (limited to 'plugin/icedteanp')
-rw-r--r-- | plugin/icedteanp/IcedTeaNPPlugin.cc | 221 | ||||
-rw-r--r-- | plugin/icedteanp/IcedTeaNPPlugin.h | 4 | ||||
-rw-r--r-- | plugin/icedteanp/java/sun/applet/PluginAppletViewer.java | 534 | ||||
-rw-r--r-- | plugin/icedteanp/java/sun/applet/PluginParameterParser.java | 90 |
4 files changed, 171 insertions, 678 deletions
diff --git a/plugin/icedteanp/IcedTeaNPPlugin.cc b/plugin/icedteanp/IcedTeaNPPlugin.cc index 302e791..19a04a2 100644 --- a/plugin/icedteanp/IcedTeaNPPlugin.cc +++ b/plugin/icedteanp/IcedTeaNPPlugin.cc @@ -229,8 +229,7 @@ static gboolean plugin_out_pipe_callback (GIOChannel* source, GIOCondition condition, gpointer plugin_data); static NPError plugin_start_appletviewer (ITNPPluginData* data); -static gchar* plugin_create_applet_tag (int16_t argc, char* argn[], - char* argv[]); +std::string plugin_parameters_string (int argc, char* argn[], char* argv[]); static void plugin_stop_appletviewer (); // Uninitialize ITNPPluginData structure static void plugin_data_destroy (NPP instance); @@ -347,7 +346,6 @@ ITNP_New (NPMIMEType pluginType, NPP instance, uint16_t mode, gchar* documentbase = NULL; gchar* read_message = NULL; - gchar* applet_tag = NULL; gchar* cookie_info = NULL; NPObject* npPluginObj = NULL; @@ -395,11 +393,10 @@ ITNP_New (NPMIMEType pluginType, NPP instance, uint16_t mode, documentbase = plugin_get_documentbase (instance); if (documentbase && argc != 0) { - // Send applet tag message to appletviewer. - applet_tag = plugin_create_applet_tag (argc, argn, argv); + // Send parameters to appletviewer. + std::string params_string = plugin_parameters_string(argc, argn, argv); - data->applet_tag = (gchar*) malloc(strlen(applet_tag)*sizeof(gchar) + strlen(documentbase)*sizeof(gchar) + 32); - g_sprintf(data->applet_tag, "tag %s %s", documentbase, applet_tag); + data->parameters_string = g_strdup_printf("tag %s %s", documentbase, params_string.c_str()); data->is_applet_instance = true; } @@ -424,33 +421,7 @@ ITNP_New (NPMIMEType pluginType, NPP instance, uint16_t mode, instance->pdata = data; - goto cleanup_done; - - cleanup_appletviewer_mutex: - g_mutex_free (data->appletviewer_mutex); - data->appletviewer_mutex = NULL; - - // cleanup_instance_string: - g_free (data->instance_id); - data->instance_id = NULL; - - // cleanup applet tag: - g_free (data->applet_tag); - data->applet_tag = NULL; - - // cleanup_data: - // Eliminate back-pointer to plugin instance. - data->owner = NULL; - (*browser_functions.memfree) (data); - data = NULL; - - // Initialization failed so return a NULL pointer for the browser - // data. - instance->pdata = NULL; - cleanup_done: - g_free (applet_tag); - applet_tag = NULL; g_free (read_message); read_message = NULL; g_free (documentbase); @@ -834,7 +805,7 @@ ITNP_SetWindow (NPP instance, NPWindow* window) // Now we have everything. Send this data to the Java side plugin_send_initialization_message( data->instance_id, (gulong) data->window_handle, - data->window_width, data->window_height, data->applet_tag); + data->window_width, data->window_height, data->parameters_string); g_mutex_unlock (data->appletviewer_mutex); @@ -1694,159 +1665,67 @@ plugin_start_appletviewer (ITNPPluginData* data) 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() + * Escape characters for passing to Java. + * "\n" for new line, "\\" for "\", "\:" for ";" */ -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)); +std::string +escape_parameter_string(const char* to_encode) { + std::string encoded; - strcpy(encoded, ""); + if (to_encode == NULL) + { + return encoded; + } - for (int i=0; i < strlen(to_encode); i++) + size_t length = strlen(to_encode); + for (int i = 0; i < length; i++) { - if (to_encode[i] == '\r') - encoded = strcat(encoded, " "); - else if (to_encode[i] == '\n') - encoded = strcat(encoded, " "); - else if (to_encode[i] == '>') - encoded = strcat(encoded, ">"); - else if (to_encode[i] == '<') - encoded = strcat(encoded, "<"); - else if (to_encode[i] == '&') - encoded = strcat(encoded, "&"); - else if (to_encode[i] == '"') - encoded = strcat(encoded, """); + if (to_encode[i] == '\n') + encoded += "\\n"; + else if (to_encode[i] == '\\') + encoded += "\\\\"; + else if (to_encode[i] == ';') + encoded += "\\:"; 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; - } + encoded += to_encode[i]; } return encoded; } -// Build up the applet tag string that we'll send to the applet -// viewer. -static gchar* -plugin_create_applet_tag (int16_t argc, char* argn[], char* argv[]) +/* + * Build a string containing an encoded list of parameters to send to the applet viewer. + * The parameters are separated as 'key1;value1;key2;value2;'. As well, they are + * separated and escaped as: + * "\n" for new line, "\\" for "\", "\:" for ";" + */ +std::string +plugin_parameters_string (int argc, char* argn[], char* argv[]) { - PLUGIN_DEBUG ("plugin_create_applet_tag\n"); - - gchar* applet_tag = g_strdup ("<EMBED "); - gchar* parameters = g_strdup (""); + PLUGIN_DEBUG ("plugin_parameters_string\n"); - for (int16_t i = 0; i < argc; i++) - { - gchar* argn_escaped = encode_string(argn[i]); - gchar* argv_escaped = encode_string(argv[i]); + std::string parameters; - if (!g_ascii_strcasecmp (argn_escaped, "code")) - { - 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_escaped, "java_code")) - { - 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_escaped, "codebase")) - { - 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_escaped, "java_codebase")) - { - 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_escaped, "classid")) - { - 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_escaped, "archive")) - { - 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_escaped, "java_archive")) - { - 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_escaped, "width")) - { - 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_escaped, "height")) + for (int i = 0; i < argc; i++) + { + if (argv[i] != NULL) { - gchar* height = g_strdup_printf ("height=\"%s\" ", argv_escaped); - applet_tag = g_strconcat (applet_tag, height, NULL); - g_free (height); - height = NULL; - } - else - { - - if (argv_escaped != '\0') - { - parameters = g_strconcat (parameters, "<PARAM NAME=\"", argn_escaped, - "\" VALUE=\"", argv_escaped, "\">", NULL); - } - } - - free(argn_escaped); - free(argv_escaped); + std::string name_escaped = escape_parameter_string(argn[i]); + std::string value_escaped = escape_parameter_string(argv[i]); - argn_escaped = NULL; - argv_escaped = NULL; + //Encode parameters and send as 'key1;value1;key2;value2;' etc + parameters += name_escaped; + parameters += ';'; + parameters += value_escaped; + parameters += ';'; } + } - applet_tag = g_strconcat (applet_tag, ">", parameters, "</EMBED>", NULL); - - g_free (parameters); - parameters = NULL; - - PLUGIN_DEBUG ("plugin_create_applet_tag return\n"); + PLUGIN_DEBUG ("plugin_parameters_string return\n"); - return applet_tag; + return parameters; } // plugin_send_message_to_appletviewer must be called while holding @@ -2057,8 +1936,8 @@ plugin_data_destroy (NPP instance) tofree->instance_id = NULL; // cleanup applet tag - g_free (tofree->applet_tag); - tofree->applet_tag = NULL; + g_free (tofree->parameters_string); + tofree->parameters_string = NULL; g_free(tofree->source); tofree->source = NULL; @@ -2537,7 +2416,7 @@ get_scriptable_object(NPP instance) // a 0 handle if (!data->window_handle) { - plugin_send_initialization_message(data->instance_id, 0, 0, 0, data->applet_tag); + plugin_send_initialization_message(data->instance_id, 0, 0, 0, data->parameters_string); } java_result = java_request.getAppletObjectInstance(id_str); diff --git a/plugin/icedteanp/IcedTeaNPPlugin.h b/plugin/icedteanp/IcedTeaNPPlugin.h index 187aede..d009e70 100644 --- a/plugin/icedteanp/IcedTeaNPPlugin.h +++ b/plugin/icedteanp/IcedTeaNPPlugin.h @@ -66,8 +66,8 @@ struct ITNPPluginData { // A unique identifier for this plugin window. gchar* instance_id; - // The applet tag sent to Java side - gchar* applet_tag; + // The parameter list string sent to Java side + gchar* parameters_string; // Mutex to protect appletviewer_alive. GMutex* appletviewer_mutex; // Back-pointer to the plugin instance to which this data belongs. diff --git a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java index f9d9422..611ed56 100644 --- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java +++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java @@ -70,7 +70,6 @@ import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; -import java.awt.Toolkit; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; @@ -87,6 +86,7 @@ import java.lang.reflect.InvocationTargetException; import java.net.SocketPermission; import java.net.URI; import java.net.URL; +import java.net.URLConnection; import java.security.AccessController; import java.security.AllPermission; import java.security.PrivilegedAction; @@ -107,6 +107,7 @@ import java.util.concurrent.locks.ReentrantLock; import javax.swing.SwingUtilities; import net.sourceforge.jnlp.NetxPanel; +import net.sourceforge.jnlp.PluginParameters; import net.sourceforge.jnlp.runtime.JNLPClassLoader; import sun.awt.AppContext; import sun.awt.SunToolkit; @@ -129,14 +130,14 @@ class PluginAppletPanelFactory { public AppletPanel createPanel(PluginStreamHandler streamhandler, final int identifier, - final long handle, int x, int y, + final long handle, final URL doc, - final Hashtable<String, String> atts) { + final PluginParameters params) { final NetxPanel panel = AccessController.doPrivileged(new PrivilegedAction<NetxPanel>() { public NetxPanel run() { - NetxPanel panel = new NetxPanel(doc, atts, false); + NetxPanel panel = new NetxPanel(doc, params, false); NetxPanel.debug("Using NetX panel"); - PluginDebug.debug(atts.toString()); + PluginDebug.debug(params.toString()); return panel; } }); @@ -146,14 +147,13 @@ class PluginAppletPanelFactory { // isn't the case, the awt eventqueue thread's context classloader // won't be set to a JNLPClassLoader, and when an applet class needs // to be loaded from the awt eventqueue, it won't be found. - final int width = Integer.parseInt(atts.get("width")); - final int height = Integer.parseInt(atts.get("height")); Thread panelInit = new Thread(panel.getThreadGroup(), new Runnable() { @Override public void run() { panel.createNewAppContext(); // create the frame. - PluginDebug.debug("X and Y are: " + width + " " + height); - panel.setAppletViewerFrame(PluginAppletViewer.framePanel(identifier,handle, width, height, panel)); + PluginDebug.debug("X and Y are: " + params.getWidth() + " " + params.getHeight()); + panel.setAppletViewerFrame(PluginAppletViewer.framePanel(identifier, handle, + params.getWidth(), params.getHeight(), panel)); panel.init(); // Start the applet @@ -194,7 +194,7 @@ class PluginAppletPanelFactory { try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { - panel.getParent().setSize(width, height); + panel.getParent().setSize(params.getWidth(), params.getHeight()); } }); } catch (InvocationTargetException ite) { @@ -599,18 +599,28 @@ public class PluginAppletViewer extends XEmbeddedFrame int spaceLocation = message.indexOf(' ', "tag".length() + 1); String documentBase = UrlUtil.decode(message.substring("tag".length() + 1, spaceLocation)); - String tag = message.substring(spaceLocation + 1); + String paramString = message.substring(spaceLocation + 1); PluginDebug.debug("Handle = ", handle, "\n", "Width = ", width, "\n", "Height = ", height, "\n", "DocumentBase = ", documentBase, "\n", - "Tag = ", tag); + "Params = ", paramString); - PluginAppletViewer.parse - (identifier, handle, width, height, - new StringReader(tag), - new URL(documentBase)); + PluginAppletPanelFactory factory = new PluginAppletPanelFactory(); + AppletMessageHandler amh = new AppletMessageHandler("appletviewer"); + URL url = new URL(documentBase); + URLConnection conn = url.openConnection(); + /* The original URL may have been redirected - this + * sets it to whatever URL/codebase we ended up getting + */ + url = conn.getURL(); + + PluginParameters params = new PluginParameterParser().parse(width, height, paramString); + + // Let user know we are starting up + streamhandler.write("instance " + identifier + " status " + amh.getMessage("status.start")); + factory.createPanel(streamhandler, identifier, handle, url, params); long maxTimeToSleep = APPLET_TIMEOUT; appletsLock.lock(); @@ -1546,24 +1556,6 @@ public class PluginAppletViewer extends XEmbeddedFrame } /** - * 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(">", ">"); - toDecode = toDecode.replace("<", "<"); - toDecode = toDecode.replace("&", "&"); - toDecode = toDecode.replace(" ", "\n"); - toDecode = toDecode.replace(" ", "\r"); - toDecode = toDecode.replace(""", "\""); - - return toDecode; - } - - /** * System parameters. */ static Hashtable<String, String> systemParam = new Hashtable<String, String>(); @@ -1580,76 +1572,14 @@ public class PluginAppletViewer extends XEmbeddedFrame } /** - * Print the HTML tag. - */ - public static void printTag(PrintStream out, Hashtable<String, String> atts) { - out.print("<applet"); - - String v = atts.get("codebase"); - if (v != null) { - out.print(" codebase=\"" + v + "\""); - } - - v = atts.get("code"); - if (v == null) { - v = "applet.class"; - } - out.print(" code=\"" + v + "\""); - v = atts.get("width"); - if (v == null) { - v = "150"; - } - out.print(" width=" + v); - - v = atts.get("height"); - if (v == null) { - v = "100"; - } - out.print(" height=" + v); - - v = atts.get("name"); - if (v != null) { - out.print(" name=\"" + v + "\""); - } - out.println(">"); - - // A very slow sorting algorithm - int len = atts.size(); - String params[] = new String[len]; - len = 0; - for (Enumeration<String> e = atts.keys(); e.hasMoreElements();) { - String param = e.nextElement(); - int i = 0; - for (; i < len; i++) { - if (params[i].compareTo(param) >= 0) { - break; - } - } - System.arraycopy(params, i, params, i + 1, len - i); - params[i] = param; - len++; - } - - for (int i = 0; i < len; i++) { - String param = params[i]; - if (systemParam.get(param) == null) { - out.println("<param name=" + param + - " value=\"" + atts.get(param) + "\">"); - } - } - out.println("</applet>"); - } - - /** * Make sure the atrributes are uptodate. */ public void updateAtts() { Dimension d = panel.getSize(); Insets in = panel.getInsets(); - panel.atts.put("width", - Integer.valueOf(d.width - (in.left + in.right)).toString()); - panel.atts.put("height", - Integer.valueOf(d.height - (in.top + in.bottom)).toString()); + int width = d.width - (in.left + in.right); + int height = d.height - (in.top + in.bottom); + panel.updateSizeInAtts(height, width); } /** @@ -1796,412 +1726,6 @@ public class PluginAppletViewer extends XEmbeddedFrame return appletPanels.size(); } - /** - * Scan spaces. - */ - public static void skipSpace(int[] c, Reader in) throws IOException { - while ((c[0] >= 0) && - ((c[0] == ' ') || (c[0] == '\t') || (c[0] == '\n') || (c[0] == '\r'))) { - c[0] = in.read(); - } - } - - /** - * Scan identifier - */ - public static String scanIdentifier(int[] c, Reader in) throws IOException { - StringBuilder buf = new StringBuilder(); - - if (c[0] == '!') { - // Technically, we should be scanning for '!--' but we are reading - // from a stream, and there is no way to peek ahead. That said, - // a ! at this point can only mean comment here afaik, so we - // should be okay - skipComment(c, in); - return ""; - } - - while (true) { - if (((c[0] >= 'a') && (c[0] <= 'z')) || - ((c[0] >= 'A') && (c[0] <= 'Z')) || - ((c[0] >= '0') && (c[0] <= '9')) || (c[0] == '_')) { - buf.append((char) c[0]); - c[0] = in.read(); - } else { - return buf.toString(); - } - } - } - - public static void skipComment(int[] c, Reader in) throws IOException { - StringBuilder buf = new StringBuilder(); - boolean commentHeaderPassed = false; - c[0] = in.read(); - buf.append((char) c[0]); - - while (true) { - if (c[0] == '-' && (c[0] = in.read()) == '-') { - buf.append((char) c[0]); - if (commentHeaderPassed) { - // -- encountered ... is > next? - if ((c[0] = in.read()) == '>') { - buf.append((char) c[0]); - - PluginDebug.debug("Comment skipped: ", buf.toString()); - - // comment skipped. - return; - } - } else { - // first -- is part of <!-- ... , just mark that we have passed it - commentHeaderPassed = true; - } - - } else if (commentHeaderPassed == false) { - buf.append((char) c[0]); - PluginDebug.debug("Warning: Attempted to skip comment, but this tag does not appear to be a comment: ", buf.toString()); - return; - } - - c[0] = in.read(); - buf.append((char) c[0]); - } - } - - /** - * Scan tag - */ - public static Hashtable<String, String> scanTag(int[] c, Reader in) throws IOException { - Hashtable<String, String> atts = new Hashtable<String, String>(); - skipSpace(c, in); - while (c[0] >= 0 && c[0] != '>') { - String att = decodeString(scanIdentifier(c, in)); - String val = ""; - skipSpace(c, in); - if (c[0] == '=') { - int quote = -1; - c[0] = in.read(); - skipSpace(c, in); - if ((c[0] == '\'') || (c[0] == '\"')) { - quote = c[0]; - c[0] = in.read(); - } - StringBuilder buf = new StringBuilder(); - while ((c[0] > 0) && - (((quote < 0) && (c[0] != ' ') && (c[0] != '\t') && - (c[0] != '\n') && (c[0] != '\r') && (c[0] != '>')) - || ((quote >= 0) && (c[0] != quote)))) { - buf.append((char) c[0]); - c[0] = in.read(); - } - if (c[0] == quote) { - c[0] = in.read(); - } - skipSpace(c, in); - val = decodeString(buf.toString()); - } - - PluginDebug.debug("PUT ", att, " = '", val, "'"); - atts.put(att.toLowerCase(java.util.Locale.ENGLISH), val); - - while (true) { - if ((c[0] == '>') || (c[0] < 0) || - ((c[0] >= 'a') && (c[0] <= 'z')) || - ((c[0] >= 'A') && (c[0] <= 'Z')) || - ((c[0] >= '0') && (c[0] <= '9')) || (c[0] == '_')) - break; - c[0] = in.read(); - } - //skipSpace(in); - } - return atts; - } - - // private static final == inline - private static final boolean isInt(Object o) { - boolean isInt = false; - try { - Integer.parseInt((String) o); - isInt = true; - } catch (Exception e) { - // don't care - } - - return isInt; - } - - /* values used for placement of AppletViewer's frames */ - private static int x = 0; - private static int y = 0; - private static final int XDELTA = 30; - private static final int YDELTA = XDELTA; - - static String encoding = null; - - /** - * Scan an html file for <applet> tags - */ - public static void parse(int identifier, long handle, String width, String height, Reader in, URL url, String enc) - throws IOException { - encoding = enc; - parse(identifier, handle, width, height, in, url, System.out, new PluginAppletPanelFactory()); - } - - public static void parse(int identifier, long handle, String width, String height, Reader in, URL url) - throws PrivilegedActionException { - - final int fIdentifier = identifier; - final long fHandle = handle; - final String fWidth = width; - final String fHeight = height; - final Reader fIn = in; - final URL fUrl = url; - AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { - public Void run() throws IOException { - parse(fIdentifier, fHandle, fWidth, fHeight, fIn, fUrl, - System.out, new PluginAppletPanelFactory()); - return null; - } - }); - } - - @SuppressWarnings("unused") - public static void parse(int identifier, long handle, String width, - String height, Reader in, URL url, - PrintStream statusMsgStream, - PluginAppletPanelFactory factory) - throws IOException { - boolean isObjectTag = false; - boolean objectTagAlreadyParsed = false; - - // The current character - // FIXME: This is an evil hack to force pass-by-reference.. the - // parsing code needs to be rewritten from scratch to prevent such - //a need - int[] c = new int[1]; - - // warning messages - String requiresNameWarning = amh.getMessage("parse.warning.requiresname"); - String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside"); - String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode"); - String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight"); - String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth"); - String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode"); - String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight"); - String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth"); - String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode"); - String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight"); - String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth"); - String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported"); - - java.net.URLConnection conn = url.openConnection(); - /* The original URL may have been redirected - this - * sets it to whatever URL/codebase we ended up getting - */ - url = conn.getURL(); - - int ydisp = 1; - Hashtable<String, String> atts = null; - - while (true) { - c[0] = in.read(); - if (c[0] == -1) - break; - - if (c[0] == '<') { - c[0] = in.read(); - if (c[0] == '/') { - c[0] = in.read(); - String nm = scanIdentifier(c, in); - if (nm.equalsIgnoreCase("applet") || - nm.equalsIgnoreCase("object") || - nm.equalsIgnoreCase("embed")) { - - // We can't test for a code tag until </OBJECT> - // because it is a parameter, not an attribute. - if (isObjectTag) { - if (atts.get("code") == null && atts.get("object") == null) { - statusMsgStream.println(objectRequiresCodeWarning); - atts = null; - } - } - - if (atts != null) { - // XXX 5/18 In general this code just simply - // shouldn't be part of parsing. It's presence - // causes things to be a little too much of a - // hack. - - // Let user know we are starting up - streamhandler.write("instance " + identifier + " status " + amh.getMessage("status.start")); - factory.createPanel(streamhandler, identifier, handle, x, y, url, atts); - - x += XDELTA; - y += YDELTA; - // make sure we don't go too far! - Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); - if ((x > d.width - 300) || (y > d.height - 300)) { - x = 0; - y = 2 * ydisp * YDELTA; - ydisp++; - } - } - atts = null; - isObjectTag = false; - } - } else { - String nm = scanIdentifier(c, in); - if (nm.equalsIgnoreCase("param")) { - Hashtable<String, String> t = scanTag(c, in); - String att = t.get("name"); - - if (att == null) { - statusMsgStream.println(requiresNameWarning); - } else { - String val = t.get("value"); - if (val == null) { - statusMsgStream.println(requiresNameWarning); - } else { - PluginDebug.debug("PUT ", att, " = ", val); - atts.put(att.toLowerCase(), val); - } - } - } else if (nm.equalsIgnoreCase("applet")) { - atts = scanTag(c, in); - - // If there is a classid and no code tag present, transform it to code tag - if (atts.get("code") == null && atts.get("classid") != null - && !(atts.get("classid")).startsWith("clsid:")) { - atts.put("code", atts.get("classid")); - } - - // remove java: from code tag - if (atts.get("code") != null && (atts.get("code")).startsWith("java:")) { - atts.put("code", (atts.get("code")).substring(5)); - } - - if (atts.get("code") == null && atts.get("object") == null) { - statusMsgStream.println(appletRequiresCodeWarning); - atts = null; - } - - if (atts.get("width") == null || !isInt(atts.get("width"))) { - atts.put("width", width); - } - - if (atts.get("height") == null || !isInt(atts.get("height"))) { - atts.put("height", height); - } - } else if (nm.equalsIgnoreCase("object")) { - isObjectTag = true; - - // Once code is set, additional nested objects are ignored - if (!objectTagAlreadyParsed) { - objectTagAlreadyParsed = true; - atts = scanTag(c, in); - } - - // If there is a classid and no code tag present, transform it to code tag - if (atts.get("code") == null && atts.get("classid") != null - && !(atts.get("classid")).startsWith("clsid:")) { - atts.put("code", atts.get("classid")); - } - - // remove java: from code tag - if (atts.get("code") != null && (atts.get("code")).startsWith("java:")) { - atts.put("code", (atts.get("code")).substring(5)); - } - - // java_* aliases override older names: - // http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/using_tags.html#in-ie - if (atts.get("java_code") != null) { - atts.put("code", (atts.get("java_code"))); - } - - if (atts.containsKey("code")) { - objectTagAlreadyParsed = true; - } - - if (atts.get("java_codebase") != null) { - atts.put("codebase", (atts.get("java_codebase"))); - } - - if (atts.get("java_archive") != null) { - atts.put("archive", (atts.get("java_archive"))); - } - - if (atts.get("java_object") != null) { - atts.put("object", (atts.get("java_object"))); - } - - if (atts.get("java_type") != null) { - atts.put("type", (atts.get("java_type"))); - } - - if (atts.get("width") == null || !isInt(atts.get("width"))) { - atts.put("width", width); - } - - if (atts.get("height") == null || !isInt(atts.get("height"))) { - atts.put("height", height); - } - } else if (nm.equalsIgnoreCase("embed")) { - atts = scanTag(c, in); - - // If there is a classid and no code tag present, transform it to code tag - if (atts.get("code") == null && atts.get("classid") != null - && !(atts.get("classid")).startsWith("clsid:")) { - atts.put("code", atts.get("classid")); - } - - // remove java: from code tag - if (atts.get("code") != null && (atts.get("code")).startsWith("java:")) { - atts.put("code", (atts.get("code")).substring(5)); - } - - // java_* aliases override older names: - // http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/using_tags.html#in-nav - if (atts.get("java_code") != null) { - atts.put("code", (atts.get("java_code"))); - } - - if (atts.get("java_codebase") != null) { - atts.put("codebase", (atts.get("java_codebase"))); - } - - if (atts.get("java_archive") != null) { - atts.put("archive", (atts.get("java_archive"))); - } - - if (atts.get("java_object") != null) { - atts.put("object", (atts.get("java_object"))); - } - - if (atts.get("java_type") != null) { - atts.put("type", (atts.get("java_type"))); - } - - if (atts.get("code") == null && atts.get("object") == null) { - statusMsgStream.println(embedRequiresCodeWarning); - atts = null; - } - - if (atts.get("width") == null || !isInt(atts.get("width"))) { - atts.put("width", width); - } - - if (atts.get("height") == null || !isInt(atts.get("height"))) { - atts.put("height", height); - } - - } - } - } - } - in.close(); - } - - private static AppletMessageHandler amh = new AppletMessageHandler("appletviewer"); private static void checkConnect(URL url) { SecurityManager security = System.getSecurityManager(); diff --git a/plugin/icedteanp/java/sun/applet/PluginParameterParser.java b/plugin/icedteanp/java/sun/applet/PluginParameterParser.java new file mode 100644 index 0000000..9ce578f --- /dev/null +++ b/plugin/icedteanp/java/sun/applet/PluginParameterParser.java @@ -0,0 +1,90 @@ +package sun.applet; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.jnlp.PluginParameters; + +class PluginParameterParser { + static private final char DELIMITER_ESCAPE = ':'; + static private final String KEY_VALUE_DELIMITER = ";"; + + /** + * Unescape characters passed from C++. + * Specifically, "\n" -> new line, "\\" -> "\", "\:" -> ";" + * + * @param str The string to unescape + * @return The unescaped string + */ + static String unescapeString(String str) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < str.length(); i++) { + char chr = str.charAt(i); + if (chr != '\\') { + sb.append(chr); + } else { + i++; // Skip ahead one + chr = str.charAt(i); + if (chr == 'n') { + sb.append('\n'); + } else if (chr == '\\') { + sb.append('\\'); + } else if (chr == DELIMITER_ESCAPE) { + sb.append(KEY_VALUE_DELIMITER); + } + } + } + return sb.toString(); + } + + /** + * Parse semi-colon delimited key-value pairs. + * @param keyvalString the escaped, semicolon-delimited, string + * @return a map of the keys to the values + */ + static Map<String, String> parseEscapedKeyValuePairs(String keyvalString) { + // Split on ';', ensuring empty strings at end are kept + String[] strs = keyvalString.split(KEY_VALUE_DELIMITER, -1 /* Keep empty strings */); + System.out.println("Split array: " + Arrays.toString(strs)); + + Map<String, String> attributes = new HashMap<String, String>(); + + /* Note that we will typically have one empty string at end */ + for (int i = 0; i < strs.length - 1; i += 2) { + String key = unescapeString(strs[i]).toLowerCase(); + String value = unescapeString(strs[i + 1]); + attributes.put(key, value); + } + + return attributes; + } + + static boolean isInt(String s) { + return s.matches("^-?\\d+$"); + } + + /** + * Parsers parameters given a string containing + * parameters in quotes. + * + * @param width default applet width + * @param height default applet height + * @param parameterString the parameters + * @return the attributes in a hash table + */ + public PluginParameters parse(String width, + String height, String parameterString) { + Map<String, String> params = parseEscapedKeyValuePairs(parameterString); + + if (params.get("width") == null || !isInt(params.get("width"))) { + params.put("width", width); + } + + if (params.get("height") == null || !isInt(params.get("height"))) { + params.put("height", height); + } + + return new PluginParameters(params); + } +} |