Exemple #1
0
void
lo_ProcessScriptTag(MWContext *context, lo_DocState *state, PA_Tag *tag, JSObject *obj)
{
    lo_TopState *top_state;
    pa_DocData *doc_data;
    XP_Bool type_explicitly_set=FALSE;
    XP_Bool saw_archive=FALSE;
#ifdef DEBUG_ScriptPlugin
	char * mimebuf = NULL;
#endif

    top_state = state->top_state;
    doc_data = (pa_DocData *)top_state->doc_data;
    XP_ASSERT(doc_data != NULL || state->in_relayout || tag->lo_data);

    if (tag->is_end == FALSE) {
        PA_Block buff;
        char *str, *url, *archiveSrc, *id, *codebase;

        /* Controversial default language value. */
        top_state->version = JSVERSION_DEFAULT;
        if (tag->type == P_STYLE || tag->type == P_LINK) {
            top_state->in_script = top_state->default_style_script_type;
        }
        else {
            /* in order to get old script behaviour, pretend
             * that the content-type is explicitly set for all scripts
             */
            type_explicitly_set = TRUE;
            top_state->in_script = SCRIPT_TYPE_MOCHA;
        }

        /* XXX account for HTML comment bytes and  "lost" newlines */
        if (lo_IsAnyCurrentAncestorSourced(state))
            top_state->script_bytes = top_state->layout_bytes;
        else
            top_state->script_bytes = top_state->layout_bytes - tag->true_len;
        if (tag->lo_data != NULL) {
            top_state->script_bytes += (int32)tag->lo_data - 1;
            tag->lo_data = NULL;
        } 
        else if (doc_data != NULL) {
            top_state->script_bytes += doc_data->comment_bytes;
        } 
        else {
            XP_ASSERT(state->in_relayout);
        }

	lo_ParseScriptLanguage(context, tag, &top_state->in_script,
			       &top_state->version);
#ifdef DEBUG_ScriptPlugin
		if (top_state->in_script == SCRIPT_TYPE_UNKNOWN)
		{
			mimebuf = npl_Script2mimeType(context,tag);
			if (mimebuf){
				if (NPL_FindPluginEnabledForType(mimebuf)){
					top_state->in_script = SCRIPT_TYPE_PLUGIN;
					XP_ASSERT(top_state->mimetype == NULL);
					StrAllocCopy((char *)top_state->mimetype,mimebuf);
					XP_FREE(mimebuf);
					mimebuf = NULL;
				}
				else{
					XP_FREE(mimebuf);
					mimebuf = NULL;
				}
			}
		}
#endif /* DEBUG_ScriptPlugin */

        buff = lo_FetchParamValue(context, tag, PARAM_TYPE);
        if (buff != NULL) {
            PA_LOCK(str, char *, buff);
            if ((XP_STRCASECMP(str, js_content_type) == 0) ||
                (!XP_STRCASECMP(str, "text/javascript"))) {
		if(tag->type == P_STYLE || tag->type == P_LINK)
		{
		    top_state->in_script = SCRIPT_TYPE_JSSS;
		    top_state->default_style_script_type = SCRIPT_TYPE_JSSS;
		}
		else
		{
		    top_state->in_script = SCRIPT_TYPE_MOCHA;                    
		}
                type_explicitly_set = TRUE;
            } 
            else if ((XP_STRCASECMP(str, TEXT_CSS) == 0)) {
                top_state->in_script = SCRIPT_TYPE_CSS;
                top_state->default_style_script_type = SCRIPT_TYPE_CSS;
                type_explicitly_set = TRUE;
            } 
            else {
                top_state->in_script = SCRIPT_TYPE_UNKNOWN;
                top_state->default_style_script_type = SCRIPT_TYPE_UNKNOWN;
            }
            PA_UNLOCK(buff);
            PA_FREE(buff);
        } 

	/* check for media=screen
	 * don't load the style sheet if there 
	 * is a media not equal to screen
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_MEDIA);
	if (buff) {
	    if (strcasecomp((char*)buff, "screen")) {
		/* set the script type to UNKNOWN
		 * so that it will get thrown away
		 */
		top_state->in_script = SCRIPT_TYPE_UNKNOWN;
	    }
	    PA_FREE(buff);
	}

        /*
         * Flush the line buffer so we can start storing Mocha script
         * source lines in there.
         */
        lo_FlushLineBuffer(context, state);

        url = archiveSrc = id = codebase = NULL;
        if (top_state->in_script != SCRIPT_TYPE_NOT) {
            /*
             * Check for the archive parameter for known languages.
             */
            buff = lo_FetchParamValue(context, tag, PARAM_ARCHIVE);
            if (buff != NULL) {
                saw_archive = TRUE;
                PA_LOCK(str, char *, buff);
                url = NET_MakeAbsoluteURL(top_state->base_url, str);
                PA_UNLOCK(buff);
                PA_FREE(buff);
		if (url == NULL) {
                    top_state->out_of_memory = TRUE;
                    return;
		}
            }

            /* 
             * Look for ID attribute. If it's there we have may have
             * an inline signed script.
             */
            buff = lo_FetchParamValue(context, tag, PARAM_ID);
            if (buff != NULL) {
                PA_LOCK(str, char *, buff);
                StrAllocCopy(id, str);
                PA_UNLOCK(buff);
                PA_FREE(buff);
		if (id == NULL) {
                    top_state->out_of_memory = TRUE;
		    XP_FREEIF(url);
                    return;
		}
            }

            /*
             * Now look for a SRC="url" attribute for known languages.
             * If found, synchronously load the url.
             */
	    buff = lo_FetchParamValue(context, tag, PARAM_SRC);  /* XXX overloaded rv */
            if (buff != NULL) {
		XP_Bool allowFileSrc = FALSE;
                char *absUrl;

                PA_LOCK(str, char *, buff);

		PREF_GetBoolPref(lo_jsAllowFileSrcFromNonFile, &allowFileSrc);
                absUrl = NET_MakeAbsoluteURL(top_state->base_url, str);
		if (absUrl == NULL) {
		    top_state->out_of_memory = TRUE;
		    XP_FREEIF(id);
                } else if (allowFileSrc == FALSE &&
		           NET_URL_Type(absUrl) == FILE_TYPE_URL &&
		           NET_URL_Type(top_state->url) != FILE_TYPE_URL) {
		    /*
		     * Deny access from http: to file: via SCRIPT SRC=...
		     * XXX silently
		     */
                    top_state->in_script = SCRIPT_TYPE_UNKNOWN;
                    XP_FREE(absUrl);
                    XP_FREEIF(url);
		    XP_FREEIF(id);
		} else if (url != NULL) {
                    XP_FREE(absUrl);
                    StrAllocCopy(archiveSrc, str);
		    if (archiveSrc == NULL) {
			top_state->out_of_memory = TRUE;
			XP_FREE(url);
			XP_FREEIF(id);
		    }
                } else {
                    url = absUrl;
                }
                PA_UNLOCK(buff);
                PA_FREE(buff);
		if (top_state->out_of_memory)
		    return;

                /*
                 * If we are doing a <script src=""> mocha script but JS
                 *   is turned off just ignore the tag
                 */
		if (!LM_CanDoJS(context)) {
                    top_state->in_script = SCRIPT_TYPE_UNKNOWN;
                    XP_FREE(url);
		    XP_FREEIF(id);
		    XP_FREEIF(archiveSrc);
                    return;
                }
            }
        }

        /*
         * Set text_divert so we know to accumulate text in line_buf
         * without interpretation.
         */
        state->text_divert = tag->type;

        /*
         * XXX need to stack these to handle blocked SCRIPT tags
         */
        top_state->script_lineno = tag->newline_count + 1;

        /* if we got here as a result of a LINK tag
         * check to make sure rel=stylesheet and then
         * check for an HREF and if one does not exist
         * fail
         */
        if (tag->type == P_LINK) {
            char *cbuff = (char*)lo_FetchParamValue(context, tag, PARAM_REL);
                        
            if (cbuff && !strcasecomp(cbuff, "stylesheet")) {
                XP_FREE(cbuff);

                cbuff = (char*)lo_FetchParamValue(context, tag, PARAM_HREF);

                if (cbuff) {
                    if (saw_archive && url) {
                        archiveSrc = XP_STRDUP(cbuff);
                    } else {
		        XP_FREEIF(url);
                        url = NET_MakeAbsoluteURL(top_state->base_url, cbuff);
                    }
		}
            }

            XP_FREEIF(cbuff);
        }

        if (url != NULL || id != NULL || codebase != NULL) {
            if ((doc_data != NULL) &&
                (state->in_relayout == FALSE) &&
                SCRIPT_EXEC_OK(top_state, state, tag->type, P_SCRIPT)) {
                ScriptData *data;

                data = XP_ALLOC(sizeof(ScriptData));
                if (data == NULL) {
                    top_state->out_of_memory = TRUE;
                    return;
                }
                data->context = context;
                data->state = state;
                data->tag = PA_CloneMDLTag(tag);
                if (data->tag == NULL) {
                    top_state->out_of_memory = TRUE;
		    XP_FREE(data);
                    return;
                }
                data->url = url;
                data->archiveSrc = archiveSrc;
                data->id = id;
                if (codebase == NULL) {
                    StrAllocCopy(codebase, top_state->base_url);
                }
                data->codebase = codebase;
                data->buffer = NULL;
                data->bufferSize = 0;
                data->version = top_state->version;

		/*
		 * Only SCRIPT ARCHIVE= ID= without SRC= is an inline signed
		 * script -- if there is a SRC= attribute, archiveSrc will be
		 * non-null.
		 */
                data->inlineSigned = (JSBool)
		    (url != NULL && archiveSrc == NULL && id != NULL);

                /* Reset version accumulator */
                top_state->version = JSVERSION_UNKNOWN;

                XP_ASSERT (tag->type == P_SCRIPT || tag->type == P_STYLE || 
			   tag->type == P_LINK);

	        /* 
		 * Out-of-line included (by src=) or inline signed script.
		 * Save continuatation data on top_state.  If it's signed,
		 * we'll verify the signature once we see </script> and
		 * have the inline script to verify.
		 */
		top_state->scriptData = data;

            } 
	    else {
                XP_FREE(url);
		XP_FREEIF(id);
		XP_FREEIF(archiveSrc);
            }
        }
    } 
    else {

	/*
	 * We are in the </script> tag now...
	 */

        size_t line_buf_len;
        intn script_type;
        char *scope_to=NULL;
        char *untransformed = NULL;

        script_type = top_state->in_script;
        top_state->in_script = SCRIPT_TYPE_NOT;

	/* guard against superfluous end tags */
	if (script_type == SCRIPT_TYPE_NOT)
	    goto end_tag_out;

	/* convert from CSS to JavaScript here */
        if (tag->type != P_LINK && script_type == SCRIPT_TYPE_CSS) {
            char *new_buffer;
            int32 new_buffer_length;

            CSS_ConvertToJS((char *)state->line_buf, 
                            state->line_buf_len,
                            &new_buffer,
                            &new_buffer_length);

            if (!new_buffer) {
                /* css translator error, unblock layout and return */
                state->text_divert = P_UNKNOWN;
                state->line_buf_len = 0; /* clear script text */
                goto end_tag_out;
            }

            untransformed = (char *) state->line_buf;
            state->line_buf = (PA_Block) new_buffer;
            state->line_buf_len = new_buffer_length;
            state->line_buf_size = new_buffer_length;

            if (state->line_buf_len)
                state->line_buf_len--; /* hack: subtract one to remove final \n */

            script_type = SCRIPT_TYPE_JSSS;
        }

        if (tag->type == P_STYLE) {
            /* mocha scoped to document == jsss */
            scope_to = "document";
        }

        /*
         * Reset these before potentially recursing indirectly through
         * the document.write() built-in function, which writes to the
         * very same doc_data->parser_stream that this <SCRIPT> tag
         * came in on.
         */
        state->text_divert = P_UNKNOWN;
        line_buf_len = state->line_buf_len;
        state->line_buf_len = 0;

        if (script_type != SCRIPT_TYPE_UNKNOWN && 
	    script_type != SCRIPT_TYPE_NOT) {
            /*
             * If mocha is disabled or can't be done in this context we
             *   are going to just ignore the buffer contents
             */
            if (!LM_CanDoJS(context)) {
				top_state->in_script = SCRIPT_TYPE_UNKNOWN;
                goto end_tag_out;
            }

            if ((doc_data != NULL) &&
                (state->in_relayout == FALSE) &&
                SCRIPT_EXEC_OK(top_state, state, tag->type, P_SCRIPT)) {

                /*
                 * First off, make sure layout is blocking on us
                 */
                if (lo_create_script_blockage(context, state, 
					tag->type == P_SCRIPT ? LO_SCRIPT : LO_UNKNOWN)) 
				{
                    ScriptData *data;

                    /*
                     * Extreme hackery.  Hideous and shameful.  See the comment
						* in lo_BlockScriptTag before similar is_end/overflow code
						* and commence vomiting.
                     */
                    lo_BlockScriptTag(context, state, NULL);

		    if (tag->is_end == (PRPackedBool)1) {
			  PA_PushOverflow(doc_data);
			  doc_data->overflow_depth ++;
		    }

		    /*
		     * Set the document.write tag insertion point.
		     */
             top_state->input_write_point[top_state->input_write_level] = &top_state->tags;

		    data = top_state->scriptData;
                    top_state->scriptData = NULL;
                    if (data && data->url) {
			/*
			 * Three cases:
			 * 1.  SCRIPT SRC=: url non-null
			 * 2.  SCRIPT ARCHIVE= SRC=: url, archiveSrc non-null
			 * 3.  SCRIPT ARCHIVE= ID=: url, id non-null
			 * In the last case, we copy the inline script into
			 * data's buffer and let lo_script_archive_exit_fn do
			 * the eval.  We use an inlineSigned flag to avoid a
			 * bunch of (url != NULL && archiveSrc == NULL && id
			 * != NULL) tests.
			 */
			if (data->inlineSigned) {
                            StrAllocCopy(data->buffer, (char *) state->line_buf);
                            data->bufferSize = line_buf_len;
			}
			lo_GetScriptFromURL(data, script_type);
                    }
		    else {
                        JSPrincipals *principals = NULL;
			ETEvalStuff * stuff;
			
                        if (data) {
			    principals = LM_NewJSPrincipals(NULL, data->id, 
							    data->codebase);
                            if (untransformed &&
				!LM_SetUntransformedSource(principals, 
                                                           untransformed,
                                                           (char *) state->line_buf))
                            {
                                top_state->out_of_memory = TRUE;
                            }
                            lo_DestroyScriptData(data);
			}

                        /* 
                         * send the buffer off to be evaluated 
			 */
#ifdef DEBUG_ScriptPlugin
			 			if (script_type == SCRIPT_TYPE_PLUGIN)
						{
							XP_ASSERT(mimebuf == NULL);
							npl_ScriptPlugin(context, state, tag, line_buf_len,top_state->mimetype);
						    lo_unblock_script_tag(context, TRUE);
						}
						else
#endif /* DEBUG_ScriptPlugin */
 

			stuff = (ETEvalStuff *) XP_NEW_ZAP(ETEvalStuff);
			if (!stuff)
			    goto end_tag_out;

			stuff->len = line_buf_len;
			stuff->line_no = top_state->script_lineno;
			if (scope_to)
			    stuff->scope_to = XP_STRDUP(scope_to);
			else
			    stuff->scope_to = NULL;
			stuff->want_result = JS_FALSE;
			stuff->data = context;
			stuff->version = top_state->version;
			stuff->principals = principals;

                        ET_EvaluateScript(context, 
                                          (char *) state->line_buf,
					  stuff,
                                          lo_ScriptEvalExitFn);
                    }

                    /* Reset version accumulator */
                    top_state->version = JSVERSION_UNKNOWN;
                }
            }
        }
      end_tag_out:
	/*
	 * If we got a </SCRIPT> and still have scriptData set here, it must
	 *   be left over from an error case above, so we free it.
	 */
	if (top_state->scriptData) {
	    XP_ASSERT(!top_state->layout_blocking_element);
            lo_DestroyScriptData(top_state->scriptData);
	    top_state->scriptData = NULL;
	}
        XP_FREEIF(untransformed);
    }
}
Exemple #2
0
void
lo_FormatObject(MWContext* context, lo_DocState* state, PA_Tag* tag)
{
	lo_TopState* top_state = state->top_state;
	lo_ObjectStack* top;
	LO_ObjectStruct* object;
	PA_Block buff;
	int16 type = LO_NONE;
	char* str;

#ifdef	ANTHRAX
	XP_Bool javaMimetypeHandler = FALSE;
	char* appletName;
	NET_cinfo* fileInfo;
#endif /* ANTHRAX */
	
	/*
	 * Make a new default object.  Passing LO_OBJECT will create an
	 * LO_Element, which being a union of all other layout element types
	 * is guaranteed to be big enough to transmogrify into one of these
	 * specific types later if necessary.
	 */
	object = (LO_ObjectStruct*) lo_NewElement(context, state, LO_OBJECT, NULL, 0);
	if (object == NULL)
	{
		state->top_state->out_of_memory = TRUE;
		return;
	}
	
	top = top_state->object_stack;
	top->object = object;

	/*
	 * Set up default fields for this object that are common
	 * to all possible object types.
	 */
	object->lo_element.type = LO_NONE;
	object->lo_element.lo_any.ele_id = NEXT_ELEMENT;
	object->lo_element.lo_any.x = state->x;
	object->lo_element.lo_any.x_offset = 0;
	object->lo_element.lo_any.y = state->y;
	object->lo_element.lo_any.y_offset = 0;
	object->lo_element.lo_any.width = 0;
	object->lo_element.lo_any.height = 0;
	object->lo_element.lo_any.next = NULL;
	object->lo_element.lo_any.prev = NULL;

	
	/*
	 * Now attempt to figure out what type of object we have.
	 * If the type can be determined here, great; otherwise
	 * we have to block until the type can be determined by
	 * reading in additional data.
	 *
	 * Initially the type of the object is LO_NONE.  When
	 * we figure out enough to know the type, we set it to
	 * LO_EMBED, LO_JAVA, or LO_IMAGE.  If the type had
	 * already been changed to a different incompatible type,
	 * then the tag is malformed and we should ignore it, so
	 * set the type to LO_UNKNOWN.
	 */
	
#if 0 
	/*
	 * Check the "codetype" attribute, which optionally determines
	 * the MIME type of the object code itself (as opposed to its
	 * data).  The only code type we know about right now is
	 * application/java-vm for Java applets.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_CODETYPE);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		if (pa_TagEqual(APPLICATION_JAVAVM, str))
		{
			/* It's a Java applet */
			if (type == LO_NONE)
				type = LO_JAVA;
			else if (type != LO_JAVA)
				type = LO_UNKNOWN;
		}
		else if (pa_TagEqual(APPLICATION_OLEOBJECT, str) ||
				 pa_TagEqual(APPLICATION_OLEOBJECT2, str))
		{
			/* It's an OLE object */
			if (type == LO_NONE)
				type = LO_EMBED;
			else if (type != LO_EMBED)
				type = LO_UNKNOWN;
		}
		PA_UNLOCK(buff);
		XP_FREE(buff);
	}
