/*
 * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "ContentExtensionParser.h"

#if ENABLE(CONTENT_EXTENSIONS)

#include "CSSParser.h"
#include "CSSParserMode.h"
#include "CSSSelectorList.h"
#include "ContentExtensionError.h"
#include "ContentExtensionRule.h"
#include "ContentExtensionsBackend.h"
#include "ContentExtensionsDebugging.h"
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSGlobalObject.h>
#include <JavaScriptCore/JSONObject.h>
#include <JavaScriptCore/VM.h>
#include <wtf/Expected.h>
#include <wtf/text/WTFString.h>


namespace WebCore {
using namespace JSC;

namespace ContentExtensions {
    
static bool containsOnlyASCIIWithNoUppercase(const String& domain)
{
    for (auto character : StringView { domain }.codeUnits()) {
        if (!isASCII(character) || isASCIIUpper(character))
            return false;
    }
    return true;
}
    
static Expected<Vector<String>, std::error_code> getStringList(ExecState& exec, const JSObject* arrayObject)
{
    static const ContentExtensionError error = ContentExtensionError::JSONInvalidConditionList;
    VM& vm = exec.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (!arrayObject || !isJSArray(arrayObject))
        return makeUnexpected(error);
    const JSArray* array = jsCast<const JSArray*>(arrayObject);
    
    Vector<String> strings;
    unsigned length = array->length();
    for (unsigned i = 0; i < length; ++i) {
        const JSValue value = array->getIndex(&exec, i);
        if (scope.exception() || !value.isString())
            return makeUnexpected(error);
        
        const String& string = asString(value)->value(&exec);
        if (string.isEmpty())
            return makeUnexpected(error);
        strings.append(string);
    }
    return WTFMove(strings);
}

static Expected<Vector<String>, std::error_code> getDomainList(ExecState& exec, const JSObject* arrayObject)
{
    auto strings = getStringList(exec, arrayObject);
    if (!strings.has_value())
        return strings;
    for (auto& domain : strings.value()) {
        // Domains should be punycode encoded lower case.
        if (!containsOnlyASCIIWithNoUppercase(domain))
            return makeUnexpected(ContentExtensionError::JSONDomainNotLowerCaseASCII);
    }
    return strings;
}

static std::error_code getTypeFlags(ExecState& exec, const JSValue& typeValue, ResourceFlags& flags, uint16_t (*stringToType)(const String&))
{
    VM& vm = exec.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (!typeValue.isObject())
        return { };

    const JSObject* object = typeValue.toObject(&exec);
    scope.assertNoException();
    if (!isJSArray(object))
        return ContentExtensionError::JSONInvalidTriggerFlagsArray;

    const JSArray* array = jsCast<const JSArray*>(object);
    
    unsigned length = array->length();
    for (unsigned i = 0; i < length; ++i) {
        const JSValue value = array->getIndex(&exec, i);
        if (scope.exception() || !value)
            return ContentExtensionError::JSONInvalidObjectInTriggerFlagsArray;
        
        String name = value.toWTFString(&exec);
        uint16_t type = stringToType(name);
        if (!type)
            return ContentExtensionError::JSONInvalidStringInTriggerFlagsArray;

        flags |= type;
    }

    return { };
}
    
static Expected<Trigger, std::error_code> loadTrigger(ExecState& exec, const JSObject& ruleObject)
{
    VM& vm = exec.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    const JSValue triggerObject = ruleObject.get(&exec, Identifier::fromString(&exec, "trigger"));
    if (!triggerObject || scope.exception() || !triggerObject.isObject())
        return makeUnexpected(ContentExtensionError::JSONInvalidTrigger);
    
    const JSValue urlFilterObject = triggerObject.get(&exec, Identifier::fromString(&exec, "url-filter"));
    if (!urlFilterObject || scope.exception() || !urlFilterObject.isString())
        return makeUnexpected(ContentExtensionError::JSONInvalidURLFilterInTrigger);

    String urlFilter = asString(urlFilterObject)->value(&exec);
    if (urlFilter.isEmpty())
        return makeUnexpected(ContentExtensionError::JSONInvalidURLFilterInTrigger);

    Trigger trigger;
    trigger.urlFilter = urlFilter;

    const JSValue urlFilterCaseValue = triggerObject.get(&exec, Identifier::fromString(&exec, "url-filter-is-case-sensitive"));
    if (urlFilterCaseValue && !scope.exception() && urlFilterCaseValue.isBoolean())
        trigger.urlFilterIsCaseSensitive = urlFilterCaseValue.toBoolean(&exec);

    const JSValue topURLFilterCaseValue = triggerObject.get(&exec, Identifier::fromString(&exec, "top-url-filter-is-case-sensitive"));
    if (topURLFilterCaseValue && !scope.exception() && topURLFilterCaseValue.isBoolean())
        trigger.topURLConditionIsCaseSensitive = topURLFilterCaseValue.toBoolean(&exec);

    const JSValue resourceTypeValue = triggerObject.get(&exec, Identifier::fromString(&exec, "resource-type"));
    if (!scope.exception() && resourceTypeValue.isObject()) {
        auto typeFlagsError = getTypeFlags(exec, resourceTypeValue, trigger.flags, readResourceType);
        if (typeFlagsError)
            return makeUnexpected(typeFlagsError);
    } else if (!resourceTypeValue.isUndefined())
        return makeUnexpected(ContentExtensionError::JSONInvalidTriggerFlagsArray);

    const JSValue loadTypeValue = triggerObject.get(&exec, Identifier::fromString(&exec, "load-type"));
    if (!scope.exception() && loadTypeValue.isObject()) {
        auto typeFlagsError = getTypeFlags(exec, loadTypeValue, trigger.flags, readLoadType);
        if (typeFlagsError)
            return makeUnexpected(typeFlagsError);
    } else if (!loadTypeValue.isUndefined())
        return makeUnexpected(ContentExtensionError::JSONInvalidTriggerFlagsArray);

    const JSValue ifDomainValue = triggerObject.get(&exec, Identifier::fromString(&exec, "if-domain"));
    if (!scope.exception() && ifDomainValue.isObject()) {
        auto ifDomain = getDomainList(exec, asObject(ifDomainValue));
        if (!ifDomain.has_value())
            return makeUnexpected(ifDomain.error());
        trigger.conditions = WTFMove(ifDomain.value());
        if (trigger.conditions.isEmpty())
            return makeUnexpected(ContentExtensionError::JSONInvalidConditionList);
        ASSERT(trigger.conditionType == Trigger::ConditionType::None);
        trigger.conditionType = Trigger::ConditionType::IfDomain;
    } else if (!ifDomainValue.isUndefined())
        return makeUnexpected(ContentExtensionError::JSONInvalidConditionList);

    const JSValue unlessDomainValue = triggerObject.get(&exec, Identifier::fromString(&exec, "unless-domain"));
    if (!scope.exception() && unlessDomainValue.isObject()) {
        if (trigger.conditionType != Trigger::ConditionType::None)
            return makeUnexpected(ContentExtensionError::JSONMultipleConditions);
        auto unlessDomain = getDomainList(exec, asObject(unlessDomainValue));
        if (!unlessDomain.has_value())
            return makeUnexpected(unlessDomain.error());
        trigger.conditions = WTFMove(unlessDomain.value());
        if (trigger.conditions.isEmpty())
            return makeUnexpected(ContentExtensionError::JSONInvalidConditionList);
        trigger.conditionType = Trigger::ConditionType::UnlessDomain;
    } else if (!unlessDomainValue.isUndefined())
        return makeUnexpected(ContentExtensionError::JSONInvalidConditionList);

    const JSValue ifTopURLValue = triggerObject.get(&exec, Identifier::fromString(&exec, "if-top-url"));
    if (!scope.exception() && ifTopURLValue.isObject()) {
        if (trigger.conditionType != Trigger::ConditionType::None)
            return makeUnexpected(ContentExtensionError::JSONMultipleConditions);
        auto ifTopURL = getStringList(exec, asObject(ifTopURLValue));
        if (!ifTopURL.has_value())
            return makeUnexpected(ifTopURL.error());
        trigger.conditions = WTFMove(ifTopURL.value());
        if (trigger.conditions.isEmpty())
            return makeUnexpected(ContentExtensionError::JSONInvalidConditionList);
        trigger.conditionType = Trigger::ConditionType::IfTopURL;
    } else if (!ifTopURLValue.isUndefined())
        return makeUnexpected(ContentExtensionError::JSONInvalidConditionList);

    const JSValue unlessTopURLValue = triggerObject.get(&exec, Identifier::fromString(&exec, "unless-top-url"));
    if (!scope.exception() && unlessTopURLValue.isObject()) {
        if (trigger.conditionType != Trigger::ConditionType::None)
            return makeUnexpected(ContentExtensionError::JSONMultipleConditions);
        auto unlessTopURL = getStringList(exec, asObject(unlessTopURLValue));
        if (!unlessTopURL.has_value())
            return makeUnexpected(unlessTopURL.error());
        trigger.conditions = WTFMove(unlessTopURL.value());
        if (trigger.conditions.isEmpty())
            return makeUnexpected(ContentExtensionError::JSONInvalidConditionList);
        trigger.conditionType = Trigger::ConditionType::UnlessTopURL;
    } else if (!unlessTopURLValue.isUndefined())
        return makeUnexpected(ContentExtensionError::JSONInvalidConditionList);

    return WTFMove(trigger);
}

bool isValidCSSSelector(const String& selector)
{
    AtomicString::init();
    QualifiedName::init();
    CSSParserContext context(HTMLQuirksMode);
    CSSParser parser(context);
    CSSSelectorList selectorList;
    parser.parseSelector(selector, selectorList);
    return selectorList.isValid();
}

static Expected<std::optional<Action>, std::error_code> loadAction(ExecState& exec, const JSObject& ruleObject)
{
    VM& vm = exec.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    const JSValue actionObject = ruleObject.get(&exec, Identifier::fromString(&exec, "action"));
    if (scope.exception() || !actionObject.isObject())
        return makeUnexpected(ContentExtensionError::JSONInvalidAction);

    const JSValue typeObject = actionObject.get(&exec, Identifier::fromString(&exec, "type"));
    if (scope.exception() || !typeObject.isString())
        return makeUnexpected(ContentExtensionError::JSONInvalidActionType);

    String actionType = asString(typeObject)->value(&exec);

    if (actionType == "block")
        return {{ ActionType::BlockLoad }};
    if (actionType == "ignore-previous-rules")
        return {{ ActionType::IgnorePreviousRules }};
    if (actionType == "block-cookies")
        return {{ ActionType::BlockCookies }};
    if (actionType == "css-display-none") {
        JSValue selector = actionObject.get(&exec, Identifier::fromString(&exec, "selector"));
        if (scope.exception() || !selector.isString())
            return makeUnexpected(ContentExtensionError::JSONInvalidCSSDisplayNoneActionType);

        String selectorString = asString(selector)->value(&exec);
        if (!isValidCSSSelector(selectorString)) {
            // Skip rules with invalid selectors to be backwards-compatible.
            return { std::nullopt };
        }
        return { Action(ActionType::CSSDisplayNoneSelector, selectorString) };
    }
    if (actionType == "make-https")
        return {{ ActionType::MakeHTTPS }};
    if (actionType == "notify") {
        JSValue notification = actionObject.get(&exec, Identifier::fromString(&exec, "notification"));
        if (scope.exception() || !notification.isString())
            return makeUnexpected(ContentExtensionError::JSONInvalidNotification);
        return { Action(ActionType::Notify, asString(notification)->value(&exec)) };
    }
    return makeUnexpected(ContentExtensionError::JSONInvalidActionType);
}

static Expected<std::optional<ContentExtensionRule>, std::error_code> loadRule(ExecState& exec, const JSObject& ruleObject)
{
    auto trigger = loadTrigger(exec, ruleObject);
    if (!trigger.has_value())
        return makeUnexpected(trigger.error());

    auto action = loadAction(exec, ruleObject);
    if (!action.has_value())
        return makeUnexpected(action.error());

    if (action.value())
        return {{{ WTFMove(trigger.value()), WTFMove(action.value().value()) }}};

    return { std::nullopt };
}

static Expected<Vector<ContentExtensionRule>, std::error_code> loadEncodedRules(ExecState& exec, String&& ruleJSON)
{
    VM& vm = exec.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    // FIXME: JSONParse should require callbacks instead of an ExecState.
    const JSValue decodedRules = JSONParse(&exec, ruleJSON);

    if (scope.exception() || !decodedRules)
        return makeUnexpected(ContentExtensionError::JSONInvalid);

    if (!decodedRules.isObject())
        return makeUnexpected(ContentExtensionError::JSONTopLevelStructureNotAnObject);

    const JSObject* topLevelObject = decodedRules.toObject(&exec);
    if (!topLevelObject || scope.exception())
        return makeUnexpected(ContentExtensionError::JSONTopLevelStructureNotAnObject);
    
    if (!isJSArray(topLevelObject))
        return makeUnexpected(ContentExtensionError::JSONTopLevelStructureNotAnArray);

    const JSArray* topLevelArray = jsCast<const JSArray*>(topLevelObject);

    Vector<ContentExtensionRule> ruleList;

    unsigned length = topLevelArray->length();
    const unsigned maxRuleCount = 50000;
    if (length > maxRuleCount)
        return makeUnexpected(ContentExtensionError::JSONTooManyRules);
    for (unsigned i = 0; i < length; ++i) {
        const JSValue value = topLevelArray->getIndex(&exec, i);
        if (scope.exception() || !value)
            return makeUnexpected(ContentExtensionError::JSONInvalidObjectInTopLevelArray);

        const JSObject* ruleObject = value.toObject(&exec);
        if (!ruleObject || scope.exception())
            return makeUnexpected(ContentExtensionError::JSONInvalidRule);

        auto rule = loadRule(exec, *ruleObject);
        if (!rule.has_value())
            return makeUnexpected(rule.error());
        if (rule.value())
            ruleList.append(*rule.value());
    }

    return WTFMove(ruleList);
}

Expected<Vector<ContentExtensionRule>, std::error_code> parseRuleList(String&& ruleJSON)
{
#if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING
    MonotonicTime loadExtensionStartTime = MonotonicTime::now();
#endif
    RefPtr<VM> vm = VM::create();

    JSLockHolder locker(vm.get());
    JSGlobalObject* globalObject = JSGlobalObject::create(*vm, JSGlobalObject::createStructure(*vm, jsNull()));

    ExecState* exec = globalObject->globalExec();
    auto ruleList = loadEncodedRules(*exec, WTFMove(ruleJSON));

    vm = nullptr;

    if (!ruleList.has_value())
        return makeUnexpected(ruleList.error());

    if (ruleList->isEmpty())
        return makeUnexpected(ContentExtensionError::JSONContainsNoRules);

#if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING
    MonotonicTime loadExtensionEndTime = MonotonicTime::now();
    dataLogF("Time spent loading extension %f\n", (loadExtensionEndTime - loadExtensionStartTime).seconds());
#endif

    return WTFMove(*ruleList);
}

} // namespace ContentExtensions
} // namespace WebCore

#endif // ENABLE(CONTENT_EXTENSIONS)
