Ejemplo n.º 1
0
bool MCImageDecode(const uint8_t *p_data, uindex_t p_size, MCImageFrame *&r_frames, uindex_t &r_frame_count)
{
	bool t_success = true;

	IO_handle t_stream = nil;

	t_success = nil != (t_stream = MCS_fakeopen(MCString((const char*)p_data, p_size)));

	if (t_success)
		t_success = MCImageDecode(t_stream, r_frames, r_frame_count);

	if (t_stream != nil)
		MCS_close(t_stream);

	return t_success;
}
Ejemplo n.º 2
0
// This is a helper method for the V1 externals interface. It ensures that the
// string is terminated by a NUL, but without affecting the value's size. It
// must only be called on value's which are already strings.
bool MCVariableValue::ensure_cstring(void)
{
	if (strnum . buffer . size != 0 &&
		strnum . svalue . length < strnum . buffer . size)
	{
		strnum . buffer . data[strnum . svalue . length] = '\0';
		return true;
	}
	
	if (!append_string(MCString("\0", 1)))
		return false;

	strnum . svalue . length -= 1;

	return true;
}
Ejemplo n.º 3
0
void MCUrlLoadEvent::Dispatch(void)
{
    MCObject *t_object;
    t_object = m_object -> Get();
    if (t_object != nil)
    {
        switch (m_status)
        {
        case kMCSystemUrlStatusFinished:
            t_object -> message_with_args(m_message, m_url, "downloaded", MCString(static_cast<char*>(m_data.bytes), m_data.size));
            break;
        case kMCSystemUrlStatusError:
            t_object -> message_with_args(m_message, m_url, "error", m_error);
            break;
        }
    }
}
Ejemplo n.º 4
0
static void MCFontDrawTextCallback(MCFontRef p_font, const char *p_text, uint32_t p_length, bool p_is_unicode, font_draw_text_context *ctxt)
{
    MCGFont t_font;
	t_font = MCFontStructToMCGFont(p_font->fontstruct);
	
	// MW-2013-12-04: [[ Bug 11535 ]] Pass through the fixed advance.
	t_font . fixed_advance = p_font -> fixed_advance;
	
	// MW-2013-12-04: [[ Bug 11549 ]] Make sure unicode text is short-aligned.
	MCExecPoint ep;
	ep . setsvalue(MCString(p_text, p_length));
	if (!p_is_unicode)
		ep . nativetoutf16();
	else if ((((uintptr_t)ep . getsvalue() . getstring()) & 1) != 0)
		ep . grabsvalue();
	
	MCGContextDrawPlatformText(ctxt->m_gcontext, (unichar_t *) ep . getsvalue() . getstring(), ep . getsvalue() . getlength(), MCGPointMake(ctxt->x, ctxt->y), t_font);
    
    // The draw position needs to be advanced. Can this be done more efficiently?
    ctxt -> x += MCGContextMeasurePlatformText(NULL, (unichar_t*)ep.getsvalue().getstring(), ep.getsvalue().getlength(), t_font);
}
Ejemplo n.º 5
0
static void MCFontMeasureTextCallback(MCFontRef p_font, const char *p_text, uint32_t p_length, bool p_is_unicode, font_measure_text_context *ctxt)
{
    if (p_length == 0 || p_text == NULL)
		return;
	
    MCGFont t_font;
	t_font = MCFontStructToMCGFont(p_font->fontstruct);
	
	// MW-2013-12-04: [[ Bug 11535 ]] Pass through the fixed advance.
	t_font . fixed_advance = p_font -> fixed_advance;
	
	// MW-2013-12-04: [[ Bug 11549 ]] Make sure unicode text is short-aligned.
	MCExecPoint ep;
	ep . setsvalue(MCString(p_text, p_length));
	if (!p_is_unicode)
		ep . nativetoutf16();
	else if ((((uintptr_t)ep . getsvalue() . getstring()) & 1) != 0)
		ep . grabsvalue();
	
    ctxt -> m_width += MCGContextMeasurePlatformText(NULL, (unichar_t *) ep . getsvalue() . getstring(), ep . getsvalue() . getlength(), t_font);
}
Ejemplo n.º 6
0
void MCS_putintourl(MCObject *p_target, const MCString& p_data, const char *p_url)
{
    bool t_success = true;

    char *t_processed = nil;
    MCObjectHandle *t_obj = nil;
    MCSPutUrlState t_state;

    t_success = MCSystemProcessUrl(p_url, kMCSystemUrlOperationStrip, t_processed);
    if (t_success)
        t_success = nil != (t_obj = p_target->gethandle());

    if (t_success)
    {
        t_state.url = t_processed;
        t_state.status = kMCSystemUrlStatusNone;
        t_state.object = t_obj;
        t_state.put_sent = 0;
        t_state.put_length = p_data.getlength();

        t_success = MCSystemPutUrl(t_processed, p_data . getstring(), p_data . getlength(), MCS_puturl_callback, &t_state);
    }

    if (t_success);
    {
        MCurlresult->clear();

        while (t_state.status != kMCSystemUrlStatusUploaded && t_state.status != kMCSystemUrlStatusError)
            MCscreen->wait(60.0, True, True);

        if (t_state.status == kMCSystemUrlStatusUploaded)
            MCresult->clear();
        else
            MCresult->sets(MCString(t_state.error));
    }

    MCCStringFree(t_processed);
    if (t_obj != nil)
        t_obj->Release();
}
Ejemplo n.º 7
0
bool MCVariableValue::get_as_real(MCExecPoint& ep, real64_t& r_value)
{
	if (is_number())
	{
		r_value = strnum . nvalue;
		return true;
	}

	if (is_empty())
	{
		r_value = 0.0;
		return true;
	}

	if (is_string())
		return MCU_stor8(MCString(strnum . svalue . string, strnum . svalue . length), r_value, ep . getconvertoctals()) == True;

	assert(is_array());

	r_value = 0.0;
	return true;
}
Ejemplo n.º 8
0
IO_stat IO_write_string(const char *string, uint4 outlen, IO_handle stream,
                        Boolean isunicode, uint1 size)
{
	IO_stat stat = IO_NORMAL;
	if (isunicode)
	{
		uint16_t *t_uniptr = (uint16_t*)string;
		uint32_t t_len = outlen / 2;
		while (t_len--)
			swap_uint2(t_uniptr++);
	}
	stat = IO_write_string(MCString(string, outlen), stream, size, true);
	if (isunicode)
	{
		uint16_t *t_uniptr = (uint16_t*)string;
		uint32_t t_len = outlen / 2;
		while (t_len--)
			swap_uint2(t_uniptr++);
	}
	
	return stat;
}
Ejemplo n.º 9
0
bool MCVariableValue::coerce_to_real(MCExecPoint& ep)
{
	assert(!is_real());

	if (is_empty())
	{
		assign_real(0.0);
		return true;
	}

	if (is_string())
	{
		if (MCU_stor8(MCString(strnum . svalue . string, strnum . svalue . length), strnum . nvalue, ep . getconvertoctals()) != True)
			return false;

		set_type(VF_BOTH);
		return true;
	}

	assert(is_array());

	assign_real(0.0);
	return true;
}
Ejemplo n.º 10
0
void MCExecPoint::setstaticbytes(const void *p_bytes, uindex_t p_length)
{
	setsvalue(MCString((const char *)p_bytes, p_length));
}
Ejemplo n.º 11
0
TEST(IRC32, GetMessageTags) {
    EXPECT_EQ(MCString(), CUtils::GetMessageTags(""));
    EXPECT_EQ(MCString(), CUtils::GetMessageTags(":nick!ident@host PRIVMSG #chan :hello world"));

    MCString exp;
    exp["a"] = "b";
    EXPECT_EQ(exp, CUtils::GetMessageTags("@a=b"));
    EXPECT_EQ(exp, CUtils::GetMessageTags("@a=b :nick!ident@host PRIVMSG #chan :hello world"));
    EXPECT_EQ(exp, CUtils::GetMessageTags("@a=b :rest"));
    exp.clear();

    exp["ab"] = "cdef";
    exp["znc.in/gh-ij"] = "klmn,op";
    EXPECT_EQ(exp, CUtils::GetMessageTags("@ab=cdef;znc.in/gh-ij=klmn,op :rest"));
    exp.clear();

    exp["a"] = "==b==";
    EXPECT_EQ(exp, CUtils::GetMessageTags("@a===b== :rest"));
    exp.clear();

    exp["a"] = "";
    exp["b"] = "c";
    exp["d"] = "";
    EXPECT_EQ(exp, CUtils::GetMessageTags("@a;b=c;d :rest"));
    exp.clear();

    exp["semi-colon"] += ';';
    exp["space"] += ' ';
    exp["NUL"] += '\0';
    exp["backslash"] += '\\';
    exp["CR"] += '\r';
    exp["LF"] += '\n';
    EXPECT_EQ(exp, CUtils::GetMessageTags(R"(@semi-colon=\:;space=\s;NUL=\0;backslash=\\;CR=\r;LF=\n :rest)"));
    exp.clear();

    exp["a"] = "; \\\r\n";
    EXPECT_EQ(exp, CUtils::GetMessageTags(R"(@a=\:\s\\\r\n :rest)"));
    exp.clear();
}