#endif

	/*
	 * Check the "classid" attribute, which optionally determines
	 * the specific implementation of the object.  The classid
	 * could be a normal URL, in which case we have to retrieve
	 * that URL and match it against a known code type (see above).
	 * There are also two "magic" URL types supported for classid:
	 * "clsid:", which indicates a COM 376-hex-digit class ID,
	 * and "java:", which indicates a specific java class to run.
	 * Note that the "java:" URL is different from the APPLET
	 * "code" attribute: the "java:" URL specifies a particular
	 * method (e.g. "java:program.run"), while the APPLET CODE
	 * attribute specifies an applet subclass (e.g. "MyApplet.class").
     *
     * Further notes about "java:"
     * We are adding two related "magic" protocol selectors to
     * augment "java:". These are "javaprogram:" and "javabean:".
     * They are used with embedded applications and application
     * objects. "javaprogram:" identifies an object as being a
     * subclass of netscape.application.Application, and is used
     * to start an instance of such application. "javabean:" is
     * used to add an embedded object to an application.
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_CLASSID);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		if (XP_STRNCASECMP(str, "clsid:", 6) == 0)
		{
			/*
			 * It's a COM class ID, so make sure we have an
			 * appropriate plug-in to handle ActiveX controls.
			 */
			if (NPL_FindPluginEnabledForType(APPLICATION_OLEOBJECT) != NULL)
			{
				if (type == LO_NONE)
					type = LO_EMBED;
				else if (type != LO_EMBED)
					type = LO_UNKNOWN;
			}
		}
		else if ( (XP_STRNCASECMP(str, "java:", 5) == 0) ||
                  (XP_STRNCASECMP(str, "javaprogram:", 12) == 0) ||
                  (XP_STRNCASECMP(str, "javabean:", 9) == 0) )
		{
			/* It's a Java class */
			if (type == LO_NONE)
				type = LO_JAVA;
			else if (type != LO_JAVA)
				type = LO_UNKNOWN;
		}
		else
		{
			/*
			 * Must be a URL to the code; we'll need to fetch it to
			 * determine the type.  bing: How should we do this?
			 */
		}
		PA_UNLOCK(buff);
		XP_FREE(buff);
	}

	/*
	 * Check the "type" attribute, which optionally determines
	 * the type of the data for the object.  The data type
	 * can be used to infer the object implementation type if
	 * the implementation hasn't been specified via "classid"
	 * or "codetype" (see above).  The two kinds of objects
	 * we currently support with typed data are plug-ins and
	 * images; for plug-ins we can ask libplug if the type is
	 * currently handled by a plug-in; for images we just check
	 * against a hard-coded list of image types we natively
	 * support (yuck).
	 */
	buff = lo_FetchParamValue(context, tag, PARAM_TYPE);
	if (buff != NULL)
	{
		PA_LOCK(str, char *, buff);
		if (NPL_FindPluginEnabledForType(str) != NULL)
		{
			/* It's a plug-in */
			if (type == LO_NONE)
				type = LO_EMBED;
			else if (type != LO_EMBED)
				type = LO_UNKNOWN;
		}

		/*  
			Adding a check for applets that handle mimetypes.
			The pref is stored based on the particular mimetype.
			We do a lookup and if there is an association, the name
			of the applet is placed into "appletName".  
			
			NOTE: PREF_CopyCharPref() allocates memory for appletName
					and we must free it.
					
			9.23.97		amusil
		*/
#ifdef	ANTHRAX
		if((appletName = NPL_FindAppletEnabledForMimetype(str)) != NULL)
			{
			/* Set the type */
			type = LO_JAVA;
			
			/* set the CLASSID to whatever was put into "appletName" */
			lo_SetClassID(tag, appletName);
			
			/* set this so that we know later to translate the DATA/SRC param to a Java arg */
			javaMimetypeHandler = TRUE;
			XP_FREE(appletName);
			}
#endif	/* ANTHRAX */	
		
#if 0
		else if (XP_STRNCASECMP(str, "image/", 6) == 0)
		{
			if (XP_STRCASECMP(str, IMAGE_GIF) ||
				XP_STRCASECMP(str, IMAGE_JPG) ||
				XP_STRCASECMP(str, IMAGE_PJPG) ||
				XP_STRCASECMP(str, IMAGE_XBM) ||
				XP_STRCASECMP(str, IMAGE_XBM2) ||
				XP_STRCASECMP(str, IMAGE_XBM3))
			{
				/* It's an image */
				if (type == LO_NONE)
					type = LO_IMAGE;
				else if (type != LO_IMAGE)
					type = LO_UNKNOWN;
			}
		}
#endif /* if 0 */

#ifdef SHACK
		if (XP_STRNCASECMP(str, "builtin", 7) == 0)
		{
			if (type == LO_NONE)
				type = LO_EMBED;
			else if (type != LO_EMBED)
				type = LO_UNKNOWN;
		}
#endif /* SHACK */

		PA_UNLOCK(buff);
		XP_FREE(buff);
	}
