예제 #1
0
static OP_STATUS
XMLWriteToFileEscaped (OpFile &file, const uni_char *string)
{
  if (*string)
    {
      TempBuffer buffer;

      while (*string)
        {
          if (*string == '&')
            RETURN_IF_ERROR (buffer.Append ("&"));
          else if (*string == '<')
            RETURN_IF_ERROR (buffer.Append ("&#60;"));
          else if (*string == '\'')
            RETURN_IF_ERROR (buffer.Append ("&#27;"));
          else
            RETURN_IF_ERROR (buffer.Append (*string));

          ++string;
        }

      return XMLWriteToFile (file, buffer.GetStorage ());
    }
  else
    return OpStatus::OK;
}
예제 #2
0
double
XPath_ConversionExpressionHelper::GetNumberL (XPath_Context *context, BOOL initial)
{
  OP_ASSERT (!numberexpression);

  StartL (context, initial);

  TempBuffer buffer; ANCHOR (TempBuffer, buffer);
  if (GetStringValueL (context, initial, buffer))
    return XPath_Value::AsNumber (buffer.GetStorage ());
  else if (booleanexpression)
    return booleanexpression->EvaluateToBooleanL (context, initial) ? 1. : 0.;
  else if (stringexpression)
    return XPath_Value::AsNumber (stringexpression->EvaluateToStringL (context, initial, buffer));

#ifdef XPATH_EXTENSION_SUPPORT
  OP_ASSERT (unknown);
  XPath_Value *value = unknown->EvaluateL (context, initial);
  double number = value->AsNumberL ();
  XPath_Value::DecRef (context, value);
  return number;
#else // XPATH_EXTENSION_SUPPORT
  OP_ASSERT (FALSE);
  return op_nan (0);
#endif // XPATH_EXTENSION_SUPPORT
}
예제 #3
0
/* static */ OP_STATUS
DOM_LSInput::GetStringData(const uni_char *&stringData, ES_Object *input, DOM_EnvironmentImpl *environment)
{
	DOM_Runtime *runtime = environment->GetDOMRuntime();
	OP_BOOLEAN result;
	ES_Value value;

	stringData = NULL;

	RETURN_IF_ERROR(result = runtime->GetName(input, UNI_L("characterStream"), &value));
	if (result == OpBoolean::IS_TRUE && value.type != VALUE_NULL && value.type != VALUE_UNDEFINED && !(value.type == VALUE_STRING && *value.value.string))
		return OpStatus::OK;

	RETURN_IF_ERROR(result = runtime->GetName(input, UNI_L("byteStream"), &value));
	if (result == OpBoolean::IS_TRUE && value.type != VALUE_NULL && value.type != VALUE_UNDEFINED && !(value.type == VALUE_STRING && *value.value.string))
		return OpStatus::OK;

	RETURN_IF_ERROR(result = runtime->GetName(input, UNI_L("stringData"), &value));
	if (result == OpBoolean::IS_TRUE && value.type == VALUE_STRING && *value.value.string)
	{
		TempBuffer *buffer = environment->GetWindow()->GetEmptyTempBuf();
		RETURN_IF_ERROR(buffer->Append(value.value.string));
		stringData = buffer->GetStorage();
	}

	return OpStatus::OK;
}
예제 #4
0
/* static */ double
XPath_Value::AsNumberL (const uni_char *string, unsigned string_length)
{
  TempBuffer buffer; ANCHOR (TempBuffer, buffer);
  buffer.AppendL (string, string_length);

  uni_char *endptr;
  return uni_strtod (buffer.GetStorage (), &endptr);
}
예제 #5
0
XMLTreeAccessor::Node *
XPath_Node::GetTreeNodeByIdL (const uni_char *id, unsigned id_length)
{
  TempBuffer buffer; ANCHOR (TempBuffer, buffer);
  buffer.AppendL (id, id_length);

  XMLTreeAccessor::Node *node;
  LEAVE_IF_ERROR (tree->GetElementById (node, buffer.GetStorage ()));

  return node;
}
예제 #6
0
OP_STATUS
DOM_CSSStyleDeclaration::MutationState::AfterChange()
{
	if (send_attrmodified)
	{
		TempBuffer newBuffer;
		StyleAttribute* styleattr = element->GetThisElement()->GetStyleAttribute();
		if (styleattr)
			OpStatus::Ignore(styleattr->ToString(&newBuffer));

		const uni_char *prevValue = prevBuffer.GetStorage(), *newValue = newBuffer.GetStorage();
		if (!(prevValue == newValue || prevValue && newValue && uni_strcmp(prevValue, newValue) == 0))
		{
			DOM_Attr* attr;
			PUT_FAILED_IF_ERROR(element->GetAttributeNode(attr, ATTR_XML, UNI_L("style"), NS_IDX_DEFAULT, TRUE, TRUE, TRUE));
			if (attr)
				PUT_FAILED_IF_ERROR(element->SendAttrModified(DOM_Object::GetCurrentThread(origining_runtime), attr, prevValue, newValue));
		}
	}

	return OpStatus::OK;
}
예제 #7
0
/* static */ BOOL
ES_DebugBuiltins::getObjectDemographics(ES_Execution_Context *context, unsigned argc, ES_Value_Internal *argv, ES_Value_Internal *return_value)
{
    return_value->SetNull();

	if (argc == 1)
	{
        if (!argv[0].ToNumber(context) || !argv[0].IsUInt32())
            return FALSE;

		if (ES_Heap *heap = g_ecmaManager->GetHeapById(argv[0].GetNumAsUInt32()))
		{
			TempBuffer *buffer = g_ecmaManager->GetHeapDebuggerBuffer();

			buffer->Clear();
			buffer->Append("{ ");

			unsigned *live_objects = heap->live_objects;

			for (unsigned index = 0; index < GCTAG_UNINITIALIZED; ++index)
			{
				if (index != 0)
					buffer->Append(", ");

				buffer->Append("\"");
				buffer->Append(g_ecmaClassName[index]);
				buffer->Append("\": ");
				buffer->AppendUnsignedLong(live_objects[index]);
			}

			buffer->Append(" }");

            return_value->SetString(JString::Make(context, buffer->GetStorage(), buffer->Length()));
		}
	}

	return TRUE;
}
예제 #8
0
/* static */ OP_STATUS
DOM_LSInput::GetSystemId(const uni_char *&systemId, ES_Object *input, DOM_EnvironmentImpl *environment)
{
	OP_BOOLEAN result;
	ES_Value value;

	systemId = NULL;

	const uni_char *stringData;

	RETURN_IF_ERROR(GetStringData(stringData, input, environment));
	if (stringData)
		return OpStatus::OK;

	RETURN_IF_ERROR(result =  environment->GetDOMRuntime()->GetName(input, UNI_L("systemId"), &value));
	if (result == OpBoolean::IS_TRUE && value.type == VALUE_STRING && *value.value.string)
	{
		TempBuffer *buffer = environment->GetWindow()->GetEmptyTempBuf();
		RETURN_IF_ERROR(buffer->Append(value.value.string));
		systemId = buffer->GetStorage();
	}

	return OpStatus::OK;
}
예제 #9
0
/* static */ OP_STATUS
JS_Console::FormatString(ES_Value* argv, int argc, OpString &str)
{
	if (argc == 0)
		return OpStatus::OK;

	// Holds the formatted string.
	TempBuffer buf;

	// The argument which will be stringified next.
	int argument = 0;

	// If the first argument is a string, check if it contains placeholders.
	if (argv[0].type == VALUE_STRING)
	{
		// The first argument is the format string. It may or may not contain
		// formatting placeholders (%).
		const uni_char *placeholder = argv[0].value.string;
		const uni_char *stored = placeholder;

		// Skip the formatting string.
		++argument;

		while ((placeholder = uni_strchr(placeholder, '%')) != NULL)
		{
			// Calculate the length until the '%'.
			int length = (placeholder - stored);

			// Skip the '%', and check that 'placeholder' now points to
			// a supported character.
			if (!JS_Console::IsSupportedPlaceholder(++placeholder))
				continue;

			// Append everything up until the '%'.
			if (length > 0)
				RETURN_IF_ERROR(buf.Append(stored, length));

			// If the character after the first '%' is another '%', then output
			// a single '%'.
			if (*placeholder == '%')
				RETURN_IF_ERROR(buf.Append("%"));
			// Otherwise, append the string representation of the ES_Value.
			else if (argument < argc)
				RETURN_IF_ERROR(JS_Console::AppendValue(argv[argument++], buf));
			// Or, if we don't have more arguments, output the original placeholder.
			else
				RETURN_IF_ERROR(buf.Append(placeholder - 1, 2));

			// Skip the character following the %, but only if not at the
			// end of string.
			if (*placeholder != '\0')
				++placeholder;

			stored = placeholder;
		}

		// Append the rest of the formatting string, if any.
		if (*stored != '\0')
			RETURN_IF_ERROR(buf.Append(stored));
	}

	// If we have more arguments, append them in a space delimited list.
	while (argument < argc)
	{
		// Never start a string with a space.
		if (argument > 0)
			RETURN_IF_ERROR(buf.Append(" "));

		RETURN_IF_ERROR(AppendValue(argv[argument++], buf));
	}

	return str.Set(buf.GetStorage());
}
예제 #10
0
/* static */ BOOL
ES_DebugBuiltins::getHeapInformation(ES_Execution_Context *context, unsigned argc, ES_Value_Internal *argv, ES_Value_Internal *return_value)
{
	Head *active, *inactive, *destroy;

	g_ecmaManager->GetHeapLists(active, inactive, destroy);

	TempBuffer *buffer = g_ecmaManager->GetHeapDebuggerBuffer();
	buffer->Clear();

	buffer->Append("{ \"heaps\": { ");

	ES_Heap *heads[3] = { static_cast<ES_Heap *>(active->First()), static_cast<ES_Heap *>(inactive->First()), static_cast<ES_Heap *>(destroy->First()) };

	for (unsigned head = 0; head < 3; ++head)
		for (ES_Heap *heap = heads[head]; heap; heap = static_cast<ES_Heap *>(heap->Suc()))
		{
			buffer->AppendFormat(UNI_L("\"%u\": { \"bytesLive\": %u, \"bytesLivePeak\": %u, \"bytesLimit\": %u, \"runtimes\": ["), heap->Id(), heap->GetBytesLive(), heap->GetBytesLivePeak(), heap->GetBytesLimit());

			ES_Runtime *runtime = heap->GetFirstRuntime();

			while (runtime)
			{
#ifndef _STANDALONE
				ES_Object *global_object = runtime->GetGlobalObject();
				if (global_object->IsHostObject() && ES_Runtime::GetHostObject(global_object)->IsA(DOM_TYPE_WINDOW))
				{
					OpString url;

					DOM_Utils::GetOriginURL(DOM_Utils::GetDOM_Runtime(runtime)).GetAttribute(URL::KUniName, url);

					for (unsigned index = 0; index < static_cast<unsigned>(url.Length()); ++index)
						if (url.CStr()[index] == '"')
							url.Insert(index++, "\\");

					buffer->AppendFormat(UNI_L("\"%s\""), url.CStr());
				}
				else
#endif // _STANDALONE
					buffer->Append("\"<unidentified runtime>\"");

				runtime = g_ecmaManager->GetNextRuntimePerHeap(runtime);

				if (runtime)
					buffer->Append(", ");
			}

			buffer->Append("] }, ");
		}

	buffer->AppendFormat(UNI_L("\"count\": %u }, \"allocators\": ["), active->Cardinal() + inactive->Cardinal() + destroy->Cardinal());

	for (ES_PageAllocator *allocator = static_cast<ES_PageAllocator *>(g_ecmaPageAllocatorList->First()); allocator; allocator = static_cast<ES_PageAllocator *>(allocator->Suc()))
	{
		buffer->AppendFormat(UNI_L("{ \"chunks\": %u, \"chunkSize\": %u, \"pages\": %u, \"pageSize\": %u, \"heaps\": ["), allocator->CountChunks(), allocator->ChunkSize(), allocator->CountPages(), allocator->PageSize());

		for (ES_HeapHandle *heaph = allocator->GetFirstHeapHandle(); heaph; heaph = static_cast<ES_HeapHandle *>(heaph->Suc()))
		{
			buffer->AppendUnsignedLong(heaph->heap->Id());

			if (heaph->Suc())
				buffer->Append(", ");
		}

		buffer->Append("] }");

		if (allocator->Suc())
			buffer->Append(", ");
	}

	buffer->Append("], \"cachedPrograms\": [");

	for (Link *link = RT_DATA.program_cache->GetCachedPrograms()->First(); link; link = link->Suc())
	{
		ES_ProgramCodeStatic *program = static_cast<ES_ProgramCodeStatic *>(link);

		buffer->AppendFormat(UNI_L("{ \"url\": \"\", \"length\": %u }"), program->source.GetSource()->length);

		if (link->Suc())
			buffer->Append(", ");
	}

	buffer->Append("] }");

    return_value->SetString(JString::Make(context, buffer->GetStorage(), buffer->Length()));

    return TRUE;
}
예제 #11
0
void
XPath_Node::GetStringValueL (TempBuffer &value)
{
  XMLTreeAccessor::Node *iter = treenode, *first = 0;
  const uni_char *data = 0;
  BOOL id, specified;

  switch (type)
    {
    case XP_NODE_ROOT:
    case XP_NODE_ELEMENT:
      LEAVE_IF_ERROR (tree->GetCharacterDataContent (data, treenode, &value));
      break;

    case XP_NODE_TEXT:
      while (XPath_Utils::GetNodeType (tree, iter) == XP_NODE_TEXT)
        {
          first = iter;

          if (XMLTreeAccessor::Node *previous = tree->GetPreviousSibling (iter))
            iter = previous;
          else
            break;
        }
      while (first && XPath_Utils::GetNodeType (tree, first) == XP_NODE_TEXT)
        {
          LEAVE_IF_ERROR (tree->GetData (data, first, &value));
          if (data != value.GetStorage ())
            /* Tree accessor returned text without generating into 'value' as
               an optimization.  But we really want it in 'value'. */
            value.AppendL (data);
          first = tree->GetNextSibling (first);
        }
      return;

    case XP_NODE_ATTRIBUTE:
      LEAVE_IF_ERROR (tree->GetAttribute (tree->GetAttributes (treenode, FALSE, TRUE), name, data, id, specified, &value));
      break;

    case XP_NODE_NAMESPACE:
      {
        const uni_char *uri = name.GetUri ();
        if (uri)
          value.AppendL (uri);
        return;
      }

    case XP_NODE_PI:
    case XP_NODE_COMMENT:
      LEAVE_IF_ERROR (tree->GetData (data, iter, &value));
      break;
    }

  /* Common case for XP_NODE_ROOT, XP_NODE_ELEMENT, XP_NODE_ATTRIBUTE,
     XP_NODE_PI and XP_NODE_COMMENT: check if the tree accessor generated the
     returned string into the buffer or if it returned a pointer to a string
     owned by the tree accessor. */

  if (data != value.GetStorage ())
    value.AppendL (data);
}
예제 #12
0
void SetDataFromItemData(const BookmarkItemData* item_data, BookmarkItem* bookmark)
{
	if (!bookmark || !item_data) return;

	// these 2 attributes must exist, as they have a different default value with others. (-1)
	::SetAttribute(bookmark, BOOKMARK_PERSONALBAR_POS, -1);
	::SetAttribute(bookmark, BOOKMARK_PANEL_POS, -1);	

	::SetAttribute(bookmark, BOOKMARK_URL,			item_data->url);
	::SetAttribute(bookmark, BOOKMARK_TITLE,		item_data->name);
	::SetAttribute(bookmark, BOOKMARK_DESCRIPTION,	item_data->description);
	::SetAttribute(bookmark, BOOKMARK_SHORTNAME,	item_data->shortname);
	::SetAttribute(bookmark, BOOKMARK_CREATED,		item_data->created);
	::SetAttribute(bookmark, BOOKMARK_VISITED,		item_data->visited);
	::SetAttribute(bookmark, BOOKMARK_TARGET,		item_data->target);
	::SetAttribute(bookmark, BOOKMARK_PERSONALBAR_POS,item_data->personalbar_position);
	::SetAttribute(bookmark, BOOKMARK_PANEL_POS,	item_data->panel_position);
	::SetAttribute(bookmark, BOOKMARK_ACTIVE,		item_data->active);
	::SetAttribute(bookmark, BOOKMARK_EXPANDED,		item_data->expanded);
	::SetAttribute(bookmark, BOOKMARK_SMALLSCREEN,	item_data->small_screen);
	::SetAttribute(bookmark, BOOKMARK_SHOW_IN_PERSONAL_BAR,item_data->personalbar_position >= 0);
	::SetAttribute(bookmark, BOOKMARK_SHOW_IN_PANEL,item_data->panel_position >= 0);
	::SetAttribute(bookmark, BOOKMARK_PARTNER_ID,	item_data->partner_id);
	::SetAttribute(bookmark, BOOKMARK_DISPLAY_URL,	item_data->display_url);

	// icon
	Image icon = g_favicon_manager->Get(item_data->url);
	OpString16 base64;
	OpBitmap *bitmap = icon.GetBitmap(NULL);
	if (bitmap)
	{
		TempBuffer buffer;
		if(OpStatus::IsSuccess(GetOpBitmapAsBase64PNG(bitmap, &buffer)))
		{
			if(OpStatus::IsSuccess(base64.Set(buffer.GetStorage(), buffer.Length())))
			{
				::SetAttribute(bookmark, BOOKMARK_FAVICON_FILE, base64);
			}
		}
		icon.ReleaseBitmap();
	}
	if (item_data->unique_id.HasContent())
	{
		OpString tmp;
		tmp.Set(item_data->unique_id);
		uni_char* uni_unique_id = OP_NEWA(uni_char, (tmp.Length()+1));
		if (uni_unique_id)
		{
			uni_strcpy(uni_unique_id, tmp.CStr());
			bookmark->SetUniqueId(uni_unique_id);
		}
	}

	bookmark->SetMaxCount(item_data->max_count);
	bookmark->SetMoveIsCopy(item_data->move_is_copy);
	bookmark->SetSubFoldersAllowed(item_data->subfolders_allowed);
	bookmark->SetSeparatorsAllowed(item_data->separators_allowed);
	bookmark->SetDeletable(item_data->deletable);

	bookmark->SetFolderType(item_data->type);
}
예제 #13
0
/* static */ const uni_char *
XPath_Value::AsStringL (double number, TempBuffer &buffer)
{
  char *storage8;

  buffer.ExpandL (33);
  buffer.SetCachedLengthPolicy (TempBuffer::UNTRUSTED);
  storage8 = reinterpret_cast<char *> (buffer.GetStorage ());

  if (op_isnan (number))
    return UNI_L ("NaN");
  else if (number == 0)
    return UNI_L ("0");
  else
    {
      if (!OpDoubleFormat::ToString (storage8, number))
        LEAVE (OpStatus::ERR_NO_MEMORY);

      char *e = 0, *p = 0;
      for (unsigned index = 0; storage8[index]; ++index)
        if (storage8[index] == '.')
          p = &storage8[index];
        else if (storage8[index] == 'e' || storage8[index] == 'E')
          e = &storage8[index];

      if (e)
        {
          TempBuffer b; ANCHOR (TempBuffer, b);

          if (number < 0)
            b.AppendL ("-");

          int exp = op_atoi (e + 1), index;
          *e = 0;
          if (exp > 0)
            {
              if (storage8[0] != '0')
                b.AppendL (storage8[0]);
              if (p)
                {
                  b.AppendL (p + 1, MIN (e - (p + 1), exp));
                  if (exp < e - (p + 1))
                    {
                      b.AppendL (".");
                      b.AppendL (p + 1 + exp, e - (p + 1 + exp));
                    }
                  else if (e - (p + 1) < exp)
                    for (index = exp; index < e - (p + 1); ++index)
                      b.AppendL ("0");
                }
              else
                for (index = 0; index < exp; ++index)
                  b.AppendL ("0");
            }
          else if (exp < 0)
            {
              b.AppendL ("0.");
              for (index = 1; index < -exp; ++index)
                b.AppendL ("0");
              for (index = 0; storage8[index]; ++index)
                if (op_isdigit (storage8[index]) && storage8[index] != '0')
                  break;
              for (; storage8[index]; ++index)
                if (op_isdigit (storage8[index]))
                  b.AppendL (storage8[index]);
            }

          buffer.Clear ();
          buffer.AppendL (b.GetStorage ());
        }
      else
        make_doublebyte_in_place (buffer.GetStorage (), op_strlen (storage8));
    }

  return buffer.GetStorage ();
}
예제 #14
0
/* virtual */ ES_PutState
DOM_CSSStyleDeclaration::PutName(OpAtom property_name, ES_Value *value, ES_Runtime *origining_runtime)
{
#ifdef NS4P_COMPONENT_PLUGINS
	if (FramesDocument* doc = style->GetEnvironment()->GetFramesDocument())
		if (LayoutWorkplace* wp = doc->GetLayoutWorkplace())
			if (wp->IsTraversing() || wp->IsReflowing())
				return PUT_FAILED;
#endif // NS4P_COMPONENT_PLUGINS

	int css_property = DOM_AtomToCssProperty(property_name);
	BOOL is_pos = FALSE, is_pixel = FALSE;
	CSS_DOMException exception = CSS_DOMEXCEPTION_NONE;

	OP_STATUS status = OpStatus::OK;
	OpStatus::Ignore(status);

	switch (property_name)
	{
    case OP_ATOM_posLeft:
    case OP_ATOM_posRight:
    case OP_ATOM_posTop:
    case OP_ATOM_posBottom:
    case OP_ATOM_posWidth:
    case OP_ATOM_posHeight:
		is_pos = TRUE;
		break;

    case OP_ATOM_pixelHeight:
    case OP_ATOM_pixelLeft:
    case OP_ATOM_pixelTop:
    case OP_ATOM_pixelWidth:
    case OP_ATOM_pixelBottom:
    case OP_ATOM_pixelRight:
		is_pixel = TRUE;
		break;

	case OP_ATOM_length:
		return PUT_READ_ONLY;

	case OP_ATOM_cssText:
		if (value->type == VALUE_NULL)
			DOMSetString(value);
		else if (value->type != VALUE_STRING)
			return PUT_NEEDS_STRING;

		if (type == DOM_ST_INLINE)
			PUT_FAILED_IF_ERROR(element->SetAttribute(ATTR_XML, UNI_L("style"), NS_IDX_DEFAULT, value->value.string, value->GetStringLength(), TRUE, origining_runtime));
		else if (type == DOM_ST_RULE)
		{
			OP_STATUS stat = style->SetText(value->value.string, exception);
			if (stat == OpStatus::ERR_NO_MEMORY)
				return PUT_NO_MEMORY;
			else if (stat == OpStatus::ERR)
			{
				if (exception == CSS_DOMEXCEPTION_NO_MODIFICATION_ALLOWED_ERR)
					return PUT_READ_ONLY;
				else if (exception == CSS_DOMEXCEPTION_SYNTAX_ERR)
					return DOM_PUTNAME_DOMEXCEPTION(SYNTAX_ERR);
			}
		}
		return PUT_SUCCESS;

	default:
		if (css_property != -1)
		{
			if (value->type == VALUE_NULL)
				DOMSetString(value);
			else if (value->type != VALUE_STRING)
				return PUT_NEEDS_STRING;

#ifdef DOM2_MUTATION_EVENTS
			MutationState mutationstate(element, (DOM_Runtime *) origining_runtime);
			if (element)
			{
				PUT_FAILED_IF_ERROR(mutationstate.BeforeChange());
			}
#endif // DOM2_MUTATION_EVENTS

			status = style->SetProperty(css_property, value->value.string, exception);

#ifdef DOM2_MUTATION_EVENTS
			if (OpStatus::IsSuccess(status) && element)
				PUT_FAILED_IF_ERROR(mutationstate.AfterChange());
#endif // DOM2_MUTATION_EVENTS

			goto handle_status;
		}
		else
			return PUT_FAILED;
	}

	if (is_pos || is_pixel)
	{
		OP_ASSERT(css_property != -1);

		if (value->type != VALUE_NUMBER)
			return PUT_NEEDS_NUMBER;

		if (is_pixel)
			value->value.number = op_floor(value->value.number);

		TempBuffer *buffer = GetEmptyTempBuf();
		PUT_FAILED_IF_ERROR(buffer->Expand(33));

		char *number8 = reinterpret_cast<char *>(buffer->GetStorage());
		char *result = OpDoubleFormat::ToString(number8, value->value.number);
		if (!result)
			return PUT_NO_MEMORY;
		make_doublebyte_in_place(buffer->GetStorage(), op_strlen(number8));

		if (is_pos)
			status = style->SetPosValue(css_property, buffer->GetStorage(), exception);
		else
			status = style->SetPixelValue(css_property, buffer->GetStorage(), exception);
	}

handle_status:
	if (OpStatus::IsMemoryError(status))
		return PUT_NO_MEMORY;
	else if (OpStatus::IsError(status))
		if (exception == CSS_DOMEXCEPTION_NO_MODIFICATION_ALLOWED_ERR)
			return PUT_READ_ONLY;
		else if (exception == CSS_DOMEXCEPTION_SYNTAX_ERR)
			return DOM_PUTNAME_DOMEXCEPTION(SYNTAX_ERR);

	return PUT_SUCCESS;
}
예제 #15
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;
}
예제 #16
0
/* virtual */ ES_GetState
JS_Location::GetName(OpAtom property_name, ES_Value* value, ES_Runtime* origining_runtime)
{
	TempBuffer *buffer = GetEmptyTempBuf();
	URL url;

	if (fakewindow)
		url = fakewindow->GetURL();
#ifdef SELFTEST
	else if (!do_navigation)
		url = current_url;
#endif // SELFTEST
	else if (FramesDocument *frames_doc = GetFramesDocument())
	{
		url = frames_doc->GetURL();

		// The anchors (hash) might be better in DocumentManager
		URL doc_man_url = frames_doc->GetDocManager()->GetCurrentURL();
		if (doc_man_url == url) // Doesn't compare anchors
			url = doc_man_url;
	}
#ifdef DOM_WEBWORKERS_SUPPORT
	/* No FramesDocument to query, so consult the origin DocumentManager for the Worker */
	if (!GetFramesDocument())
	{
		DOM_WebWorkerController *web_workers = GetEnvironment()->GetWorkerController();
		if (DOM_WebWorker *ww = web_workers->GetWorkerObject())
			url = ww->GetLocationURL();
		else if (DocumentManager *doc = web_workers->GetWorkerDocManager())
			url = doc->GetCurrentURL();
		OP_ASSERT(!url.IsEmpty());
	}
#endif // DOM_WEBWORKERS_SUPPORT

	switch (property_name)
	{
	case OP_ATOM_href:
		DOMSetString(value, url.GetAttribute(URL::KUniName_With_Fragment_Escaped).CStr());
		return GET_SUCCESS;

	case OP_ATOM_protocol:
		if (value)
		{
			const char *protocol = url.GetAttribute(URL::KProtocolName).CStr();
			if (protocol)
			{
				GET_FAILED_IF_ERROR(buffer->Append(protocol));
				GET_FAILED_IF_ERROR(buffer->Append(":"));
			}

			DOMSetString(value, buffer);
		}
		return GET_SUCCESS;

	case OP_ATOM_host:
	case OP_ATOM_hostname:
		if (value)
		{
			const uni_char *name = url.GetServerName() ? url.GetServerName()->UniName() : NULL;

			if (property_name == OP_ATOM_host)
			{
				unsigned short port = url.GetServerPort();
				if (port)
				{
					GET_FAILED_IF_ERROR(buffer->Append(name));
					GET_FAILED_IF_ERROR(buffer->Append(":"));
					GET_FAILED_IF_ERROR(buffer->AppendUnsignedLong(port));
					name = buffer->GetStorage();
				}
			}

			DOMSetString(value, name);
		}
		return GET_SUCCESS;

	case OP_ATOM_port:
		if (value)
		{
			unsigned short port = url.GetServerPort();
			if (port)
				GET_FAILED_IF_ERROR(buffer->AppendUnsignedLong(port));

			DOMSetString(value, buffer);
		}
		return GET_SUCCESS;

	case OP_ATOM_pathname:
		if (value)
		{
			const uni_char *path = url.GetAttribute(URL::KUniPath).CStr();

			if (path)
			{
				GET_FAILED_IF_ERROR(buffer->Append(path));
				uni_char *path_tmp = buffer->GetStorage();

				/* It isn't obvious from the JS spec and the relevant RFC, but in
				   Javascript the 'pathname' excludes any arguments passed to the page. */
				if (uni_char *query_start = uni_strchr(path_tmp, '?'))
				{
					path = path_tmp;
					*query_start = 0;
				}
			}

			DOMSetString(value, path);
		}
		return GET_SUCCESS;

	case OP_ATOM_search:
		if (value)
		{
			const uni_char *name = url.GetAttribute(URL::KUniName).CStr();

			if (name)
				name = uni_strchr(name, '?');

			DOMSetString(value, name);
		}
		return GET_SUCCESS;

	case OP_ATOM_hash:
		if (value)
		{
			const uni_char *fragment = url.UniRelName();

			// MSIE emits "#" for the empty fragment (as in http://www.opera.com/# ) but no other
			// browser does that and neither will we.
			if (fragment && *fragment)
			{
				GET_FAILED_IF_ERROR(buffer->Append('#'));
				GET_FAILED_IF_ERROR(buffer->Append(fragment));
				fragment = buffer->GetStorage();
			}

			DOMSetString(value, fragment);
		}
		return GET_SUCCESS;
	}

	return GET_FAILED;
}