/* 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; }
/* 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; }