#ifdef	ANTHRAX
	else /* we didn't find a TYPE param, so check the filename to get the type - amusil */
		{
		buff = lo_FetchParamValue(context, tag, PARAM_SRC);
		/* if no src, check if there's a DATA param */
		if(buff == NULL)
			buff = lo_FetchParamValue(context, tag, PARAM_DATA);
			
		
		/* extract the mimetype info */
		PA_LOCK(str, char *, buff);
		fileInfo = NET_cinfo_find_type(str);
		
		str = fileInfo->type;
		if((appletName = NPL_FindAppletEnabledForMimetype(str)) != NULL)
			{
			/* Set the type */
			type = LO_JAVA;
			
			/* set the CLASSID to whatever was put into "appletName" */
			lo_SetClassID(tag, appletName);
			
			/* set this so that we know later to translate the DATA/SRC param to a Java arg */
			javaMimetypeHandler = TRUE;
			XP_FREE(appletName);			/* do we need to free this regardless? */	
			}
		if(buff)
			XP_FREE(buff);
		}
#endif	/* ANTRHAX */


	if (type == LO_EMBED)
	{
		object->lo_element.type = LO_EMBED;
	}
#ifdef JAVA
	else if (type == LO_JAVA)
	{
		if (LJ_GetJavaEnabled() != FALSE)
		{
			/*
			 * Close out the current applet if necessary
			 * (people tend to forget "</APPLET>").
			 */
			if (state->current_java != NULL)
				lo_CloseJavaApp(context, state, state->current_java);
				
			object->lo_element.type = LO_JAVA;
			lo_FormatJavaObject(context, state, tag, (LO_JavaAppStruct*) object);
			
			/* 
				If we determined previously that this is an applet to mimetype
				association, we must set up the SRC or DATA as an arg for the 
				applet.
				
				9.8.97		amusil
			*/
#ifdef	ANTHRAX
			if(javaMimetypeHandler)
				lo_SetJavaArgs((char*)tag->data, state->current_java);
#endif	/* ANTHRAX */
		}
	}
