static mp3_lrc_filter_t *mp3_lrc_parse_unicode(unsigned short *str, u32 buf_size)
{
  u32 x = 0;
  unsigned long i = 0 , j = 0;
  unsigned long count = 0;
  unsigned short *p_char = 0;
  unsigned short *p_temp = 0;
  unsigned short lrc[1024];
  unsigned short *p_lrc = 0;
  mp3_lrc_filter_t *p_f = NULL;
  mp3_lrc_filter_t *p_b = NULL;
  mp3_lrc_filter_t *p_head = NULL;

  if(str == NULL)
  {
     return NULL;
  }
  
  p_char = uni_strstr(str,(u16 *)"[");
  if(p_char == NULL)
  {
    return NULL;
  }
  
  buf_size = buf_size - (str - p_char);
  while((p_char != NULL) && ((p_char + 1) != NULL) && (*p_char != '\0') && (buf_size > 0))
  {
    //character between 0 and 9
    if((*p_char == '[') && (*(p_char + 1) >= 48) && (*(p_char + 1) <= 57))
    {
      if(((p_char + 2) == NULL) || ((p_char + 4) == NULL) || ((p_char + 5) == NULL))
      {
         return NULL;
      }
      
      count = (*(p_char + 2) - '0') * 60 + (*(p_char + 4) - '0') * 10 + *(p_char + 5) - '0';
      p_temp = p_char;

      while((p_temp ++) != NULL)
      {
        if((p_temp == NULL) || ((p_temp + 1) == NULL))
        {
          return NULL;
        }      
        
        if((*p_temp == ']') && (*(p_temp + 1) != '['))
        {
          p_temp ++;
          break;
        }

        j++;
        if(j > 1000)
          break;
      }

      p_lrc = lrc;
      while((p_lrc != NULL) && (p_temp != NULL) && (*p_temp != '\n') && (*p_temp != '\r'))
      {
        *p_lrc++ = *p_temp++;
      }
      //*p_lrc ++ = '\r';
      *p_lrc = '\0';

      p_b = (mp3_lrc_filter_t *)mtos_malloc(LRCLEN);
      CHECK_FAIL_RET_NULL(p_b != NULL);
      memset(p_b,0,sizeof(mp3_lrc_filter_t));
      
      p_b->start_time = count;
      //strcpy((char *)p_b->lyric,(char *)lrc);
      x = uni_strlen(lrc);
      memcpy((void *)p_b->lyric, (void *)lrc, 2 * x);

      if(p_b->lyric[0] == 0x0D)
      {
            p_b->lyric[0] = ' ';
            p_b->lyric[1] = '\0';
      }
      else if(p_b->lyric[0] == '\0')
      {
           p_b->lyric[0] = ' ';
           p_b->lyric[1] = '\0';
      }

      if(i == 0)
      {
        p_head = p_f = p_b;
        i++;
      }
      else
      {
        p_f->p_next = p_b;
        p_f = p_b;
        p_b->p_next = NULL;
      }
    }

    p_char ++;
    buf_size --;
  }

  if(p_f != NULL)
  {
     p_f->p_next = NULL;
  }
  
  return p_head;
  
}
예제 #2
0
/***********************************************************************************
 ** MakeSearchURL
 **
 **
 ***********************************************************************************/
