void JSValue::setTainted(unsigned int tainted) { if (isString()) { asString(*this)->setTainted(tainted); } else if (isObject()) { if (this->inherits(&StringObject::s_info)) { return asStringObject(*this)->setTainted(tainted); } } }
JSValue JSC_HOST_CALL stringProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { // Also used for valueOf. if (thisValue.isString()) return thisValue; if (thisValue.isObject(&StringObject::info)) return asStringObject(thisValue)->internalValue(); return throwError(exec, TypeError); }
EncodedJSValue JSC_HOST_CALL jsHTMLDocumentPrototypeFunctionWrite(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (!thisValue.inherits(&JSHTMLDocument::s_info)) return throwVMTypeError(exec); JSHTMLDocument* castedThis = static_cast<JSHTMLDocument*>(asObject(thisValue)); #if defined(JSC_TAINTED) /* if we comment out the following code segement and move the detection to bindings/js/JSHTMLDocumentCustom.cpp one of the test case like below cannot be detected anymore. need to investigate the reason behind. document.write("hello"+document.location.href.substring(document.location.href.indexOf("default=")+8));\ the guess is the following code does not cover the primitive string. */ JSValue s = exec->argument(0); if (s.isString() && s.isTainted()) { HTMLDocument* d1 = static_cast<HTMLDocument*>(castedThis->impl()); d1->setTainted(s.isTainted()); TaintedStructure trace_struct; trace_struct.taintedno = s.isTainted(); trace_struct.internalfunc = "jsHTMLDocumentPrototypeFunctionWrite"; trace_struct.jsfunc = "document.write"; trace_struct.action = "sink"; trace_struct.value = TaintedUtils::UString2string(s.toString(exec)); TaintedTrace* trace = TaintedTrace::getInstance(); trace->addTaintedTrace(trace_struct); } if (s.inherits(&StringObject::s_info)) { unsigned int tainted = asStringObject(s)->isTainted(); if (tainted) { HTMLDocument* d2 = static_cast<HTMLDocument*>(castedThis->impl()); d2->setTainted(tainted); TaintedStructure trace_struct; trace_struct.taintedno = tainted; trace_struct.internalfunc = "jsHTMLDocumentPrototypeFunctionWrite"; trace_struct.jsfunc = "document.write"; trace_struct.action = "sink"; trace_struct.value = TaintedUtils::UString2string(s.toString(exec)); TaintedTrace* trace = TaintedTrace::getInstance(); trace->addTaintedTrace(trace_struct); } } #endif return JSValue::encode(castedThis->write(exec)); }
unsigned int JSValue::isTainted() const { #ifdef JSC_TAINTED_DEBUG // The JSValue class itself does not have the tainted flag, the tainted flag is located in the UString class wrapped by JSString and StringObject. #endif if (isString()) { return asString(*this)->isTainted(); } else if (isObject()) { if (this->inherits(&StringObject::s_info)) { return asStringObject(*this)->isTainted(); } else { return 0; } } else { return 0; } }
EncodedJSValue JSC_HOST_CALL jsHTMLDocumentPrototypeFunctionWriteln(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (!thisValue.inherits(&JSHTMLDocument::s_info)) return throwVMTypeError(exec); JSHTMLDocument* castedThis = static_cast<JSHTMLDocument*>(asObject(thisValue)); #if defined(JSC_TAINTED) JSValue s = exec->argument(0); if (s.isString() && s.isTainted() > 0) { HTMLDocument* d1 = static_cast<HTMLDocument*>(castedThis->impl()); d1->setTainted(s.isTainted()); TaintedStructure trace_struct; trace_struct.taintedno = s.isTainted(); trace_struct.internalfunc = "jsHTMLDocumentPrototypeFunctionWriteln"; trace_struct.jsfunc = "document.writeln"; trace_struct.action = "sink"; trace_struct.value = TaintedUtils::UString2string(s.toString(exec)); TaintedTrace* trace = TaintedTrace::getInstance(); trace->addTaintedTrace(trace_struct); } if (s.inherits(&StringObject::s_info)) { unsigned int tainted = asStringObject(s)->isTainted(); if (tainted) { HTMLDocument* d2 = static_cast<HTMLDocument*>(castedThis->impl()); d2->setTainted(tainted); TaintedStructure trace_struct; trace_struct.taintedno = tainted; trace_struct.internalfunc = "jsHTMLDocumentPrototypeFunctionWriteln"; trace_struct.jsfunc = "document.writeln"; trace_struct.action = "sink"; trace_struct.value = TaintedUtils::UString2string(s.toString(exec)); TaintedTrace* trace = TaintedTrace::getInstance(); trace->addTaintedTrace(trace_struct); } } #endif return JSValue::encode(castedThis->writeln(exec)); }
bool JSCryptoAlgorithmDictionary::getAlgorithmIdentifier(ExecState* exec, JSValue value, CryptoAlgorithmIdentifier& algorithmIdentifier) { // typedef (Algorithm or DOMString) AlgorithmIdentifier; String algorithmName; if (value.isString()) algorithmName = value.toString(exec)->value(exec); else if (value.isObject()) { if (value.getObject()->inherits(StringObject::info())) algorithmName = asString(asStringObject(value)->internalValue())->value(exec); else { // FIXME: This doesn't perform some checks mandated by WebIDL for dictionaries: // - null and undefined input should be treated as if all elements in the dictionary were undefined; // - undefined elements should be treated as having a default value, or as not present if there isn't such; // - RegExp and Date objects cannot be converted to dictionaries. // // This is partially because we don't implement it elsewhere in WebCore yet, and partially because // WebCrypto doesn't yet clearly specify what to do with non-present values in most cases anyway. JSDictionary dictionary(exec, value.getObject()); dictionary.get("name", algorithmName); } } if (exec->hadException()) return false; if (!algorithmName.containsOnlyASCII()) { throwSyntaxError(exec); return false; } if (!CryptoAlgorithmRegistry::singleton().getIdentifierForName(algorithmName, algorithmIdentifier)) { setDOMException(exec, NOT_SUPPORTED_ERR); return false; } return true; }