#endif /* JAVA */
#if 0
	else if (type == LO_IMAGE)
	{
		object->type = LO_IMAGE;
		lo_FormatImageObject(context, state, tag, (LO_ImageStruct*) object);
	}
#endif /* if 0 */
	else
	{
		/*
		 * Check for a "data" attribute; if it exists, we can get
		 * the URL later to see what the type of the object should be.
		 */
		buff = lo_FetchParamValue(context, tag, PARAM_DATA);
		if (buff != NULL)
		{
			PA_LOCK(str, char *, buff);
			if (XP_STRNCASECMP(str, "data:", 5) == 0)
			{
				/* bing: deal with magic data URLs here */
				PA_UNLOCK(buff);
				XP_FREE(buff);
			}
			else
			{
				
				/*
				 * Block layout until we can read the PARAM tags
				 * and closing </OBJECT> tag, go get the data URL,
				 * and determine its type.  At that point (in
				 * either LO_NewObjectStream, or lo_ObjectURLExit),
				 * we know the object type and can unblock.
				 */
				top->data_url = str;
				state->top_state->layout_blocking_element = (LO_Element*) object;
				PA_UNLOCK(buff);
				/* Don't free buff; we stored it in the object stack */
			}
		}
		else
		{
			/*
			 * Otherwise we just don't know what to do with this!
			 */
			object->lo_element.type = LO_UNKNOWN;
		}
	}
}
static BOOL wfe_IsRegisteredForPlugin(int iFormatOut, URL_Struct *pUrlStruct, MWContext *pContext)
{
	//	Find the callers mime/type in the iFormatOut registry list,
	//  and return true if found.
	CString csMimeType = pUrlStruct->content_type;
	
	//	Find the relevant mime type in our list.
	//	There should always be a wild on the end of the list, but if not, duh.
	XP_List *list = NET_GetRegConverterList(iFormatOut);
    ContentTypeConverter *pConv;

	while(pConv = (ContentTypeConverter *)XP_ListNextObject(list))
	{
		
		//	Do a wild compare on the mime types
		if(WildMime(csMimeType, pConv->format_in))
		{
            //  May have found an appropriate converter.

            //  Only when the viewer is not automated,
            //  and the mime types are a case insensitive
            //  match, return TRUE.
			// ZZZ: Make sure it's a plug-in and not an automated viewer.
			// We're doing it this demented way because pConv->bAutomated is
			// getting stomped and points to garbage
			if ((pConv->bAutomated == FALSE) && NPL_FindPluginEnabledForType(pConv->format_in)) {
				// only check for can handle by OLE when there is no plugin register for
				// the mine type.
				// Find out can we handle by OLE.
				if (strcmp(pConv->format_in, "*") == 0) 
					/* there previously was a call to FE_FileType here, but it is clearly
					unnecessary given the check of fe_CanHandlebyOLE we've added.  byrd.
					reminder - we should overhaul/remove FE_FileType and it's other call.
					&& 
					FE_FileType(pUrlStruct->address, pUrlStruct->content_type,
									pUrlStruct->content_encoding))
									*/
				{
					if(iFormatOut == FO_EMBED){
						/* don't have to worry about FO_CACHE_AND_EMBED since cache bit cleared by NET_CacheConverter */
						/* also, don't want to interfere w/ full-page case... */
						char* ext[1];
						ext[0] = FE_FindFileExt(pUrlStruct->address);

						if(ext[0] && fe_CanHandleByOLE(ext,1))
							return FALSE;
						else
							return TRUE;
					}

					else return FALSE;
				}
				else
                    return TRUE;
            }
            //  Only when the viewer is not automated,
            //  and the handler is for wildcard MIME type,
            //  and OLE doesn't want it, return TRUE.
			// ZZZ: See above comment
            if ((pConv->bAutomated == FALSE) && XP_STRCMP(pConv->format_in, "*") == 0 &&
				NPL_FindPluginEnabledForType("*")) {
                // the following code is copied from EmbedStream(), OLE related stuff
                // BUG: this code needs to be shared code!

                // extract the extension of the file name
                char aExt[_MAX_EXT];
                size_t stExt = 0;
                DWORD dwFlags = EXT_NO_PERIOD;
                
#ifdef XP_WIN16
                dwFlags |= EXT_DOT_THREE;
#endif
                aExt[0] = '\0';
                stExt = EXT_Invent(aExt, sizeof(aExt), dwFlags, pUrlStruct->address, pUrlStruct->content_type);
                CString csFinalExtension = aExt;

                //  Check to see if the embedded file matches any known extensions.
                //  If not, then consider the file of no use to the user.
	            //	Use new way if we are in a different style of context.
                if(wfe_IsExtensionRegistrationValid(csFinalExtension, ABSTRACTCX(pContext)->GetDialogOwner(), FALSE) == FALSE) {
                    return TRUE;
                }		
            }
		}
	}
    return FALSE;
}