TEST(IRC32, SetMessageTags) {
    CString sLine;

    sLine = ":rest";
    CUtils::SetMessageTags(sLine, MCString());
    EXPECT_EQ(":rest", sLine);

    MCString tags;
    tags["a"] = "b";
    CUtils::SetMessageTags(sLine, tags);
    EXPECT_EQ("@a=b :rest", sLine);

    tags["c"] = "d";
    CUtils::SetMessageTags(sLine, tags);
    EXPECT_EQ("@a=b;c=d :rest", sLine);

    tags["e"] = "";
    CUtils::SetMessageTags(sLine, tags);
    EXPECT_EQ("@a=b;c=d;e :rest", sLine);
    tags.clear();

    tags["semi-colon"] += ';';
    tags["space"] += ' ';
    tags["NUL"] += '\0';
    tags["backslash"] += '\\';
    tags["CR"] += '\r';
    tags["LF"] += '\n';
    CUtils::SetMessageTags(sLine, tags);
    EXPECT_EQ(R"(@CR=\r;LF=\n;NUL=\0;backslash=\\;semi-colon=\:;space=\s :rest)", sLine);
    tags.clear();

    tags["a"] = "; \\\r\n";
    CUtils::SetMessageTags(sLine, tags);
    EXPECT_EQ(R"(@a=\:\s\\\r\n :rest)", sLine);
}
Ejemplo n.º 12
0
IO_stat IO_write_string(const char *string, IO_handle stream, uint1 size)
{
	return IO_write_string(MCString(string), stream, size);
}
Ejemplo n.º 13
0
MCString MCString::FromUTF8(const std::string& utf8) {
    std::wstring utf16;
    utf8::utf8to16(utf8.begin(), utf8.end(), std::back_inserter(utf16));
    return MCString(utf16);
}
Ejemplo n.º 14
0
Exec_stat MCPut::exec_cookie(MCExecPoint &ep)
{
	char *t_name = NULL;
	char *t_value = NULL;
	char *t_path = NULL;
	char *t_domain = NULL;
	
	uint32_t t_name_len = 0;
	uint32_t t_value_len = 0;
	uint32_t t_path_len = 0;
	uint32_t t_domain_len = 0;
	
	uint32_t t_expires = 0;
	
	bool t_success = true;
	
	
	t_value = ep.getsvalue().clone();
	t_value_len = ep.getsvalue().getlength();
	
	t_success = (ES_NORMAL == name->eval(ep));
	
	if (t_success)
	{
		t_name = ep.getsvalue().clone();
		t_name_len = ep.getsvalue().getlength();
		if (expires != NULL)
			t_success = expires->eval(ep);
	}
	if (t_success && expires)
		t_success = ep.isempty() || MCU_stoui4(ep.getsvalue(), t_expires);
	
	if (t_success && path)
	{
		t_success = path->eval(ep);
		if (t_success)
		{
			t_path = ep.getsvalue().clone();
			t_path_len = ep.getsvalue().getlength();
		}
	}
	
	if (t_success && domain)
	{
		t_success = domain->eval(ep);
		if (t_success)
		{
			t_domain = ep.getsvalue().clone();
			t_domain_len = ep.getsvalue().getlength();
		}
	}
		
	if(t_success)
		t_success = MCServerSetCookie(MCString(t_name, t_name_len), MCString(t_value, t_value_len), t_expires, MCString(t_path, t_path_len), MCString(t_domain, t_domain_len), is_secure, is_httponly);

	MCCStringFree(t_name);
	MCCStringFree(t_value);
	MCCStringFree(t_path);
	MCCStringFree(t_domain);

	if (!t_success)
	{
		MCeerror->add(EE_PUT_CANTSETINTO, line, pos);
		return ES_ERROR;
	}
	ep.clear();
	return ES_NORMAL;
}
Ejemplo n.º 15
0
bool cgi_initialize()
{
	// need to ensure PATH_TRANSLATED points to the script and PATH_INFO contains everything that follows
	cgi_fix_path_variables();

	// Resolve the main script that has been requested by the CGI interface.
	MCserverinitialscript = MCsystem -> ResolvePath(MCS_getenv("PATH_TRANSLATED"));
	
	// Set the current folder to be that containing the CGI file.
	char *t_server_script_folder;
	t_server_script_folder = strdup(MCserverinitialscript);
#ifdef _WINDOWS_SERVER
	strrchr(t_server_script_folder, '\\')[0] = '\0';
#else
	strrchr(t_server_script_folder, '/')[0] = '\0';
#endif
	MCsystem -> SetCurrentFolder(t_server_script_folder);
	delete t_server_script_folder;
	
	// Initialize the headers.
	MCservercgiheaders = NULL;
	MCservercgiheaders_sent = false;
	
	// Get the document root
	MCservercgidocumentroot = getenv("DOCUMENT_ROOT");
	
	// Initialize the input wrapper.  This creates a cache of the input stream
	// which is filled as the stream is read from.  this allows stdin to be used
	// to populate the post data arrays, and also to be read from by the script
	// without conflicting
	s_cgi_stdin_cache = new MCStreamCache(IO_stdin->handle);
	IO_stdin = new IO_header(new MCCacheHandle(s_cgi_stdin_cache), 0);
		
	// Initialize the output wrapper, this simply ensures we output headers
	// before any content.
	IO_stdout = new IO_header(new cgi_stdout, 0);
	
	// Need an exec-point for variable creation.
	MCExecPoint ep;
	
	// Construct the _SERVER variable
	/* UNCHECKED */ MCVariable::createwithname_cstring("$_SERVER", s_cgi_server);
	s_cgi_server -> setnext(MCglobals);
	MCglobals = s_cgi_server;
	for(uint32_t i = 0; environ[i] != NULL; i++)
	{
		
		static const char *s_cgi_vars[] =
		{
			"GATEWAY_INTERFACE=",
			"SERVER_ADDR=",
			"SERVER_NAME=",
			"SERVER_SOFTWARE=",
			"SERVER_PROTOCOL=",
			"REQUEST_METHOD=",
			"REQUEST_TIME=",
			"QUERY_STRING=",
			"DOCUMENT_ROOT=",
			"HTTPS=",
			
			// MW-2009-08-12: For some reason I missed this first time around :o)
			"REMOTE_USER="******"REMOTE_ADDR=",
			"REMOTE_HOST=",
			"REMOTE_PORT=",
			
			// MM-2011-09-08: Added as part of customer support request for REMOTE_USER.
			//   The standard Apache LiveCode server config redirects the script to the server engine.
			//   This appears to mean that REMOTE_USER is never set 
			//   (I guess it will only ever be set if the server engine itself is behind authentication)
			//   but REDIRECT_REMOTE_USER is.
			"REDIRECT_REMOTE_USER="******"SERVER_ADMIN=",
			"SERVER_PORT=",
			"SERVER_SIGNATURE=",
			
			"PATH_TRANSLATED=",
			
			"REQUEST_URI=",

			"PATH_INFO=",
			"SCRIPT_NAME=",
			"SCRIPT_FILENAME=",

			"CONTENT_TYPE=",
			"CONTENT_LENGTH=",

			NULL
		};
		
		bool t_found;
		t_found = false;
		
		if (strncasecmp(environ[i], "HTTP_", 5) == 0)
			t_found = true;
		else
			for(uint32_t j = 0; s_cgi_vars[j] != NULL && !t_found; j++)
				if (strncasecmp(environ[i], s_cgi_vars[j], strlen(s_cgi_vars[j])) == 0)
					t_found = true;

		if (t_found)
		{
			const char *t_value;
			t_value = strchr(environ[i], '=');
			if (t_value == NULL)
			{
				ep . clear();
				t_value = environ[i] + strlen(environ[i]);
			}
			else
				ep . setsvalue(t_value + 1);
			
			s_cgi_server -> getvalue() . store_element(ep, MCString(environ[i], t_value - environ[i]));
		}
	}
	
	// Construct the GET variables by parsing the QUERY_STRING
	
	/* UNCHECKED */ MCDeferredVariable::createwithname_cstring("$_GET_RAW", cgi_compute_get_raw_var, nil, s_cgi_get_raw);
	s_cgi_get_raw -> setnext(MCglobals);
	MCglobals = s_cgi_get_raw;	
	/* UNCHECKED */ MCDeferredVariable::createwithname_cstring("$_GET", cgi_compute_get_var, nil, s_cgi_get);
	s_cgi_get -> setnext(MCglobals);
	MCglobals = s_cgi_get;
	/* UNCHECKED */ MCDeferredVariable::createwithname_cstring("$_GET_BINARY", cgi_compute_get_binary_var, nil, s_cgi_get_binary);
	s_cgi_get_binary -> setnext(MCglobals);
	MCglobals = s_cgi_get_binary;	
	
	// Construct the _POST variables by reading stdin.
	
	/* UNCHECKED */ MCDeferredVariable::createwithname_cstring("$_POST_RAW", cgi_compute_post_raw_var, nil, s_cgi_post_raw);
	s_cgi_post_raw -> setnext(MCglobals);
	MCglobals = s_cgi_post_raw;
	/* UNCHECKED */ MCDeferredVariable::createwithname_cstring("$_POST", cgi_compute_post_var, nil, s_cgi_post);
	s_cgi_post -> setnext(MCglobals);
	MCglobals = s_cgi_post;
	/* UNCHECKED */ MCDeferredVariable::createwithname_cstring("$_POST_BINARY", cgi_compute_post_binary_var, nil, s_cgi_post_binary);
	s_cgi_post_binary -> setnext(MCglobals);
	MCglobals = s_cgi_post_binary;	
	
	// Construct the FILES variable by reading stdin

	/* UNCHECKED */ MCDeferredVariable::createwithname_cstring("$_FILES", cgi_compute_files_var, nil, s_cgi_files);
	s_cgi_files -> setnext(MCglobals);
	MCglobals = s_cgi_files;
	
	// Construct the COOKIES variable by parsing HTTP_COOKIE
	/* UNCHECKED */ MCDeferredVariable::createwithname_cstring("$_COOKIE", cgi_compute_cookie_var, nil, s_cgi_cookie);
	s_cgi_cookie -> setnext(MCglobals);
	MCglobals = s_cgi_cookie;
	
	// Create the $_SESSION variable explicitly, to be populated upon calls to "start session"
	// required as implicit references to "$_SESSION" will result in its creation as an env var
	MCVariable *t_session_var = NULL;
	/* UNCHECKED */ MCVariable::createwithname_cstring("$_SESSION", t_session_var);
	t_session_var->setnext(MCglobals);
	MCglobals = t_session_var;

	return true;
}
Ejemplo n.º 16
0
bool MCServerStartSession()
{
	// start session:
	// if MCsessionid is empty - get id from cookie
	// if MCsessionid not empty - use MCsessionid - clear MCsessionid once opened
	bool t_success = true;
	
	if (s_current_session != NULL)
		return true;

	const char *t_session_id = NULL;
	char *t_cookie_id = NULL;
	
	t_session_id = MCsessionid;
	
	if (t_session_id == NULL)
	{
		t_success = MCServerGetSessionIdFromCookie(t_cookie_id);
		t_session_id = t_cookie_id;
	}
	
	if (t_success)
		t_success = MCSessionStart(t_session_id, s_current_session);
	
	MCVariable *t_session_var = NULL;
	
	if (t_success)
	{
		t_session_var = MCVariable::lookupglobal_cstring("$_SESSION");
		if (t_session_var == NULL)
		{
			t_success = MCVariable::createwithname_cstring("$_SESSION", t_session_var);
			if (t_success)
			{
				t_session_var->setnext(MCglobals);
				MCglobals = t_session_var;
			}
		}
	}
	if (t_success)
		t_session_var->getvalue().assign_empty();
	
	if (t_success)
	{
		if (s_current_session->data_length > 0)
			t_success = t_session_var->getvalue().decode(MCString(s_current_session->data, s_current_session->data_length));
	}
	
	if (t_success)
	{
		// clear MCsessionid - now associated with open session
		MCCStringFree(MCsessionid);
		MCsessionid = NULL;
	}
	else
	{
		MCSessionDiscard(s_current_session);
		s_current_session = NULL;
	}
	
	MCCStringFree(t_cookie_id);
	
	return t_success;
}
Ejemplo n.º 17
0
IO_stat MCLogicalFontTableLoad(IO_handle p_stream)
{
	// Delete any existing font table.
	MCLogicalFontTableFinish();

	// Keep track of any IO errors.
	IO_stat t_stat;
	t_stat = IO_NORMAL;

	// Read the number of entries.
	uint2 t_count;
	if (t_stat == IO_NORMAL)
		t_stat = IO_read_uint2(&t_count, p_stream);

	// Allocate an array big enough to hold all of them.
	if (t_stat == IO_NORMAL)
		if (!MCMemoryNewArray(t_count, s_logical_font_table))
			t_stat = IO_ERROR;

	if (t_stat == IO_NORMAL)
	{
		// The size and capacity of the table are equal to the count.
		s_logical_font_table_size = s_logical_font_table_capacity = t_count;

		// Iterate t_count times to load each entry in.
		for(uint32_t i = 0; i < t_count && t_stat == IO_NORMAL; i++)
		{
			char *t_textfont;
			uint2 t_textsize, t_textstyle;
			t_textfont = nil;

			// Read in the textSize, textStyle and (original) textFont props.
			t_stat = IO_read_uint2(&t_textsize, p_stream);
			if (t_stat == IO_NORMAL)
				t_stat = IO_read_uint2(&t_textstyle, p_stream);
			if (t_stat == IO_NORMAL)
				t_stat = IO_read_string(t_textfont, p_stream);

			// Now convert the textFont string into a name, splitting off the
			// lang tag (if any).
			MCNameRef t_textfont_name;
			bool t_is_unicode;
			if (t_stat == IO_NORMAL)
			{
				// MW-2012-02-17: [[ Bug ]] It seems possible for the textFont string
				//   to be empty in some cases - so handle this case carefully.
				const char *t_textfont_tag;
				if (t_textfont != nil)
				{
					t_textfont_tag = strchr(t_textfont, ',');
					if (t_textfont_tag == nil)
					{
						t_textfont_tag = t_textfont + strlen(t_textfont);
						t_is_unicode = false;
					}
					else
						t_is_unicode = true;
				}
				else
				{
					t_textfont_tag = nil;
					t_is_unicode = false;
				}

				if (!MCNameCreateWithOldString(MCString(t_textfont, t_textfont_tag - t_textfont), t_textfont_name))
					t_stat = IO_ERROR;
			}

			// Set the appropriate table entry.
			if (t_stat == IO_NORMAL)
				MCLogicalFontTableSetEntry(i, t_textfont_name, t_textstyle, t_textsize, t_is_unicode);

			// Cleanup the (temporary) original textFont string.
			delete t_textfont;
		}
	}

	return t_stat;
}
Ejemplo n.º 18
0
bool MCResidentImageRep::GetDataStream(IO_handle &r_stream)
{
	r_stream = MCS_fakeopen(MCString((char*)m_data, m_size));
	return r_stream != nil;
}
Ejemplo n.º 19
0
static bool cgi_multipart_body_callback(void *p_context, const char *p_data, uint32_t p_data_length, bool p_finished, bool p_truncated)
{
	cgi_multipart_context_t *t_context = (cgi_multipart_context_t*)p_context;
	bool t_success = true;

	if (cgi_context_is_form_data(t_context))
	{
		if (t_context->post_binary_variable != NULL)
		{
			t_success = t_context->post_binary_variable->append_string(MCString(p_data, p_data_length));

			if (t_success && p_finished)
			{
				uint32_t t_native_length;
				char *t_native = NULL;
				MCString t_value;
				t_value = t_context->post_binary_variable->get_string();
				if (cgi_native_from_encoding(MCserveroutputtextencoding, t_value.getstring(), t_value.getlength(), t_native, t_native_length))
					t_context->post_variable -> assign_buffer(t_native, t_native_length);
			}
		}
	}
	else if (cgi_context_is_file(t_context))
	{
		if (t_context->file_status == kMCFileStatusOK)
		{
			if (IO_NORMAL == MCS_write(p_data, 1, p_data_length, t_context->file_handle))
				t_context->file_size += p_data_length;
			else
				t_context->file_status = kMCFileStatusIOError;
		}
		
		if (t_success && (p_finished || p_truncated))
		{
			MCExecPoint ep;
			MCVariableValue *t_file_varvalue = NULL;
			cgi_fetch_variable_value_for_key(s_cgi_files, t_context->name, MCCStringLength(t_context->name), ep, t_context->file_variable);
			
			if (t_context->file_status == kMCFileStatusOK && t_context->file_size == 0)
				t_context->file_status = kMCFileStatusFailed;
			
			if (p_truncated)
				t_context->file_status = kMCFileStatusStopped;
			
			ep.setsvalue(MCString(t_context->file_name));
			t_context->file_variable->store_element(ep, MCString("name"));
			ep.setsvalue(MCString(t_context->type));
			t_context->file_variable->store_element(ep, MCString("type"));
			ep.setsvalue(MCString(t_context->temp_name));
			t_context->file_variable->store_element(ep, MCString("filename"));
			ep.setuint(t_context->file_size);
			t_context->file_variable->store_element(ep, MCString("size"));

			if (t_context->file_status != kMCFileStatusOK)
			{
				ep.setsvalue(MCMultiPartGetErrorMessage(t_context->file_status));
				t_context->file_variable->store_element(ep, MCString("error"));
			}
		}
	}
	
	if (t_success && p_finished)
	{
		// clear context for next part
		cgi_dispose_multipart_context(t_context);
	}
	
	return t_success;
}