BOOL SearchTemplate::MakeSearchURL(URL& url_object, 
								   const uni_char* keyword, 
								   BOOL resolve_keyword, 
								   SearchEngineManager::SearchReqIssuer search_req_issuer,
								   const OpStringC& key, 
								   URL_CONTEXT_ID context_id)
{
	uni_char keyword2[MAX_URL_LEN+1]; // searchword-part
	uni_char url[MAX_URL_LEN+200+1]; // final url (+200 for the string in search_engines)

	if (resolve_keyword)
	{
		// Change a "www.opera.com" to "http://www.opera.com"
		OpString keyword_before;
		OpString keyword_after;
		keyword_before.Set(keyword);
		ResolveUrlNameL(keyword_before, keyword_after);

		UrlifySearchString(keyword2, keyword_after.CStr()); // basic urlifying
	}
	else
	{
		UrlifySearchString(keyword2, keyword); // basic urlifying
	}

	unsigned int current_length = uni_strlen(keyword2);
	uni_char* searchencoding = m_encoding.CStr();

	EncodeFormsData(searchencoding ? make_singlebyte_in_tempbuffer(searchencoding, uni_strlen(searchencoding)) : "iso-8859-1",
									keyword2 /*uni_char variable*/, 0, current_length /*length now and later*/, MAX_URL_LEN /*max I can take*/);

	keyword2[current_length] = 0; // null-terminate yourself

	// MAX_URL_LEN = maximum number of characters to store

	if (!m_is_post && m_url.Find(UNI_L("%s")) == KNotFound) //if the string doesn't contain a %s we don't have anything to format the string with, prevents crashing
		return FALSE;

	uni_char* urlstring = m_url.CStr();
	uni_char* poststring = m_query.CStr();
	uni_char* teststring = urlstring;

	if(m_is_post)		// if the search uses post, check the query
	{
		teststring = poststring;
	}

	if(!teststring || !*teststring)
	{
		return FALSE;
	}

	int stringholders = 0;
	int intholders = 0;
	uni_char* tmp = teststring;
	uni_char* last_stringholder = NULL;

	while(tmp && *tmp)
	{
		tmp = uni_strstr(tmp, UNI_L("%s"));
		if (tmp)
		{
			last_stringholder = tmp;
			stringholders++;
			tmp++;
		}
	}

	tmp = urlstring;
	while(tmp && *tmp)
	{
		tmp = uni_strstr(tmp, UNI_L("%i"));
		if(tmp)
		{
			// Bug#96348: Make sure the intholder is always last
			if (tmp < last_stringholder)
				return FALSE;

			intholders++;
			tmp++;
		}
	}

	// escape away % followed by number before calling uni_snprintf

	SprintEscape(urlstring);

	if(stringholders!=1)
	{
		return FALSE;
	}

	// We need a new url so we don't screw the original which "urlstring" is pointing at
	OpString urlstring_copy;
	urlstring_copy.Set(urlstring);

	if (!urlstring_copy.HasContent())
		return FALSE;

	//Substitue the string '{TrackingCode}' in the URL with the string from the key 'SpeedDial Tracking Code' 
	// or 'Default Tracking Code' depending on the search request issuer types.
	if (KNotFound != urlstring_copy.FindI(OpStringC16(UNI_L("{TrackingCode}"))))
	{
		if (search_req_issuer == SearchEngineManager::SEARCH_REQ_ISSUER_SPEEDDIAL)
		{
			urlstring_copy.ReplaceAll(UNI_L("{TrackingCode}"), m_speeddial_tracking_code.CStr());
		}
		else
		{
			urlstring_copy.ReplaceAll(UNI_L("{TrackingCode}"), m_default_tracking_code.CStr());
		}
	}

	// Check if there was a google TLD
	if (m_use_tld)
	{
		OpStringC google_tld = g_pcui->GetStringPref(PrefsCollectionUI::GoogleTLDDefault);

		// Do a check to make sure the string looks ok has a .google. and isn't too long
		if (google_tld.Find(".google.") == KNotFound || google_tld.Length() > 30)
			return FALSE;

		// Change the www.google.com bit to the TLD version in the preference
		uni_char *second_slash = uni_strchr(urlstring_copy.CStr(), '/');
		if (!second_slash)
			return FALSE;

		second_slash = uni_strchr(second_slash + 1, '/');
		if (!second_slash)
			return FALSE;

		uni_char *third_slash = uni_strchr(second_slash + 1, '/');
		if (!third_slash)
			return FALSE;

		// Build the new string
		OpString new_url;

		*second_slash = '\0';
		new_url.Set(urlstring_copy.CStr());
		new_url.AppendFormat(UNI_L("/www%s%s"), google_tld.CStr(), third_slash);

		urlstring_copy.Set(new_url.CStr());
	}

#ifdef GOOGLE_G_SEARCH_NOT_PAID
	// Special google hack so that if the search is started with "g search" from the address bar we change the
	// sourceid so that we don't get paid. Currently not active
	if (!GetUniqueGUID().Compare(GOGGLE_SEARCH_GUID) && key.HasContent() && !key.Compare(GetKey().CStr()))
	{
		// Change the "sourceid=opera" to "source=opera_g"
		uni_char *p = uni_strstr(urlstring_copy.CStr(), GOOGLE_SEARCH_PAY_SOURCEID);
		if (p)
		{
			// Terminate the string at the point "sourceid=opera" starts
			*p = '\0';

			OpString new_url;

			new_url.AppendFormat(UNI_L("%s%s%s"), urlstring_copy.CStr(), GOOGLE_SEARCH_NO_PAY_SOURCEID, (p + uni_strlen(GOOGLE_SEARCH_PAY_SOURCEID)));

			urlstring_copy.Set(new_url.CStr());
		}
	}
#endif // GOOGLE_G_SEARCH_NOT_PAID

	uni_snprintf(url, MAX_URL_LEN+200, urlstring_copy.CStr() , keyword2, 0);

	url[MAX_URL_LEN + 200] = '\0';

	// replace $ with % again
	SprintUnEscape(url);

	URL dummy;
	OpString8 real_url;

	OpStatus::Ignore(real_url.SetUTF8FromUTF16(url));

	url_object = g_url_api->GetURL(dummy, real_url, m_is_post, context_id);

	if(m_is_post)
	{
		// escape away % followed by number before calling uni_snprintf
		SprintEscape(m_query.CStr());

		uni_snprintf(url, MAX_URL_LEN+200, m_query.CStr() , keyword2, 0);

		// replace $ with % again
		SprintUnEscape(url);

		url_object.SetHTTP_Method(HTTP_METHOD_POST);

		char* char_url = make_singlebyte_in_tempbuffer(url, uni_strlen(url));

		url_object.SetHTTP_Data(char_url, TRUE);
		url_object.SetHTTP_ContentType(FormUrlEncodedString);

	}
	url[MAX_URL_LEN + 200] = '\0';

	return TRUE;
}
예제 #3
0
uni_char*
Debug::InitSettings(const char* filename)
{
	// Load settings from file

	OpFile f;
	OpFile* in = &f;
	uni_char* uf = uni_up_strdup(filename);
	BOOL ok = uf && OpStatus::IsSuccess(in->Construct(uf));
	ok = ok && OpStatus::IsSuccess(in->Open(OPFILE_READ));
	op_free(uf);
	if (!ok)
	{
		uni_char* ufilename = uni_up_strdup(filename);
		if ( ufilename == 0 )
			return 0;

		const uni_char* full_path_and_name = f.GetFullPath();
		if (!full_path_and_name || !*full_path_and_name)
			full_path_and_name = ufilename;
		uni_char* buf = OP_NEWA(uni_char, 100 + uni_strlen(full_path_and_name));
		if ( buf != 0 )
			uni_sprintf(buf, UNI_L("Could not open debug settings file: %s"),
			full_path_and_name);
		op_free(ufilename);
		return buf;
	}

#define READLINE_BUFFER_SIZE 300

	uni_char str[READLINE_BUFFER_SIZE]; // ARRAY OK 2007-03-09 mortenro
	uni_char* tmp;
	int sLen;

	BOOL clearfile = FALSE;

	// Read all lines in file
	while (ReadLine(in, str, READLINE_BUFFER_SIZE))
	{
		if (*str == 0)
			continue;

		// Skip whitespace in the beginning of the line
		while (str[0] == ' ' || str[0] == '\t')
			uni_strcpy(str, str+1);

		if (*str == 0)
			continue;

		// Skip \r character at end of line
		if (str[uni_strlen(str) - 1] == '\r')
			str[uni_strlen(str) - 1] = '\0';

		if (*str == 0)
			continue;

		// Skip whitespace in the end of the line
		while (*str && (str[uni_strlen(str) - 1] == ' ' || str[uni_strlen(str) - 1] == '\t'))
			str[uni_strlen(str) - 1] = '\0';

		sLen = uni_strlen(str);

		if (sLen == 0)
			continue;

		// Skip lines starting with #
		if (*str == '#')
			continue;

		// Make all chars before equal sign lower case so we don't need to use FindI
		// which uses a table manager.
		uni_char* eq = uni_strstr(str, UNI_L("="));
		int eq_pos = -1;
		if (eq)
		{
			eq_pos = eq - str;

			for (int i=0; i < eq_pos && i < sLen; ++i)
			{
				str[i] = uni_tolower(str[i]);
			}
		}

		// Check for output=filename
		tmp = uni_strstr(str, UNI_L("output="));
		if (tmp)
		{
			tmp += 7;
			if (*tmp)
			{
				Debug::SetOutputFile(tmp);
			}
			continue;
		}

		// Check for clearfile=[on/off]
		tmp = uni_strstr(str, UNI_L("clearfile=on"));
		if (tmp == str)
		{
			clearfile = TRUE;
			continue;
		}

		// Check for debugging=[on/off]
		tmp = uni_strstr(str, UNI_L("debugging=on"));
		if (tmp == str)
		{
			g_dbg_debugging = TRUE;
			continue;
		}

		// Check for tracing=[on/off]
		tmp = uni_strstr(str, UNI_L("tracing=on"));
		if (tmp == str)
		{
			g_dbg_tracing = TRUE;
			continue;
		}

		// Check for prefix=off
		tmp = uni_strstr(str, UNI_L("prefix=off"));
		if (tmp == str)
		{
			g_dbg_prefix = FALSE;
			continue;
		}

		// Check for timing=[on/off]
		tmp = uni_strstr(str, UNI_L("timing=on"));
		if (tmp == str)
		{
			g_dbg_timing = TRUE;
			continue;
		}

		// Check for timestamp=[on/off]
		tmp = uni_strstr(str, UNI_L("timestamp=on"));
		if (tmp == str)
		{
			g_dbg_timestamp = TRUE;
			continue;
		}

		// Check for systemdebug=[on/off]
		tmp = uni_strstr(str, UNI_L("systemdebug=on"));
		if (tmp == str)
		{
			g_dbg_system_debug = TRUE;
			continue;
		}

		// Check for console=[on/off]
		tmp = uni_strstr(str, UNI_L("console=on"));
		if (tmp == str)
		{
			g_dbg_console = TRUE;
			continue;
		}

		// Add keyword
		if (uni_str_eq(str, "*")) 
			g_dbg_all_keywords = TRUE;
		else
			Debug::AddKeyword(str);
	}
	in->Close();

	// Clear output file if specified
	if (clearfile && g_dbg_filename && *g_dbg_filename)
	{
		uni_char* uf = uni_up_strdup(g_dbg_filename);
		if (uf)
		{
			OpFile f;
			f.Construct(uf);
			f.Open(OPFILE_WRITE);
			f.Close();
			op_free(uf);
		}
	}

	return NULL;
}
예제 #4
0
OP_STATUS
OpSecurityManager_DOM::CheckWorkerScriptImport(const OpSecurityContext& source, const OpSecurityContext& target, BOOL& allowed)
{
	allowed = FALSE;

	URLType target_type = target.GetURL().Type();
	switch (source.GetURL().Type())
	{
	case URL_HTTP:
	case URL_HTTPS:
	case URL_DATA:
		allowed = target_type == URL_HTTP || target_type == URL_HTTPS || target_type == URL_DATA;
		break;

	case URL_FILE:
		if (target_type == URL_FILE)
		{
			/* The target must be at or below the source/worker's directory. */

			OpString worker_file, target_file;

			{
				OpString worker_string, target_string;

				RETURN_IF_ERROR(source.GetURL().GetAttribute(URL::KUniName_Username_Password_Escaped_NOT_FOR_UI, worker_string));
				RETURN_IF_ERROR(target.GetURL().GetAttribute(URL::KUniName_Username_Password_Escaped_NOT_FOR_UI, target_string));

				RETURN_OOM_IF_NULL(worker_file.Reserve(worker_string.Length() + 1));
				UriUnescape::Unescape(worker_file.CStr(), worker_string.CStr(), UriUnescape::ExceptUnsafeCtrl);

				RETURN_OOM_IF_NULL(target_file.Reserve(target_string.Length() + 1));
				UriUnescape::Unescape(target_file.CStr(), target_string.CStr(), UriUnescape::ExceptUnsafeCtrl);
			}

			unsigned length = worker_file.Length();
			const uni_char *str = worker_file.CStr();
			while (length != 0)
				if (str[length - 1] == '/')
					break;
				else
					--length;

			allowed = length > 0 && length < static_cast<unsigned>(target_file.Length()) &&
			          uni_strncmp(worker_file.CStr(), target_file.CStr(), length) == 0;

			if (allowed)
			{
				const uni_char *dotdot = target_file.CStr() + length;
				while (dotdot && allowed)
				{
					dotdot = uni_strstr(dotdot, UNI_L(".."));
					if (dotdot && (IS_LIKELY_PATH_SEP_CHARACTER(dotdot[-1]) && IS_LIKELY_PATH_SEP_CHARACTER(dotdot[2])))
						allowed = FALSE;
					else
						dotdot = dotdot ? dotdot + 1 : NULL;
				}
			}
		}
		else
			allowed = target_type == URL_HTTP || target_type == URL_HTTPS || target_type == URL_DATA;
		break;
	default:
		break;
	}

	return OpStatus::OK;
}
예제 #5
0
/* virtual */ ES_PutState
JS_Location::PutName(OpAtom property_name, ES_Value* value, ES_Runtime* origining_runtime)
{
	if (GetName(property_name, NULL, origining_runtime) != GET_SUCCESS)
		return PUT_FAILED;

	FramesDocument *frames_doc = GetFramesDocument();
	if (!frames_doc)
		return PUT_SUCCESS;

	if (value->type != VALUE_STRING)
		return PUT_NEEDS_STRING;

	const uni_char *value_string = value->value.string;

	while (value_string[0] == ' ')
		++value_string;

	if (property_name == OP_ATOM_href)
		if (value_string[0] == '#')
			property_name = OP_ATOM_hash;
		else if (value_string[0] == '?')
			property_name = OP_ATOM_search;

	URL url;
	DocumentReferrer ref_url(GetStandardRefURL(frames_doc, origining_runtime));
	TempBuffer buffer;

	URL current_url = ref_url.url;
#ifdef SELFTEST
	if (!do_navigation)
		current_url = this->current_url;
#endif // SELFTEST

	switch (property_name)
	{
	case OP_ATOM_href:
	case OP_ATOM_protocol:
	case OP_ATOM_host:
	case OP_ATOM_hostname:
	case OP_ATOM_port:
	case OP_ATOM_pathname:
		BOOL allowed;
		if (OpStatus::IsError(OpSecurityManager::CheckSecurity(OpSecurityManager::DOM_ALLOWED_TO_NAVIGATE, static_cast<DOM_Runtime *>(origining_runtime), GetRuntime(), allowed)) ||
			!allowed)
			return PUT_SECURITY_VIOLATION;
	}

	switch (property_name)
	{
	case OP_ATOM_protocol:
	{
		unsigned length = uni_strlen(value_string);
		while (length > 0 && value_string[length - 1] == ':')
			length--;
		if (length > 0)
		{
			const uni_char *current_url_string = current_url.GetAttribute(URL::KUniName_Username_Password_NOT_FOR_UI).CStr();
			const uni_char *current_scheme_end = uni_strchr(current_url_string, ':');
			if (!current_scheme_end)
				return PUT_SUCCESS;

			PUT_FAILED_IF_ERROR(buffer.Append(value_string, length));
			PUT_FAILED_IF_ERROR(buffer.Append(current_scheme_end));

			url = GetEncodedURL(origining_runtime->GetFramesDocument(), buffer.GetStorage());

			BOOL allowed;
			if (url.Type() == URL_JAVASCRIPT)
				if (OpStatus::IsError(OpSecurityManager::CheckSecurity(OpSecurityManager::DOM_STANDARD, static_cast<DOM_Runtime *>(origining_runtime), GetRuntime(), allowed)) ||
				    !allowed)
					return PUT_SUCCESS;
		}
		break;
	}
	case OP_ATOM_host:
	{
		const uni_char *current_url_string = current_url.GetAttribute(URL::KUniName_Username_Password_NOT_FOR_UI).CStr();
		const uni_char *current_scheme_end = uni_strchr(current_url_string, ':');

		// URL must be an "authority-based URL"
		if (current_scheme_end && current_scheme_end[1] == '/' && current_scheme_end[2] == '/')
		{
			OpString hostname;
			PUT_FAILED_IF_ERROR(current_url.GetAttribute(URL::KUniHostName, hostname));
			/* Just bail if the URL doesn't have a hostname after all. */
			if (!hostname.CStr())
				return PUT_SUCCESS;

			uni_char *hostname_start = uni_strstr(current_url_string, hostname.CStr());
			OP_ASSERT(hostname_start);
			uni_char *hostname_end = hostname_start + hostname.Length();

			unsigned short port = current_url.GetAttribute(URL::KServerPort);
			if (port > 0 && *hostname_end == ':')
			{
				hostname_end++;
				while (uni_isdigit(*hostname_end))
					hostname_end++;
			}

			PUT_FAILED_IF_ERROR(buffer.Append(current_url_string, hostname_start - current_url_string));
			PUT_FAILED_IF_ERROR(buffer.Append(value_string));
			PUT_FAILED_IF_ERROR(buffer.Append(hostname_end));

			url = GetEncodedURL(origining_runtime->GetFramesDocument(), buffer.GetStorage());
		}
		break;
	}
	case OP_ATOM_hostname:
	{
		while (*value_string == '/')
			value_string++;

		const uni_char *current_url_string = current_url.GetAttribute(URL::KUniName_Username_Password_NOT_FOR_UI).CStr();
		const uni_char *current_scheme_end = uni_strchr(current_url_string, ':');

		// URL must be an "authority-based URL"
		if (*value_string && current_scheme_end && current_scheme_end[1] == '/' && current_scheme_end[2] == '/')
		{
			OpString hostname;
			PUT_FAILED_IF_ERROR(current_url.GetAttribute(URL::KUniHostName, hostname));
			/* Just bail if the URL doesn't have a hostname after all. */
			if (!hostname.CStr())
				return PUT_SUCCESS;

			uni_char *hostname_start = uni_strstr(current_url_string, hostname.CStr());
			OP_ASSERT(hostname_start);
			uni_char *hostname_end = hostname_start + hostname.Length();

			PUT_FAILED_IF_ERROR(buffer.Append(current_url_string, hostname_start - current_url_string));
			PUT_FAILED_IF_ERROR(buffer.Append(value_string));
			PUT_FAILED_IF_ERROR(buffer.Append(hostname_end));

			url = GetEncodedURL(origining_runtime->GetFramesDocument(), buffer.GetStorage());
		}
		break;
	}
	case OP_ATOM_port:
	{
		const uni_char *current_url_string = current_url.GetAttribute(URL::KUniName_Username_Password_NOT_FOR_UI).CStr();
		const uni_char *current_scheme_end = uni_strchr(current_url_string, ':');
		// URL must be an "authority-based URL"
		if (current_scheme_end && current_scheme_end[1] == '/' && current_scheme_end[2] == '/')
		{
			while (*value_string == '0')
				value_string++;

			int port = 0;
			if (uni_isdigit(*value_string))
				port = uni_atoi(value_string);

			if (port <= 0 || port > 65535)
				break;

			OpString hostname;
			PUT_FAILED_IF_ERROR(current_url.GetAttribute(URL::KUniHostName, hostname));
			/* Just bail if the URL doesn't have a hostname after all. */
			if (!hostname.CStr())
				return PUT_SUCCESS;

			uni_char *hostname_start = uni_strstr(current_scheme_end, hostname.CStr());
			OP_ASSERT(hostname_start);
			uni_char *hostname_end = hostname_start + hostname.Length();

			PUT_FAILED_IF_ERROR(buffer.Append(current_url_string, hostname_end - current_url_string));
			PUT_FAILED_IF_ERROR(buffer.Append(":"));
			if (*hostname_end == ':')
			{
				hostname_end++;
				while (uni_isdigit(*hostname_end))
					hostname_end++;
			}
			PUT_FAILED_IF_ERROR(buffer.AppendLong(port));
			PUT_FAILED_IF_ERROR(buffer.Append(hostname_end));

			url = GetEncodedURL(origining_runtime->GetFramesDocument(), buffer.GetStorage());
		}
		break;
	}
	case OP_ATOM_href:
	case OP_ATOM_pathname:
	{
		url = GetEncodedURL(origining_runtime->GetFramesDocument(), value_string);

		BOOL allowed;
		// Stricter security for javascript urls. It's possible this check should move into DocumentManager in the future.
		if (url.Type() == URL_JAVASCRIPT)
			if (OpStatus::IsError(OpSecurityManager::CheckSecurity(OpSecurityManager::DOM_STANDARD, static_cast<DOM_Runtime *>(origining_runtime), GetRuntime(), allowed)) ||
			    !allowed)
				return PUT_SUCCESS;

		break;
	}
	case OP_ATOM_search:
	{
		const uni_char *current_url_string = current_url.GetAttribute(URL::KUniName_Username_Password_NOT_FOR_UI).CStr();
		int current_len;

		const uni_char *current_search_start = uni_strchr(current_url_string, '?');
		if (current_search_start)
			current_len = current_search_start - current_url_string;
		else
			current_len = uni_strlen(current_url_string);

		if (value_string[0] == '?')
			++value_string;

		PUT_FAILED_IF_ERROR(buffer.Expand(current_len + uni_strlen(value_string) + 2));

		OpStatus::Ignore(buffer.Append(current_url_string, current_len)); // buffer is successfully expanded above
		OpStatus::Ignore(buffer.Append("?"));
		OpStatus::Ignore(buffer.Append(value_string));

		url = GetEncodedURL(origining_runtime->GetFramesDocument(), buffer.GetStorage());
		break;
	}
	case OP_ATOM_hash:
		if (value_string[0] == '#')
			++value_string;

		// Strip trailing whitespace
		if (unsigned length = uni_strlen(value_string))
		{
			if (value_string[length - 1] == ' ')
			{
				PUT_FAILED_IF_ERROR(buffer.Append(value_string));

				uni_char *string = buffer.GetStorage();

				while (length > 0 && string[length - 1] == ' ')
					--length;

				string[length] = 0;
				value_string = string;
			}
		}

#ifdef SELFTEST
		url = URL(!do_navigation ? current_url : frames_doc->GetURL(), value_string);
#else
		url = URL(frames_doc->GetURL(), value_string);
#endif // SELFTEST
		break;
	}

	if (url.Type() != URL_NULL_TYPE)
	{
#ifdef GADGET_SUPPORT
		switch (property_name)
		{
		case OP_ATOM_href:
		case OP_ATOM_protocol:
		case OP_ATOM_host:
		case OP_ATOM_hostname:
		case OP_ATOM_port:
		case OP_ATOM_pathname:
		{
			BOOL allowed;
			if (frames_doc->GetWindow()->GetGadget())
				if (OpStatus::IsError(OpSecurityManager::CheckSecurity(OpSecurityManager::GADGET_ALLOWED_TO_NAVIGATE, OpSecurityContext(frames_doc), url, allowed)) || !allowed)
					return PUT_SECURITY_VIOLATION;
		}
		}
#endif // GADGET_SUPPORT
		return SetTheURL(frames_doc, ref_url, url, GetCurrentThread(origining_runtime), property_name == OP_ATOM_hash);
	}
	else
		return PUT_SUCCESS;
}
예제 #6
0
OP_STATUS OpFolderListing::GenerateData()
{
#ifdef _LOCALHOST_SUPPORT_
	// Prefix for local files
# ifdef HAS_COMPLEX_GLOBALS
	static const uni_char * const localhost_prefix =
		UNI_L("file://localhost/");
# else
#  define localhost_prefix UNI_L("file://localhost/")
# endif
	static const size_t localhost_prefix_len = 17;
	OP_ASSERT(uni_strlen(localhost_prefix) == localhost_prefix_len);
#endif

	const uni_char * OP_MEMORY_VAR dirend_char = UNI_L("");
#if PATHSEPCHAR != '/'
	const uni_char * OP_MEMORY_VAR displayable_dirend_char = dirend_char;
#else
# define displayable_dirend_char dirend_char
#endif

	// FIXME: OOM - not reported, not checked

	// Set attributes.
	m_url.SetAttribute(URL::KIsDirectoryListing, TRUE);

	// Get the URL and take copies of it for processing.
	OpString base;
	RETURN_IF_ERROR(m_url.GetAttribute(URL::KUniName_Username_Escaped, base));
	m_temp_base = SetNewStr(base.CStr());
	m_displayable_base_url = SetNewStr(base.CStr());
	if (!m_temp_base || !m_displayable_base_url)
	{
		return OpStatus::ERR_NO_MEMORY;
	}

	// Check if this is a local file or not.
#ifdef _LOCALHOST_SUPPORT_
	OP_MEMORY_VAR bool is_local_file = false;
#else
	static const bool is_local_file = false;
#endif
#ifdef _LOCALHOST_SUPPORT_
	if (uni_strncmp(m_displayable_base_url, localhost_prefix, localhost_prefix_len) == 0)
	{
		is_local_file = true;
	}
#endif

	static const uni_char pathsepchar = '/';

	//  If wildchars, remove upto last PATHSEPCHAR/
	unsigned int PathLen = uni_strcspn(m_temp_base, UNI_L(WILDCHARS));
	if (PathLen != uni_strlen(m_temp_base))
	{
		int i;
		for (i = PathLen; i > 0 && m_temp_base[i] != PATHSEPCHAR && m_temp_base[i] != '/' && m_temp_base[i] != '\\' ; i--) {}
		m_temp_base[i] = '\0';
	}

	PathLen = uni_strcspn(m_temp_base,UNI_L("?"));
	m_temp_base[PathLen] = '\0';
	{
		// Ignore parameter portion, but only for the last element to ensure
		// proper path names for FTP and file (anyone using parameters in the
		// parent directories will just have to take their chances).
		uni_char *temp_path = uni_strrchr(m_temp_base, '/'); // don't bother looking for backslash
		if(temp_path)
		{
			uni_char *temp_param = uni_strchr(temp_path, ';');
			if(temp_param)
			{
				PathLen = temp_param - m_temp_base;
				m_temp_base[PathLen] = '\0';
			}
		}
	}

	// If the path does not end in a path separator, add one.
	if (m_temp_base[PathLen-1] != '/'
#if PATHSEPCHAR != '/'
		&& m_temp_base[PathLen-1] != PATHSEPCHAR
#endif
	   )
	{
		dirend_char = UNI_L("/");
#if PATHSEPCHAR != '/'
		if (is_local_file)
		{
			displayable_dirend_char = UNI_L(PATHSEP);
		}
		else
		{
			displayable_dirend_char = dirend_char;
		}
#endif
	}

	// Create a HTML version of the URL string.
	m_htmlified_url = HTMLify_string(m_temp_base);
	if (!m_htmlified_url)
	{
		return OpStatus::ERR_NO_MEMORY;
	}

	// Transmogrify the URL to make it displayable.
	UriUnescape::ReplaceChars(m_displayable_base_url,
		(static_cast<URLType>(m_url.GetAttribute(URL::KType)) == URL_FILE ?
		 UriUnescape::LocalfileUrlUtf8 : UriUnescape::SafeUtf8));

	// Remove localhost prefix
	if (is_local_file)
		op_memmove(m_displayable_base_url, m_displayable_base_url + localhost_prefix_len, UNICODE_SIZE(uni_strlen(m_displayable_base_url + localhost_prefix_len) + 1));

#ifdef SYS_CAP_FILESYSTEM_HAS_DRIVES
	// Clean up the generated path string
	if (is_local_file)
	{
		// Replace Netscape-compatible "|" as drive letter postfix with
		// a drive separator, which we assume to be ":"
		if (m_displayable_base_url[0] &&
		    '|' == m_displayable_base_url[1])
		{
			m_displayable_base_url[1] = ':';
		}

		// Make sure drive letter is upper-cased
		if (Unicode::IsLower(m_displayable_base_url[0]))
		{
			m_displayable_base_url[0] = Unicode::ToUpper(m_displayable_base_url[0]);
		}
	}
#endif

	// Remove formatting characters
	RemoveFormattingCharacters(m_displayable_base_url);

	// Create a HTML version of the displayable URL string.
	m_htmlified_displayable_base_url = HTMLify_string(m_displayable_base_url);
	if (!m_htmlified_displayable_base_url)
	{
		return OpStatus::ERR_NO_MEMORY;
	}

	// Set up the document title from the displayable URL string.
	OpString document_title;
#ifndef SYS_CAP_FILESYSTEM_HAS_DRIVES
	if (is_local_file)
	{
		// Include an initial slash for local files on file systems that do
		// not have drive letters, to avoid blank titles or titles like
		// "usr/bin".
		if (uni_strcmp(m_htmlified_displayable_base_url, localhost_prefix) == 0)
		{
			RETURN_IF_ERROR(document_title.Set("/"));
		}
		else
		{
			RETURN_IF_ERROR(document_title.SetConcat(UNI_L("/"), m_htmlified_displayable_base_url));
		}
	}
	else
#endif
	{
		RETURN_IF_ERROR(document_title.Set(m_htmlified_displayable_base_url));
	}


	// Write the document.
#ifdef _LOCALHOST_SUPPORT_
	OpString dirstyle;
	TRAP_AND_RETURN(rc, g_pcfiles->GetFileURLL(PrefsCollectionFiles::StyleDirFile, &dirstyle));
	RETURN_IF_ERROR(OpenDocument(document_title.CStr(), dirstyle.CStr()));
#else
	RETURN_IF_ERROR(OpenDocument(document_title.CStr(), NULL));
#endif

	m_url.WriteDocumentDataUniSprintf(UNI_L(" <base href=\"%s%s\">\n"), m_htmlified_url, dirend_char);

	RETURN_IF_ERROR(OpenBody(Str::S_FOLDER_LISTING_TEXT));

	RETURN_IF_ERROR(m_url.WriteDocumentData(URL::KNormal, UNI_L("<h2>")));

	// Provide links to each parent directory in the hierarchy.
	size_t len_htmlified = uni_strlen(m_htmlified_url);
	size_t len_displayable = uni_strlen(m_htmlified_displayable_base_url);
	size_t idx_htmlified = 0, idx_displayable = 0;
	uni_char *protocolsuffix = NULL;
	if (NULL != (protocolsuffix = uni_strstr(m_htmlified_url, UNI_L("://"))))
	{
		uni_char *thirdslash = uni_strchr(protocolsuffix + 3, '/');
		if (thirdslash)
		{
			idx_htmlified = thirdslash - m_htmlified_url + 1;
			if(!is_local_file)
			{
				m_url.WriteDocumentDataUniSprintf(UNI_L("<a href=\"%.*s\">%.*s</a>"), idx_htmlified, m_htmlified_url, idx_htmlified, m_htmlified_url);
			}
		}
		else
		{
			idx_htmlified = static_cast<size_t>(-1);
		}
	}
	else
	{
		idx_htmlified = static_cast<size_t>(-1);
	}
	if (NULL != (protocolsuffix = uni_strstr(m_htmlified_displayable_base_url, UNI_L("://"))))
	{
		uni_char *thirdslash = uni_strchr(protocolsuffix + 3, '/');
		if (thirdslash)
		{
			idx_displayable = thirdslash - m_htmlified_displayable_base_url + 1;
		}
	}

	if (static_cast<size_t>(-1) == idx_htmlified)
	{
		m_url.WriteDocumentDataUniSprintf(UNI_L("%s%s</h2>\n\n"),
										  m_htmlified_url, displayable_dirend_char);
	}
	else
	{
#ifndef SYS_CAP_FILESYSTEM_HAS_DRIVES
		if (is_local_file)
		{
			// Add the initial slash manually, as it does not have a
			// left-hand-side component.
			m_url.WriteDocumentDataUniSprintf(UNI_L("<a href=\"%s\">/</a>"), localhost_prefix);
		}
#endif
		while (idx_htmlified < len_htmlified && idx_displayable < len_displayable)
		{
			uni_char *nextslash_htmlified = uni_strchr(m_htmlified_url + idx_htmlified, '/');
			if (!nextslash_htmlified)
			{
				nextslash_htmlified = m_htmlified_url + len_htmlified;
			}
			uni_char *nextslash_displayable =
				uni_strchr(m_htmlified_displayable_base_url + idx_displayable, pathsepchar);
			if (!nextslash_displayable)
			{
				nextslash_displayable = m_htmlified_displayable_base_url + len_displayable;
			}
			int temp_idx_htmlified = nextslash_htmlified - m_htmlified_url;
			int temp_idx_displayable = nextslash_displayable - m_htmlified_displayable_base_url;

			m_url.WriteDocumentDataUniSprintf(UNI_L("<a href=\"%.*s/\">%.*s</a>/"),
											 temp_idx_htmlified, m_htmlified_url,
											 temp_idx_displayable - idx_displayable, &m_htmlified_displayable_base_url[idx_displayable]);

			idx_htmlified = temp_idx_htmlified + 1;
			idx_displayable = temp_idx_displayable + 1;
		}
		m_url.WriteDocumentData(URL::KNormal, UNI_L("</h2>\n\n"));
	}

	// Clean up.
	delete[] m_temp_base; m_temp_base = NULL;
	delete[] m_htmlified_url; m_htmlified_url = NULL;
	delete[] m_displayable_base_url; m_displayable_base_url = NULL;
	delete[] m_htmlified_displayable_base_url; m_htmlified_displayable_base_url = NULL;

	return OpStatus::OK;
}