<commit_before>//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "RuntimeTypePch.h"

#include "Types/NullTypeHandler.h"
#include "Types/SimpleTypeHandler.h"

namespace Js
{
    int NullTypeHandlerBase::GetPropertyCount()
    {
        return 0;
    }

    PropertyId NullTypeHandlerBase::GetPropertyId(ScriptContext* scriptContext, PropertyIndex index)
    {
        return Constants::NoProperty;
    }

    PropertyId NullTypeHandlerBase::GetPropertyId(ScriptContext* scriptContext, BigPropertyIndex index)
    {
        return Constants::NoProperty;
    }

    BOOL NullTypeHandlerBase::FindNextProperty(ScriptContext* scriptContext, PropertyIndex& index, JavascriptString** propertyString, PropertyId* propertyId,
        PropertyAttributes* attributes, Type* type, DynamicType *typeToEnumerate, bool requireEnumerable, bool enumSymbols)
    {
        Assert(propertyString);
        Assert(propertyId);
        Assert(type);
        return FALSE;
    }

    PropertyIndex NullTypeHandlerBase::GetPropertyIndex(PropertyRecord const* propertyRecord)
    {
        return Constants::NoSlot;
    }

    bool NullTypeHandlerBase::GetPropertyEquivalenceInfo(PropertyRecord const* propertyRecord, PropertyEquivalenceInfo& info)
    {
        info.slotIndex = Constants::NoSlot;
        info.isAuxSlot = false;
        info.isWritable = false;
        return false;
    }

    bool NullTypeHandlerBase::IsObjTypeSpecEquivalent(const Type* type, const TypeEquivalenceRecord& record, uint& failedPropertyIndex)
    {
        uint propertyCount = record.propertyCount;
        EquivalentPropertyEntry* properties = record.properties;
        for (uint pi = 0; pi < propertyCount; pi++)
        {
            const EquivalentPropertyEntry* refInfo = &properties[pi];
            if (!this->NullTypeHandlerBase::IsObjTypeSpecEquivalent(type, refInfo))
            {
                return false;
            }
        }
        return true;
    }

    bool NullTypeHandlerBase::IsObjTypeSpecEquivalent(const Type* type, const EquivalentPropertyEntry *entry)
    {
        return entry->slotIndex == Constants::NoSlot && !entry->mustBeWritable;
    }

    BOOL NullTypeHandlerBase::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl)
    {
        // Check numeric propertyId only if objectArray is available
        uint32 indexVal;
        ScriptContext* scriptContext = instance->GetScriptContext();

        if (noRedecl != nullptr)
        {
            *noRedecl = false;
        }

        if (instance->HasObjectArray() && scriptContext->IsNumericPropertyId(propertyId, &indexVal))
        {
            return DynamicTypeHandler::HasItem(instance, indexVal);
        }

        return false;
    }

    BOOL NullTypeHandlerBase::HasProperty(DynamicObject* instance, JavascriptString* propertyNameString)
    {
        PropertyRecord const* propertyRecord;
        instance->GetScriptContext()->GetOrAddPropertyRecord(propertyNameString->GetString(), propertyNameString->GetLength(), &propertyRecord);
        return NullTypeHandlerBase::HasProperty(instance, propertyRecord->GetPropertyId());
    }

    BOOL NullTypeHandlerBase::GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
    {
        // Check numeric propertyId only if objectArray is available
        uint32 indexVal;
        ScriptContext* scriptContext = instance->GetScriptContext();
        if (instance->HasObjectArray() && scriptContext->IsNumericPropertyId(propertyId, &indexVal))
        {
            return DynamicTypeHandler::GetItem(instance, originalInstance, indexVal, value, requestContext);
        }

        *value = requestContext->GetMissingPropertyResult();
        return false;
    }

    BOOL NullTypeHandlerBase::GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
    {
        PropertyRecord const* propertyRecord;
        instance->GetScriptContext()->GetOrAddPropertyRecord(propertyNameString->GetString(), propertyNameString->GetLength(), &propertyRecord);
        return NullTypeHandlerBase::GetProperty(instance, originalInstance, propertyRecord->GetPropertyId(), value, info, requestContext);
    }

    BOOL NullTypeHandlerBase::SetProperty(DynamicObject* instance, PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
    {
        return ConvertToSimpleType(instance)->SetProperty(instance, propertyId, value, flags, info);
    }

    BOOL NullTypeHandlerBase::SetProperty(DynamicObject* instance, JavascriptString* propertyNameString, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
    {
        return ConvertToSimpleType(instance)->SetProperty(instance, propertyNameString, value, flags, info);
    }

    BOOL NullTypeHandlerBase::AddProperty(DynamicObject* instance, PropertyId propertyId, Var value, PropertyAttributes attributes, PropertyValueInfo* info, PropertyOperationFlags flags, SideEffects possibleSideEffects)
    {
        if (this->isPrototype && (ChangeTypeOnProto() || (GetIsShared() && IsolatePrototypes())))
        {
            ScriptContext* scriptContext = instance->GetScriptContext();
            return ConvertToSimpleDictionaryType(instance)->AddProperty(instance, scriptContext->GetPropertyName(propertyId), value, attributes, info, flags, possibleSideEffects);
        }
        else
        {
            return ConvertToSimpleType(instance)->AddProperty(instance, propertyId, value, attributes, info, flags, possibleSideEffects);
        }
    }

    BOOL NullTypeHandlerBase::DeleteProperty(DynamicObject* instance, PropertyId propertyId, PropertyOperationFlags flags)
    {
        // Check numeric propertyId only if objectArray is available
        ScriptContext* scriptContext = instance->GetScriptContext();
        uint32 indexVal;
        if (instance->HasObjectArray() && scriptContext->IsNumericPropertyId(propertyId, &indexVal))
        {
            return DynamicTypeHandler::DeleteItem(instance, indexVal, flags);
        }

        return true;
    }

    BOOL NullTypeHandlerBase::IsEnumerable(DynamicObject* instance, PropertyId propertyId)
    {
        return true;
    }

    BOOL NullTypeHandlerBase::IsWritable(DynamicObject* instance, PropertyId propertyId)
    {
        return true;
    }

    BOOL NullTypeHandlerBase::IsConfigurable(DynamicObject* instance, PropertyId propertyId)
    {
        return true;
    }

    BOOL NullTypeHandlerBase::SetEnumerable(DynamicObject* instance, PropertyId propertyId, BOOL value)
    {
        return false;
    }

    BOOL NullTypeHandlerBase::SetWritable(DynamicObject* instance, PropertyId propertyId, BOOL value)
    {
        return false;
    }

    BOOL NullTypeHandlerBase::SetConfigurable(DynamicObject* instance, PropertyId propertyId, BOOL value)
    {
        return false;
    }

    BOOL NullTypeHandlerBase::SetAccessors(DynamicObject* instance, PropertyId propertyId, Var getter, Var setter, PropertyOperationFlags flags)
    {
        return ConvertToDictionaryType(instance)->SetAccessors(instance, propertyId, getter, setter, flags);
    }

    BOOL NullTypeHandlerBase::PreventExtensions(DynamicObject* instance)
    {
        return ConvertToDictionaryType(instance)->PreventExtensions(instance);
    }

    BOOL NullTypeHandlerBase::Seal(DynamicObject* instance)
    {
        return ConvertToDictionaryType(instance)->Seal(instance);
    }

    BOOL NullTypeHandlerBase::FreezeImpl(DynamicObject* instance, bool isConvertedType)
    {
        return ConvertToDictionaryType(instance)->Freeze(instance, true);
    }

    template <typename T>
    T* NullTypeHandlerBase::ConvertToTypeHandler(DynamicObject* instance)
    {
        ScriptContext* scriptContext = instance->GetScriptContext();
        Recycler* recycler = scriptContext->GetRecycler();

        T * newTypeHandler = RecyclerNew(recycler, T, recycler);
        Assert((newTypeHandler->GetFlags() & IsPrototypeFlag) == 0);
        // EnsureSlots before updating the type handler and instance, as EnsureSlots allocates and may throw.
        instance->EnsureSlots(0, newTypeHandler->GetSlotCapacity(), scriptContext, newTypeHandler);
        Assert(((this->GetFlags() & IsPrototypeFlag) != 0) == this->isPrototype);
        newTypeHandler->SetFlags(IsPrototypeFlag, this->GetFlags());
        newTypeHandler->SetPropertyTypes(PropertyTypesWritableDataOnly | PropertyTypesWritableDataOnlyDetection | PropertyTypesInlineSlotCapacityLocked, this->GetPropertyTypes());
        if (instance->HasReadOnlyPropertiesInvisibleToTypeHandler())
        {
            newTypeHandler->ClearHasOnlyWritableDataProperties();
        }
        newTypeHandler->SetInstanceTypeHandler(instance);

        return newTypeHandler;
    }

    SimpleTypeHandler<1>* NullTypeHandlerBase::ConvertToSimpleType(DynamicObject* instance)
    {
        SimpleTypeHandler<1>* newTypeHandler = ConvertToTypeHandler<SimpleTypeHandler<1>>(instance);

#ifdef PROFILE_TYPES
        instance->GetScriptContext()->convertNullToSimpleCount++;
#endif
        return newTypeHandler;
    }

    SimpleDictionaryTypeHandler * NullTypeHandlerBase::ConvertToSimpleDictionaryType(DynamicObject * instance)
    {
        SimpleDictionaryTypeHandler* newTypeHandler = ConvertToTypeHandler<SimpleDictionaryTypeHandler>(instance);

#ifdef PROFILE_TYPES
        instance->GetScriptContext()->convertNullToSimpleDictionaryCount++;
#endif
        return newTypeHandler;
    }

    DictionaryTypeHandler * NullTypeHandlerBase::ConvertToDictionaryType(DynamicObject * instance)
    {
        DictionaryTypeHandler* newTypeHandler = ConvertToTypeHandler<DictionaryTypeHandler>(instance);

#ifdef PROFILE_TYPES
        instance->GetScriptContext()->convertNullToDictionaryCount++;
#endif
        return newTypeHandler;
    }

    ES5ArrayTypeHandler* NullTypeHandlerBase::ConvertToES5ArrayType(DynamicObject * instance)
    {
        ES5ArrayTypeHandler* newTypeHandler = ConvertToTypeHandler<ES5ArrayTypeHandler>(instance);

#ifdef PROFILE_TYPES
        instance->GetScriptContext()->convertNullToDictionaryCount++;
#endif
        return newTypeHandler;
    }

    BOOL NullTypeHandlerBase::SetPropertyWithAttributes(DynamicObject* instance, PropertyId propertyId, Var value, PropertyAttributes attributes, PropertyValueInfo* info, PropertyOperationFlags flags, SideEffects possibleSideEffects)
    {
        // Always check numeric propertyId. May create objectArray.
        uint32 indexVal;
        if (instance->GetScriptContext()->IsNumericPropertyId(propertyId, &indexVal))
        {
            return NullTypeHandlerBase::SetItemWithAttributes(instance, indexVal, value, attributes);
        }

        return this->AddProperty(instance, propertyId, value, attributes, info, flags, possibleSideEffects);
    }

    BOOL NullTypeHandlerBase::SetAttributes(DynamicObject* instance, PropertyId propertyId, PropertyAttributes attributes)
    {
        return false;
    }

    BOOL NullTypeHandlerBase::GetAttributesWithPropertyIndex(DynamicObject * instance, PropertyId propertyId, BigPropertyIndex index, PropertyAttributes * attributes)
    {
        return false;
    }

    DynamicTypeHandler* NullTypeHandlerBase::ConvertToTypeWithItemAttributes(DynamicObject* instance)
    {
        return JavascriptArray::Is(instance) ?
            ConvertToES5ArrayType(instance) : ConvertToDictionaryType(instance);
    }

    void NullTypeHandlerBase::SetIsPrototype(DynamicObject* instance)
    {
        if (!this->isPrototype)
        {
            // We don't force a type transition even when ChangeTypeOnProto() == true, because objects with NullTypeHandlers don't
            // have any properties, so there is nothing to invalidate.  Types with NullTypeHandlers also aren't cached in typeWithoutProperty
            // caches, so there will be no fast property add path that could skip prototype cache invalidation.
            NullTypeHandler<true>* protoTypeHandler = NullTypeHandler<true>::GetDefaultInstance();
            AssertMsg(protoTypeHandler->GetFlags() == (GetFlags() | IsPrototypeFlag), "Why did we change the flags of a NullTypeHandler?");
            Assert(this->GetIsInlineSlotCapacityLocked() == protoTypeHandler->GetIsInlineSlotCapacityLocked());
            protoTypeHandler->SetPropertyTypes(PropertyTypesWritableDataOnly | PropertyTypesWritableDataOnlyDetection, GetPropertyTypes());
            SetInstanceTypeHandler(instance, protoTypeHandler);
        }
    }

    template<bool IsPrototypeTemplate>
    NullTypeHandler<IsPrototypeTemplate> NullTypeHandler<IsPrototypeTemplate>::defaultInstance;

    template<bool IsPrototypeTemplate>
    NullTypeHandler<IsPrototypeTemplate> * NullTypeHandler<IsPrototypeTemplate>::GetDefaultInstance() { return &defaultInstance; }

    template class NullTypeHandler<false>;
    template class NullTypeHandler<true>;
}
<commit_msg>[MERGE #1277 @MikeHolman] Fix crash when tracing EquivObjTypeSpec<commit_after>//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "RuntimeTypePch.h"

#include "Types/NullTypeHandler.h"
#include "Types/SimpleTypeHandler.h"

namespace Js
{
    int NullTypeHandlerBase::GetPropertyCount()
    {
        return 0;
    }

    PropertyId NullTypeHandlerBase::GetPropertyId(ScriptContext* scriptContext, PropertyIndex index)
    {
        return Constants::NoProperty;
    }

    PropertyId NullTypeHandlerBase::GetPropertyId(ScriptContext* scriptContext, BigPropertyIndex index)
    {
        return Constants::NoProperty;
    }

    BOOL NullTypeHandlerBase::FindNextProperty(ScriptContext* scriptContext, PropertyIndex& index, JavascriptString** propertyString, PropertyId* propertyId,
        PropertyAttributes* attributes, Type* type, DynamicType *typeToEnumerate, bool requireEnumerable, bool enumSymbols)
    {
        Assert(propertyString);
        Assert(propertyId);
        Assert(type);
        return FALSE;
    }

    PropertyIndex NullTypeHandlerBase::GetPropertyIndex(PropertyRecord const* propertyRecord)
    {
        return Constants::NoSlot;
    }

    bool NullTypeHandlerBase::GetPropertyEquivalenceInfo(PropertyRecord const* propertyRecord, PropertyEquivalenceInfo& info)
    {
        info.slotIndex = Constants::NoSlot;
        info.isAuxSlot = false;
        info.isWritable = false;
        return false;
    }

    bool NullTypeHandlerBase::IsObjTypeSpecEquivalent(const Type* type, const TypeEquivalenceRecord& record, uint& failedPropertyIndex)
    {
        uint propertyCount = record.propertyCount;
        EquivalentPropertyEntry* properties = record.properties;
        for (uint pi = 0; pi < propertyCount; pi++)
        {
            const EquivalentPropertyEntry* refInfo = &properties[pi];
            if (!this->NullTypeHandlerBase::IsObjTypeSpecEquivalent(type, refInfo))
            {
                failedPropertyIndex = pi;
                return false;
            }
        }
        return true;
    }

    bool NullTypeHandlerBase::IsObjTypeSpecEquivalent(const Type* type, const EquivalentPropertyEntry *entry)
    {
        return entry->slotIndex == Constants::NoSlot && !entry->mustBeWritable;
    }

    BOOL NullTypeHandlerBase::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl)
    {
        // Check numeric propertyId only if objectArray is available
        uint32 indexVal;
        ScriptContext* scriptContext = instance->GetScriptContext();

        if (noRedecl != nullptr)
        {
            *noRedecl = false;
        }

        if (instance->HasObjectArray() && scriptContext->IsNumericPropertyId(propertyId, &indexVal))
        {
            return DynamicTypeHandler::HasItem(instance, indexVal);
        }

        return false;
    }

    BOOL NullTypeHandlerBase::HasProperty(DynamicObject* instance, JavascriptString* propertyNameString)
    {
        PropertyRecord const* propertyRecord;
        instance->GetScriptContext()->GetOrAddPropertyRecord(propertyNameString->GetString(), propertyNameString->GetLength(), &propertyRecord);
        return NullTypeHandlerBase::HasProperty(instance, propertyRecord->GetPropertyId());
    }

    BOOL NullTypeHandlerBase::GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
    {
        // Check numeric propertyId only if objectArray is available
        uint32 indexVal;
        ScriptContext* scriptContext = instance->GetScriptContext();
        if (instance->HasObjectArray() && scriptContext->IsNumericPropertyId(propertyId, &indexVal))
        {
            return DynamicTypeHandler::GetItem(instance, originalInstance, indexVal, value, requestContext);
        }

        *value = requestContext->GetMissingPropertyResult();
        return false;
    }

    BOOL NullTypeHandlerBase::GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
    {
        PropertyRecord const* propertyRecord;
        instance->GetScriptContext()->GetOrAddPropertyRecord(propertyNameString->GetString(), propertyNameString->GetLength(), &propertyRecord);
        return NullTypeHandlerBase::GetProperty(instance, originalInstance, propertyRecord->GetPropertyId(), value, info, requestContext);
    }

    BOOL NullTypeHandlerBase::SetProperty(DynamicObject* instance, PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
    {
        return ConvertToSimpleType(instance)->SetProperty(instance, propertyId, value, flags, info);
    }

    BOOL NullTypeHandlerBase::SetProperty(DynamicObject* instance, JavascriptString* propertyNameString, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
    {
        return ConvertToSimpleType(instance)->SetProperty(instance, propertyNameString, value, flags, info);
    }

    BOOL NullTypeHandlerBase::AddProperty(DynamicObject* instance, PropertyId propertyId, Var value, PropertyAttributes attributes, PropertyValueInfo* info, PropertyOperationFlags flags, SideEffects possibleSideEffects)
    {
        if (this->isPrototype && (ChangeTypeOnProto() || (GetIsShared() && IsolatePrototypes())))
        {
            ScriptContext* scriptContext = instance->GetScriptContext();
            return ConvertToSimpleDictionaryType(instance)->AddProperty(instance, scriptContext->GetPropertyName(propertyId), value, attributes, info, flags, possibleSideEffects);
        }
        else
        {
            return ConvertToSimpleType(instance)->AddProperty(instance, propertyId, value, attributes, info, flags, possibleSideEffects);
        }
    }

    BOOL NullTypeHandlerBase::DeleteProperty(DynamicObject* instance, PropertyId propertyId, PropertyOperationFlags flags)
    {
        // Check numeric propertyId only if objectArray is available
        ScriptContext* scriptContext = instance->GetScriptContext();
        uint32 indexVal;
        if (instance->HasObjectArray() && scriptContext->IsNumericPropertyId(propertyId, &indexVal))
        {
            return DynamicTypeHandler::DeleteItem(instance, indexVal, flags);
        }

        return true;
    }

    BOOL NullTypeHandlerBase::IsEnumerable(DynamicObject* instance, PropertyId propertyId)
    {
        return true;
    }

    BOOL NullTypeHandlerBase::IsWritable(DynamicObject* instance, PropertyId propertyId)
    {
        return true;
    }

    BOOL NullTypeHandlerBase::IsConfigurable(DynamicObject* instance, PropertyId propertyId)
    {
        return true;
    }

    BOOL NullTypeHandlerBase::SetEnumerable(DynamicObject* instance, PropertyId propertyId, BOOL value)
    {
        return false;
    }

    BOOL NullTypeHandlerBase::SetWritable(DynamicObject* instance, PropertyId propertyId, BOOL value)
    {
        return false;
    }

    BOOL NullTypeHandlerBase::SetConfigurable(DynamicObject* instance, PropertyId propertyId, BOOL value)
    {
        return false;
    }

    BOOL NullTypeHandlerBase::SetAccessors(DynamicObject* instance, PropertyId propertyId, Var getter, Var setter, PropertyOperationFlags flags)
    {
        return ConvertToDictionaryType(instance)->SetAccessors(instance, propertyId, getter, setter, flags);
    }

    BOOL NullTypeHandlerBase::PreventExtensions(DynamicObject* instance)
    {
        return ConvertToDictionaryType(instance)->PreventExtensions(instance);
    }

    BOOL NullTypeHandlerBase::Seal(DynamicObject* instance)
    {
        return ConvertToDictionaryType(instance)->Seal(instance);
    }

    BOOL NullTypeHandlerBase::FreezeImpl(DynamicObject* instance, bool isConvertedType)
    {
        return ConvertToDictionaryType(instance)->Freeze(instance, true);
    }

    template <typename T>
    T* NullTypeHandlerBase::ConvertToTypeHandler(DynamicObject* instance)
    {
        ScriptContext* scriptContext = instance->GetScriptContext();
        Recycler* recycler = scriptContext->GetRecycler();

        T * newTypeHandler = RecyclerNew(recycler, T, recycler);
        Assert((newTypeHandler->GetFlags() & IsPrototypeFlag) == 0);
        // EnsureSlots before updating the type handler and instance, as EnsureSlots allocates and may throw.
        instance->EnsureSlots(0, newTypeHandler->GetSlotCapacity(), scriptContext, newTypeHandler);
        Assert(((this->GetFlags() & IsPrototypeFlag) != 0) == this->isPrototype);
        newTypeHandler->SetFlags(IsPrototypeFlag, this->GetFlags());
        newTypeHandler->SetPropertyTypes(PropertyTypesWritableDataOnly | PropertyTypesWritableDataOnlyDetection | PropertyTypesInlineSlotCapacityLocked, this->GetPropertyTypes());
        if (instance->HasReadOnlyPropertiesInvisibleToTypeHandler())
        {
            newTypeHandler->ClearHasOnlyWritableDataProperties();
        }
        newTypeHandler->SetInstanceTypeHandler(instance);

        return newTypeHandler;
    }

    SimpleTypeHandler<1>* NullTypeHandlerBase::ConvertToSimpleType(DynamicObject* instance)
    {
        SimpleTypeHandler<1>* newTypeHandler = ConvertToTypeHandler<SimpleTypeHandler<1>>(instance);

#ifdef PROFILE_TYPES
        instance->GetScriptContext()->convertNullToSimpleCount++;
#endif
        return newTypeHandler;
    }

    SimpleDictionaryTypeHandler * NullTypeHandlerBase::ConvertToSimpleDictionaryType(DynamicObject * instance)
    {
        SimpleDictionaryTypeHandler* newTypeHandler = ConvertToTypeHandler<SimpleDictionaryTypeHandler>(instance);

#ifdef PROFILE_TYPES
        instance->GetScriptContext()->convertNullToSimpleDictionaryCount++;
#endif
        return newTypeHandler;
    }

    DictionaryTypeHandler * NullTypeHandlerBase::ConvertToDictionaryType(DynamicObject * instance)
    {
        DictionaryTypeHandler* newTypeHandler = ConvertToTypeHandler<DictionaryTypeHandler>(instance);

#ifdef PROFILE_TYPES
        instance->GetScriptContext()->convertNullToDictionaryCount++;
#endif
        return newTypeHandler;
    }

    ES5ArrayTypeHandler* NullTypeHandlerBase::ConvertToES5ArrayType(DynamicObject * instance)
    {
        ES5ArrayTypeHandler* newTypeHandler = ConvertToTypeHandler<ES5ArrayTypeHandler>(instance);

#ifdef PROFILE_TYPES
        instance->GetScriptContext()->convertNullToDictionaryCount++;
#endif
        return newTypeHandler;
    }

    BOOL NullTypeHandlerBase::SetPropertyWithAttributes(DynamicObject* instance, PropertyId propertyId, Var value, PropertyAttributes attributes, PropertyValueInfo* info, PropertyOperationFlags flags, SideEffects possibleSideEffects)
    {
        // Always check numeric propertyId. May create objectArray.
        uint32 indexVal;
        if (instance->GetScriptContext()->IsNumericPropertyId(propertyId, &indexVal))
        {
            return NullTypeHandlerBase::SetItemWithAttributes(instance, indexVal, value, attributes);
        }

        return this->AddProperty(instance, propertyId, value, attributes, info, flags, possibleSideEffects);
    }

    BOOL NullTypeHandlerBase::SetAttributes(DynamicObject* instance, PropertyId propertyId, PropertyAttributes attributes)
    {
        return false;
    }

    BOOL NullTypeHandlerBase::GetAttributesWithPropertyIndex(DynamicObject * instance, PropertyId propertyId, BigPropertyIndex index, PropertyAttributes * attributes)
    {
        return false;
    }

    DynamicTypeHandler* NullTypeHandlerBase::ConvertToTypeWithItemAttributes(DynamicObject* instance)
    {
        return JavascriptArray::Is(instance) ?
            ConvertToES5ArrayType(instance) : ConvertToDictionaryType(instance);
    }

    void NullTypeHandlerBase::SetIsPrototype(DynamicObject* instance)
    {
        if (!this->isPrototype)
        {
            // We don't force a type transition even when ChangeTypeOnProto() == true, because objects with NullTypeHandlers don't
            // have any properties, so there is nothing to invalidate.  Types with NullTypeHandlers also aren't cached in typeWithoutProperty
            // caches, so there will be no fast property add path that could skip prototype cache invalidation.
            NullTypeHandler<true>* protoTypeHandler = NullTypeHandler<true>::GetDefaultInstance();
            AssertMsg(protoTypeHandler->GetFlags() == (GetFlags() | IsPrototypeFlag), "Why did we change the flags of a NullTypeHandler?");
            Assert(this->GetIsInlineSlotCapacityLocked() == protoTypeHandler->GetIsInlineSlotCapacityLocked());
            protoTypeHandler->SetPropertyTypes(PropertyTypesWritableDataOnly | PropertyTypesWritableDataOnlyDetection, GetPropertyTypes());
            SetInstanceTypeHandler(instance, protoTypeHandler);
        }
    }

    template<bool IsPrototypeTemplate>
    NullTypeHandler<IsPrototypeTemplate> NullTypeHandler<IsPrototypeTemplate>::defaultInstance;

    template<bool IsPrototypeTemplate>
    NullTypeHandler<IsPrototypeTemplate> * NullTypeHandler<IsPrototypeTemplate>::GetDefaultInstance() { return &defaultInstance; }

    template class NullTypeHandler<false>;
    template class NullTypeHandler<true>;
}
<|endoftext|>


<commit_before>#ifndef NANO_SIGNAL_SLOT_HPP
#define NANO_SIGNAL_SLOT_HPP

#include "nano_function.hpp"
#include "nano_observer.hpp"

namespace Nano
{

template <typename T_rv> class Signal;
template <typename T_rv, typename... Args>
class Signal<T_rv(Args...)> : private Observer
{
    template <typename T>
    void insert_sfinae(DelegateKey const& key, typename T::Observer* instance)
    {
        Observer::insert(key, instance);
        instance->insert(key, this);
    }
    template <typename T>
    void remove_sfinae(DelegateKey const& key, typename T::Observer* instance)
    {
        Observer::remove(key);
        instance->remove(key);
    }
    template <typename T>
    void insert_sfinae(DelegateKey const& key, ...)
    {
        Observer::insert(key);
    }
    template <typename T>
    void remove_sfinae(DelegateKey const& key, ...)
    {
        Observer::remove(key);
    }

    public:

    using Function = Function<T_rv(Args...)>;

    //-------------------------------------------------------------------CONNECT

    template <T_rv (*fun_ptr)(Args...)>
    void connect()
    {
        Observer::insert(Function::template bind<fun_ptr>());
    }

    template <typename T, T_rv (T::*mem_ptr)(Args...)>
    void connect(T* instance)
    {
        auto delegate  = Function::template bind<T, mem_ptr>(instance);
        insert_sfinae<T>(delegate, instance);
    }
    template <typename T, T_rv (T::*mem_ptr)(Args...) const>
    void connect(T* instance)
    {
        auto delegate  = Function::template bind<T, mem_ptr>(instance);
        insert_sfinae<T>(delegate, instance);
    }

    template <typename T, T_rv (T::*mem_ptr)(Args...)>
    void connect(T& instance)
    {
        connect<T, mem_ptr>(std::addressof(instance));
    }
    template <typename T, T_rv (T::*mem_ptr)(Args...) const>
    void connect(T& instance)
    {
        connect<T, mem_ptr>(std::addressof(instance));
    }

    //----------------------------------------------------------------DISCONNECT

    template <T_rv (*fun_ptr)(Args...)>
    void disconnect()
    {
        Observer::remove(Function::template bind<fun_ptr>());
    }

    template <typename T, T_rv (T::*mem_ptr)(Args...)>
    void disconnect(T* instance)
    {
        auto delegate  = Function::template bind<T, mem_ptr>(instance);
        remove_sfinae<T>(delegate, instance);
    }
    template <typename T, T_rv (T::*mem_ptr)(Args...) const>
    void disconnect(T* instance)
    {
        auto delegate  = Function::template bind<T, mem_ptr>(instance);
        remove_sfinae<T>(delegate, instance);
    }

    template <typename T, T_rv (T::*mem_ptr)(Args...)>
    void disconnect(T& instance)
    {
        disconnect<T, mem_ptr>(std::addressof(instance));
    }
    template <typename T, T_rv (T::*mem_ptr)(Args...) const>
    void disconnect(T& instance)
    {
        disconnect<T, mem_ptr>(std::addressof(instance));
    }

    //----------------------------------------------------------------------EMIT

    void operator() (Args... args)
    {
        for (auto const& slot : tracked_connections)
        {
            Function(std::get<0>(slot))(std::forward<Args>(args)...);
        }
    }
    template <typename Accumulator>
    void operator() (Args... args, Accumulator sink)
    {
        for (auto const& slot : tracked_connections)
        {
            sink(Function(std::get<0>(slot))(std::forward<Args>(args)...));
        }
    }
};

} // namespace Nano ------------------------------------------------------------

#endif // NANO_SIGNAL_SLOT_HPP
<commit_msg>Fixed possible shadowing in using declaration.<commit_after>#ifndef NANO_SIGNAL_SLOT_HPP
#define NANO_SIGNAL_SLOT_HPP

#include "nano_function.hpp"
#include "nano_observer.hpp"

namespace Nano
{

template <typename T_rv> class Signal;
template <typename T_rv, typename... Args>
class Signal<T_rv(Args...)> : private Observer
{
    template <typename T>
    void insert_sfinae(DelegateKey const& key, typename T::Observer* instance)
    {
        Observer::insert(key, instance);
        instance->insert(key, this);
    }
    template <typename T>
    void remove_sfinae(DelegateKey const& key, typename T::Observer* instance)
    {
        Observer::remove(key);
        instance->remove(key);
    }
    template <typename T>
    void insert_sfinae(DelegateKey const& key, ...)
    {
        Observer::insert(key);
    }
    template <typename T>
    void remove_sfinae(DelegateKey const& key, ...)
    {
        Observer::remove(key);
    }

    public:

    using Delegate = Function<T_rv(Args...)>;

    //-------------------------------------------------------------------CONNECT

    template <T_rv (*fun_ptr)(Args...)>
    void connect()
    {
        Observer::insert(Delegate::template bind<fun_ptr>());
    }

    template <typename T, T_rv (T::*mem_ptr)(Args...)>
    void connect(T* instance)
    {
        auto delegate  = Delegate::template bind<T, mem_ptr>(instance);
        insert_sfinae<T>(delegate, instance);
    }
    template <typename T, T_rv (T::*mem_ptr)(Args...) const>
    void connect(T* instance)
    {
        auto delegate  = Delegate::template bind<T, mem_ptr>(instance);
        insert_sfinae<T>(delegate, instance);
    }

    template <typename T, T_rv (T::*mem_ptr)(Args...)>
    void connect(T& instance)
    {
        connect<T, mem_ptr>(std::addressof(instance));
    }
    template <typename T, T_rv (T::*mem_ptr)(Args...) const>
    void connect(T& instance)
    {
        connect<T, mem_ptr>(std::addressof(instance));
    }

    //----------------------------------------------------------------DISCONNECT

    template <T_rv (*fun_ptr)(Args...)>
    void disconnect()
    {
        Observer::remove(Delegate::template bind<fun_ptr>());
    }

    template <typename T, T_rv (T::*mem_ptr)(Args...)>
    void disconnect(T* instance)
    {
        auto delegate  = Delegate::template bind<T, mem_ptr>(instance);
        remove_sfinae<T>(delegate, instance);
    }
    template <typename T, T_rv (T::*mem_ptr)(Args...) const>
    void disconnect(T* instance)
    {
        auto delegate  = Delegate::template bind<T, mem_ptr>(instance);
        remove_sfinae<T>(delegate, instance);
    }

    template <typename T, T_rv (T::*mem_ptr)(Args...)>
    void disconnect(T& instance)
    {
        disconnect<T, mem_ptr>(std::addressof(instance));
    }
    template <typename T, T_rv (T::*mem_ptr)(Args...) const>
    void disconnect(T& instance)
    {
        disconnect<T, mem_ptr>(std::addressof(instance));
    }

    //----------------------------------------------------------------------EMIT

    void operator() (Args... args)
    {
        for (auto const& slot : tracked_connections)
        {
            Delegate(std::get<0>(slot))(std::forward<Args>(args)...);
        }
    }
    template <typename Accumulator>
    void operator() (Args... args, Accumulator sink)
    {
        for (auto const& slot : tracked_connections)
        {
            sink(Delegate(std::get<0>(slot))(std::forward<Args>(args)...));
        }
    }
};

} // namespace Nano ------------------------------------------------------------

#endif // NANO_SIGNAL_SLOT_HPP
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#include <openssl_helpers.h>

#include <tpm20.h>
#include <tpm2_lib.h>
#include <gflags/gflags.h>

//
// Copyright 2015 Google Corporation, All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//     http://www.apache.org/licenses/LICENSE-2.0
// or in the the file LICENSE-2.0.txt in the top level sourcedirectory
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License
//
// Portions of this code were derived TPM2.0-TSS published
// by Intel under the license set forth in intel_license.txt
// and downloaded on or about August 6, 2015.
// Portions of this code were derived tboot published
// by Intel under the license set forth in intel_license.txt
// and downloaded on or about August 6, 2015.
// Portions of this code were derived from the crypto utility
// published by John Manferdelli under the Apache 2.0 license.
// See github.com/jlmucb/crypto.
// File: ClientGetProgramKeyCert.cc

//  This program decrypts the program  key certificate using ActivateCredential
//  and stores the resulting decrypted cert.

// Calling sequence: ClientGetProgramKeyCert.exe
//    --slot_primary=slot-number
//    --slot_seal= slot-number
//    --program_key_response_file=input-file-name
//    --program_key_cert_file=output-file-name

using std::string;

#define CALLING_SEQUENCE "ClientGetProgramKeyCert.exe " \
"--slot_primary=slot-number " \
"--slot_seal= slot-number " \
"--slot_quote= slot-number " \
"--program_key_response_file=input-file-name " \
"--program_key_cert_file=output-file-name\n"

void PrintOptions() {
  printf("Calling sequence: %s", CALLING_SEQUENCE);
}

DEFINE_string(program_key_response_file, "", "input-file-name");
DEFINE_int32(slot_primary, 1, "slot-number");
DEFINE_int32(slot_seal, 2, "slot-number");
DEFINE_int32(slot_quote, 3, "slot-number");
DEFINE_string(program_key_type, "RSA", "alg name");
DEFINE_string(program_key_cert_file, "", "output-file-name");

#ifndef GFLAGS_NS
#define GFLAGS_NS gflags
#endif

#define MAX_SIZE_PARAMS 4096
#define DEBUG

int main(int an, char** av) {
  LocalTpm tpm;
  int ret_val = 0;

  GFLAGS_NS::ParseCommandLineFlags(&an, &av, true);
  if (!tpm.OpenTpm("/dev/tpm0")) {
    printf("Can't open tpm\n");
    return 1;
  }

  OpenSSL_add_all_algorithms();

  TPM_HANDLE nv_handle = 0;

  string authString("01020304");
  string parentAuth("01020304");
  string emptyAuth;

  TPML_PCR_SELECTION pcrSelect;

  TPM_HANDLE ekHandle = 0;
  TPM_HANDLE root_handle = 0;
  TPM_HANDLE seal_handle = 0;
  TPM_HANDLE quote_handle = 0;

  TPM2B_DIGEST credential;
  TPM2B_ID_OBJECT credentialBlob;
  TPM2B_ENCRYPTED_SECRET secret;

  TPM2B_DIGEST recovered_credential;

  TPMA_OBJECT primary_flags;
  TPM2B_PUBLIC ek_pub_out;

  int current_size = 0;
  int context_data_size = 930;
  byte context_save_area[MAX_SIZE_PARAMS];

  int size_response = MAX_SIZE_PARAMS;
  byte response_buf[MAX_SIZE_PARAMS];
  program_cert_response_message response;
  int size_cert_out = MAX_SIZE_PARAMS;
  byte cert_out_buf[MAX_SIZE_PARAMS];

  string input;
  string output;

#ifdef DEBUG
  TPM2B_DIGEST test_cred;
#endif

  // Generate program key
  if (FLAGS_program_key_type != "RSA") {
    printf("Only RSA supported\n");
    ret_val = 1;
    goto done;
  }
  if (FLAGS_program_key_response_file == "") {
    printf("No key name\n");
    ret_val = 1;
    goto done;
  }
  if (FLAGS_program_key_cert_file == "") {
    printf("No key name\n");
    ret_val = 1;
    goto done;
  }

  // Create endorsement key
  *(uint32_t*)(&primary_flags) = 0;

  primary_flags.fixedTPM = 1;
  primary_flags.fixedParent = 1;
  primary_flags.sensitiveDataOrigin = 1;
  primary_flags.userWithAuth = 1;
  primary_flags.decrypt = 1;
  primary_flags.restricted = 1;

  InitSinglePcrSelection(-1, TPM_ALG_SHA1, pcrSelect);
  if (Tpm2_CreatePrimary(tpm, TPM_RH_ENDORSEMENT, emptyAuth, pcrSelect,
                         TPM_ALG_RSA, TPM_ALG_SHA256, primary_flags,
                         TPM_ALG_AES, 128, TPM_ALG_CFB, TPM_ALG_NULL,
                         2048, 0x010001, &ekHandle, &ek_pub_out)) {
    printf("CreatePrimary succeeded parent: %08x\n", ekHandle);
  } else {
    printf("CreatePrimary failed\n");
    ret_val = 1;
    goto done;
  }

  // restore context
  // TODO(jlm): should get pcr list from parameters
  InitSinglePcrSelection(7, TPM_ALG_SHA1, pcrSelect);

  // root handle
  memset(context_save_area, 0, MAX_SIZE_PARAMS);
  nv_handle = GetNvHandle(FLAGS_slot_primary);
  if (!Tpm2_ReadNv(tpm, nv_handle, authString, (uint16_t) context_data_size,
                   context_save_area)) {
    printf("Root ReadNv failed\n");
    ret_val = 1;
    goto done;
  }
#ifdef DEBUG1
  printf("\ncontext_save_area: ");
  PrintBytes(context_data_size - 6, context_save_area + 6);
  printf("\n\n");
#endif
  if (!Tpm2_LoadContext(tpm, context_data_size - 6, context_save_area + 6,
                        &root_handle)) {
    printf("Root LoadContext failed\n");
    ret_val = 1;
    goto done;
  }

  // quote handle
  memset(context_save_area, 0, MAX_SIZE_PARAMS);
  nv_handle = GetNvHandle(FLAGS_slot_quote);
  if (!Tpm2_ReadNv(tpm, nv_handle, authString, (uint16_t)context_data_size,
                   context_save_area)) {
    printf("Quote ReadNv failed\n");
    ret_val = 1;
    goto done;
  }
  if (!Tpm2_LoadContext(tpm, context_data_size - 6, context_save_area + 6,
                        &quote_handle)) {
    printf("Quote LoadContext failed\n");
    ret_val = 1;
    goto done;
  }
#ifdef DEBUG1
  printf("\ncontext_save_area: ");
  PrintBytes(context_data_size - 6, context_save_area + 6);
  printf("\n\n");
#endif

  memset((void*)&credential, 0, sizeof(TPM2B_DIGEST));
  memset((void*)&secret, 0, sizeof(TPM2B_ENCRYPTED_SECRET));
  memset((void*)&credentialBlob, 0, sizeof(TPM2B_ID_OBJECT));

  // Get response
  if (!ReadFileIntoBlock(FLAGS_program_key_response_file, &size_response,
                         response_buf)) {
    printf("Can't read response\n");
    ret_val = 1;
    goto done;
  }
  input.assign((const char*)response_buf, size_response);
  if (!response.ParseFromString(input)) {
    printf("Can't parse response\n");
    ret_val = 1;
    goto done;
  }

#ifdef DEBUG
  printf("\nintegrity (%d): ", (int)response.integrityhmac().size());
  PrintBytes(response.integrityhmac().size(),
             (byte*)response.integrityhmac().data());
  printf("\n");
  printf("encidentity(%d): ", (int)response.encidentity().size());
  PrintBytes(response.encidentity().size(),
             (byte*)response.encidentity().data());
  printf("\n");
  printf("\nsecret: %d\n", (int)response.secret().size());
  PrintBytes(response.secret().size(), (byte*)response.secret().data());
  printf("\n");
#endif

  // Fill credential blob and secret
  credentialBlob.size = (int)response.integrityhmac().size() + (int)response.encidentity().size();
  current_size = 0;
  memcpy(&credentialBlob.credential[current_size],
         (byte*) response.integrityhmac().data(),
         response.integrityhmac().size());
  current_size += response.integrityhmac().size();
  memcpy(&credentialBlob.credential[current_size],
         (byte*) response.encidentity().data(),
         response.encidentity().size());
  current_size += response.encidentity().size();

#ifdef DEBUG
  printf("Constructed credBlob (%d): ", credentialBlob.size);
  PrintBytes(credentialBlob.size, credentialBlob.credential);
  printf("\n");
#endif

  // secret
  secret.size = response.secret().size();
  memcpy(secret.secret, response.secret().data(), secret.size);

#ifdef DEBUG
{
  uint16_t quote_pub_blob_size = MAX_SIZE_PARAMS;
  byte quote_pub_blob[MAX_SIZE_PARAMS];
  TPM2B_PUBLIC quote_pub_out;
  TPM2B_NAME quote_pub_name;
  TPM2B_NAME quote_qualified_pub_name;

  if (Tpm2_ReadPublic(tpm, quote_handle, &quote_pub_blob_size, quote_pub_blob,
                      quote_pub_out, quote_pub_name,
                      quote_qualified_pub_name)) {
    printf("Quote ReadPublic succeeded\n");
  } else {
    printf("Quote ReadPublic failed\n");
    ret_val = 1;
    goto done;
  }

  TPM2B_DIGEST original_credential;
  TPM2B_ID_OBJECT credBlob;
  TPM2B_ENCRYPTED_SECRET active_secret;

  original_credential.size = 16;
  memset(original_credential.buffer, 0, original_credential.size);

  if (!Tpm2_MakeCredential(tpm, ekHandle, original_credential, quote_pub_name,
                          &credBlob, &active_secret)) {
    printf("MakeCredential failed\n");
  } else {
    printf("From MakeCred\n");
    printf("original cred: ");
    PrintBytes(original_credential.size, original_credential.buffer);
    printf("\n");
    printf("active_pub_name (%d): ", quote_pub_name.size);
    PrintBytes(quote_pub_name.size, quote_pub_name.name);
    printf("\n");
    printf("active_secret (%d): ", active_secret.size);
    PrintBytes(active_secret.size, active_secret.secret);
    printf("\n");
    printf("credBlob (%d): ", credBlob.size);
    PrintBytes(credBlob.size, credBlob.credential);
    printf("\n");
  }
  if (Tpm2_ActivateCredential(tpm, quote_handle, ekHandle, parentAuth, emptyAuth,
                              credBlob, active_secret, test_credential)) {
    printf("Paired ActivateCredential succeeded\n");
    printf("Original credential (%d): ", original_credential.size);
    PrintBytes(original_credential.size, original_credential.buffer);
    printf("\n");
    printf("Recovered credential (%d): ", test_cred.size);
    PrintBytes(test_cred.size, test_cred.buffer);
    printf("\n");
  } else {
    printf("Paired ActivateCredential failed\n");
  }
}
#endif

  if (!Tpm2_ActivateCredential(tpm, quote_handle, ekHandle, parentAuth, emptyAuth,
                               credentialBlob, secret, &recovered_credential)) {
    printf("ActivateCredential failed\n");
    ret_val = 1;
    goto done;
  }

#ifdef DEBUG
  printf("ActivateCredential succeeded\n");
  printf("Recovered credential (%d): ", recovered_credential.size);
  PrintBytes(recovered_credential.size, recovered_credential.buffer);
  printf("\n");
#endif

  // Decrypt cert, credential is key
  // response.request_id();
  // response.program_name();
  // response.enc_alg();
  // response.enc_mode();
  // response.encrypted_cert();

  if (response.encrypted_cert().size() > MAX_SIZE_PARAMS) {
    printf("encrypted cert too large\n");
    ret_val = 1;
    goto done;
  }
  size_cert_out = response.encrypted_cert().size();
  if (!AesCtrCrypt(128, recovered_credential.buffer,
                   response.encrypted_cert().size(),
                   (byte*)response.encrypted_cert().data(),
                   cert_out_buf)) {
    printf("Can't parse response\n");
    ret_val = 1;
    goto done;
  }
  size_cert_out = response.encrypted_cert().size();
#ifdef DEBUG
  printf("decrypted cert (%d): ", size_cert_out);
  PrintBytes(size_cert_out, cert_out_buf);
  printf("\n");
#endif

 // Write output cert
 if (!WriteFileFromBlock(FLAGS_program_key_cert_file,
                          size_cert_out,
                          cert_out_buf)) {
    printf("Can't write out program cert\n");
    ret_val = 1;
    goto done;
  }

done:
 if (root_handle != 0) {
    Tpm2_FlushContext(tpm, root_handle);
  }
  if (seal_handle != 0) {
    Tpm2_FlushContext(tpm, seal_handle);
  }
  if (quote_handle != 0) {
    Tpm2_FlushContext(tpm, quote_handle);
  }
  if (ekHandle != 0) {
    Tpm2_FlushContext(tpm, ekHandle);
  }
  tpm.CloseTpm();
  return ret_val;
}

<commit_msg>syntax<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#include <openssl_helpers.h>

#include <tpm20.h>
#include <tpm2_lib.h>
#include <gflags/gflags.h>

//
// Copyright 2015 Google Corporation, All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//     http://www.apache.org/licenses/LICENSE-2.0
// or in the the file LICENSE-2.0.txt in the top level sourcedirectory
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License
//
// Portions of this code were derived TPM2.0-TSS published
// by Intel under the license set forth in intel_license.txt
// and downloaded on or about August 6, 2015.
// Portions of this code were derived tboot published
// by Intel under the license set forth in intel_license.txt
// and downloaded on or about August 6, 2015.
// Portions of this code were derived from the crypto utility
// published by John Manferdelli under the Apache 2.0 license.
// See github.com/jlmucb/crypto.
// File: ClientGetProgramKeyCert.cc

//  This program decrypts the program  key certificate using ActivateCredential
//  and stores the resulting decrypted cert.

// Calling sequence: ClientGetProgramKeyCert.exe
//    --slot_primary=slot-number
//    --slot_seal= slot-number
//    --program_key_response_file=input-file-name
//    --program_key_cert_file=output-file-name

using std::string;

#define CALLING_SEQUENCE "ClientGetProgramKeyCert.exe " \
"--slot_primary=slot-number " \
"--slot_seal= slot-number " \
"--slot_quote= slot-number " \
"--program_key_response_file=input-file-name " \
"--program_key_cert_file=output-file-name\n"

void PrintOptions() {
  printf("Calling sequence: %s", CALLING_SEQUENCE);
}

DEFINE_string(program_key_response_file, "", "input-file-name");
DEFINE_int32(slot_primary, 1, "slot-number");
DEFINE_int32(slot_seal, 2, "slot-number");
DEFINE_int32(slot_quote, 3, "slot-number");
DEFINE_string(program_key_type, "RSA", "alg name");
DEFINE_string(program_key_cert_file, "", "output-file-name");

#ifndef GFLAGS_NS
#define GFLAGS_NS gflags
#endif

#define MAX_SIZE_PARAMS 4096
#define DEBUG

int main(int an, char** av) {
  LocalTpm tpm;
  int ret_val = 0;

  GFLAGS_NS::ParseCommandLineFlags(&an, &av, true);
  if (!tpm.OpenTpm("/dev/tpm0")) {
    printf("Can't open tpm\n");
    return 1;
  }

  OpenSSL_add_all_algorithms();

  TPM_HANDLE nv_handle = 0;

  string authString("01020304");
  string parentAuth("01020304");
  string emptyAuth;

  TPML_PCR_SELECTION pcrSelect;

  TPM_HANDLE ekHandle = 0;
  TPM_HANDLE root_handle = 0;
  TPM_HANDLE seal_handle = 0;
  TPM_HANDLE quote_handle = 0;

  TPM2B_DIGEST credential;
  TPM2B_ID_OBJECT credentialBlob;
  TPM2B_ENCRYPTED_SECRET secret;

  TPM2B_DIGEST recovered_credential;

  TPMA_OBJECT primary_flags;
  TPM2B_PUBLIC ek_pub_out;

  int current_size = 0;
  int context_data_size = 930;
  byte context_save_area[MAX_SIZE_PARAMS];

  int size_response = MAX_SIZE_PARAMS;
  byte response_buf[MAX_SIZE_PARAMS];
  program_cert_response_message response;
  int size_cert_out = MAX_SIZE_PARAMS;
  byte cert_out_buf[MAX_SIZE_PARAMS];

  string input;
  string output;

#ifdef DEBUG
  TPM2B_DIGEST test_cred;
#endif

  // Generate program key
  if (FLAGS_program_key_type != "RSA") {
    printf("Only RSA supported\n");
    ret_val = 1;
    goto done;
  }
  if (FLAGS_program_key_response_file == "") {
    printf("No key name\n");
    ret_val = 1;
    goto done;
  }
  if (FLAGS_program_key_cert_file == "") {
    printf("No key name\n");
    ret_val = 1;
    goto done;
  }

  // Create endorsement key
  *(uint32_t*)(&primary_flags) = 0;

  primary_flags.fixedTPM = 1;
  primary_flags.fixedParent = 1;
  primary_flags.sensitiveDataOrigin = 1;
  primary_flags.userWithAuth = 1;
  primary_flags.decrypt = 1;
  primary_flags.restricted = 1;

  InitSinglePcrSelection(-1, TPM_ALG_SHA1, pcrSelect);
  if (Tpm2_CreatePrimary(tpm, TPM_RH_ENDORSEMENT, emptyAuth, pcrSelect,
                         TPM_ALG_RSA, TPM_ALG_SHA256, primary_flags,
                         TPM_ALG_AES, 128, TPM_ALG_CFB, TPM_ALG_NULL,
                         2048, 0x010001, &ekHandle, &ek_pub_out)) {
    printf("CreatePrimary succeeded parent: %08x\n", ekHandle);
  } else {
    printf("CreatePrimary failed\n");
    ret_val = 1;
    goto done;
  }

  // restore context
  // TODO(jlm): should get pcr list from parameters
  InitSinglePcrSelection(7, TPM_ALG_SHA1, pcrSelect);

  // root handle
  memset(context_save_area, 0, MAX_SIZE_PARAMS);
  nv_handle = GetNvHandle(FLAGS_slot_primary);
  if (!Tpm2_ReadNv(tpm, nv_handle, authString, (uint16_t) context_data_size,
                   context_save_area)) {
    printf("Root ReadNv failed\n");
    ret_val = 1;
    goto done;
  }
#ifdef DEBUG1
  printf("\ncontext_save_area: ");
  PrintBytes(context_data_size - 6, context_save_area + 6);
  printf("\n\n");
#endif
  if (!Tpm2_LoadContext(tpm, context_data_size - 6, context_save_area + 6,
                        &root_handle)) {
    printf("Root LoadContext failed\n");
    ret_val = 1;
    goto done;
  }

  // quote handle
  memset(context_save_area, 0, MAX_SIZE_PARAMS);
  nv_handle = GetNvHandle(FLAGS_slot_quote);
  if (!Tpm2_ReadNv(tpm, nv_handle, authString, (uint16_t)context_data_size,
                   context_save_area)) {
    printf("Quote ReadNv failed\n");
    ret_val = 1;
    goto done;
  }
  if (!Tpm2_LoadContext(tpm, context_data_size - 6, context_save_area + 6,
                        &quote_handle)) {
    printf("Quote LoadContext failed\n");
    ret_val = 1;
    goto done;
  }
#ifdef DEBUG1
  printf("\ncontext_save_area: ");
  PrintBytes(context_data_size - 6, context_save_area + 6);
  printf("\n\n");
#endif

  memset((void*)&credential, 0, sizeof(TPM2B_DIGEST));
  memset((void*)&secret, 0, sizeof(TPM2B_ENCRYPTED_SECRET));
  memset((void*)&credentialBlob, 0, sizeof(TPM2B_ID_OBJECT));

  // Get response
  if (!ReadFileIntoBlock(FLAGS_program_key_response_file, &size_response,
                         response_buf)) {
    printf("Can't read response\n");
    ret_val = 1;
    goto done;
  }
  input.assign((const char*)response_buf, size_response);
  if (!response.ParseFromString(input)) {
    printf("Can't parse response\n");
    ret_val = 1;
    goto done;
  }

#ifdef DEBUG
  printf("\nintegrity (%d): ", (int)response.integrityhmac().size());
  PrintBytes(response.integrityhmac().size(),
             (byte*)response.integrityhmac().data());
  printf("\n");
  printf("encidentity(%d): ", (int)response.encidentity().size());
  PrintBytes(response.encidentity().size(),
             (byte*)response.encidentity().data());
  printf("\n");
  printf("\nsecret: %d\n", (int)response.secret().size());
  PrintBytes(response.secret().size(), (byte*)response.secret().data());
  printf("\n");
#endif

  // Fill credential blob and secret
  credentialBlob.size = (int)response.integrityhmac().size() + (int)response.encidentity().size();
  current_size = 0;
  memcpy(&credentialBlob.credential[current_size],
         (byte*) response.integrityhmac().data(),
         response.integrityhmac().size());
  current_size += response.integrityhmac().size();
  memcpy(&credentialBlob.credential[current_size],
         (byte*) response.encidentity().data(),
         response.encidentity().size());
  current_size += response.encidentity().size();

#ifdef DEBUG
  printf("Constructed credBlob (%d): ", credentialBlob.size);
  PrintBytes(credentialBlob.size, credentialBlob.credential);
  printf("\n");
#endif

  // secret
  secret.size = response.secret().size();
  memcpy(secret.secret, response.secret().data(), secret.size);

#ifdef DEBUG
{
  uint16_t quote_pub_blob_size = MAX_SIZE_PARAMS;
  byte quote_pub_blob[MAX_SIZE_PARAMS];
  TPM2B_PUBLIC quote_pub_out;
  TPM2B_NAME quote_pub_name;
  TPM2B_NAME quote_qualified_pub_name;

  if (Tpm2_ReadPublic(tpm, quote_handle, &quote_pub_blob_size, quote_pub_blob,
                      quote_pub_out, quote_pub_name,
                      quote_qualified_pub_name)) {
    printf("Quote ReadPublic succeeded\n");
  } else {
    printf("Quote ReadPublic failed\n");
    ret_val = 1;
    goto done;
  }

  TPM2B_DIGEST original_credential;
  TPM2B_ID_OBJECT credBlob;
  TPM2B_ENCRYPTED_SECRET active_secret;

  original_credential.size = 16;
  memset(original_credential.buffer, 0, original_credential.size);

  if (!Tpm2_MakeCredential(tpm, ekHandle, original_credential, quote_pub_name,
                          &credBlob, &active_secret)) {
    printf("MakeCredential failed\n");
  } else {
    printf("From MakeCred\n");
    printf("original cred: ");
    PrintBytes(original_credential.size, original_credential.buffer);
    printf("\n");
    printf("active_pub_name (%d): ", quote_pub_name.size);
    PrintBytes(quote_pub_name.size, quote_pub_name.name);
    printf("\n");
    printf("active_secret (%d): ", active_secret.size);
    PrintBytes(active_secret.size, active_secret.secret);
    printf("\n");
    printf("credBlob (%d): ", credBlob.size);
    PrintBytes(credBlob.size, credBlob.credential);
    printf("\n");
  }
  if (Tpm2_ActivateCredential(tpm, quote_handle, ekHandle, parentAuth, emptyAuth,
                              credBlob, active_secret, &test_cred)) {
    printf("Paired ActivateCredential succeeded\n");
    printf("Original credential (%d): ", original_credential.size);
    PrintBytes(original_credential.size, original_credential.buffer);
    printf("\n");
    printf("Recovered credential (%d): ", test_cred.size);
    PrintBytes(test_cred.size, test_cred.buffer);
    printf("\n");
  } else {
    printf("Paired ActivateCredential failed\n");
  }
}
#endif

  if (!Tpm2_ActivateCredential(tpm, quote_handle, ekHandle, parentAuth, emptyAuth,
                               credentialBlob, secret, &recovered_credential)) {
    printf("ActivateCredential failed\n");
    ret_val = 1;
    goto done;
  }

#ifdef DEBUG
  printf("ActivateCredential succeeded\n");
  printf("Recovered credential (%d): ", recovered_credential.size);
  PrintBytes(recovered_credential.size, recovered_credential.buffer);
  printf("\n");
#endif

  // Decrypt cert, credential is key
  // response.request_id();
  // response.program_name();
  // response.enc_alg();
  // response.enc_mode();
  // response.encrypted_cert();

  if (response.encrypted_cert().size() > MAX_SIZE_PARAMS) {
    printf("encrypted cert too large\n");
    ret_val = 1;
    goto done;
  }
  size_cert_out = response.encrypted_cert().size();
  if (!AesCtrCrypt(128, recovered_credential.buffer,
                   response.encrypted_cert().size(),
                   (byte*)response.encrypted_cert().data(),
                   cert_out_buf)) {
    printf("Can't parse response\n");
    ret_val = 1;
    goto done;
  }
  size_cert_out = response.encrypted_cert().size();
#ifdef DEBUG
  printf("decrypted cert (%d): ", size_cert_out);
  PrintBytes(size_cert_out, cert_out_buf);
  printf("\n");
#endif

 // Write output cert
 if (!WriteFileFromBlock(FLAGS_program_key_cert_file,
                          size_cert_out,
                          cert_out_buf)) {
    printf("Can't write out program cert\n");
    ret_val = 1;
    goto done;
  }

done:
 if (root_handle != 0) {
    Tpm2_FlushContext(tpm, root_handle);
  }
  if (seal_handle != 0) {
    Tpm2_FlushContext(tpm, seal_handle);
  }
  if (quote_handle != 0) {
    Tpm2_FlushContext(tpm, quote_handle);
  }
  if (ekHandle != 0) {
    Tpm2_FlushContext(tpm, ekHandle);
  }
  tpm.CloseTpm();
  return ret_val;
}

<|endoftext|>


<commit_before>#include "QGCViewModeSelection.h"
#include "ui_QGCViewModeSelection.h"
#include "QGC.h"
#include "MainWindow.h"

QGCViewModeSelection::QGCViewModeSelection(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QGCViewModeSelection),
    selected(false)
{
    ui->setupUi(this);

    connect(ui->viewModeGeneric, SIGNAL(clicked()), this, SLOT(selectGeneric()));
    connect(ui->viewModeAR, SIGNAL(clicked()), this, SLOT(selectWifi()));
    connect(ui->viewModePX4, SIGNAL(clicked()), this, SLOT(selectPX4()));
    connect(ui->notAgainCheckBox, SIGNAL(clicked(bool)), this, SIGNAL(settingsStorageRequested(bool)));
}

QGCViewModeSelection::~QGCViewModeSelection()
{
    delete ui;
}

enum MainWindow::CUSTOM_MODE QGCViewModeSelection::waitForInput() {
    while (!selected)
        QGC::SLEEP::msleep(200);

    return mode;
}

void QGCViewModeSelection::selectGeneric() {
    emit customViewModeSelected(MainWindow::CUSTOM_MODE_NONE);
    mode = MainWindow::CUSTOM_MODE_NONE;
    selected = true;
}

void QGCViewModeSelection::selectWifi() {
    emit customViewModeSelected(MainWindow::CUSTOM_MODE_WIFI);
    mode = MainWindow::CUSTOM_MODE_WIFI;
    selected = true;
}

void QGCViewModeSelection::selectPX4() {
    emit customViewModeSelected(MainWindow::CUSTOM_MODE_PX4);
    mode = MainWindow::CUSTOM_MODE_PX4;
    selected = true;
}<commit_msg>Added missing newline<commit_after>#include "QGCViewModeSelection.h"
#include "ui_QGCViewModeSelection.h"
#include "QGC.h"
#include "MainWindow.h"

QGCViewModeSelection::QGCViewModeSelection(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QGCViewModeSelection),
    selected(false)
{
    ui->setupUi(this);

    connect(ui->viewModeGeneric, SIGNAL(clicked()), this, SLOT(selectGeneric()));
    connect(ui->viewModeAR, SIGNAL(clicked()), this, SLOT(selectWifi()));
    connect(ui->viewModePX4, SIGNAL(clicked()), this, SLOT(selectPX4()));
    connect(ui->notAgainCheckBox, SIGNAL(clicked(bool)), this, SIGNAL(settingsStorageRequested(bool)));
}

QGCViewModeSelection::~QGCViewModeSelection()
{
    delete ui;
}

enum MainWindow::CUSTOM_MODE QGCViewModeSelection::waitForInput() {
    while (!selected)
        QGC::SLEEP::msleep(200);

    return mode;
}

void QGCViewModeSelection::selectGeneric() {
    emit customViewModeSelected(MainWindow::CUSTOM_MODE_NONE);
    mode = MainWindow::CUSTOM_MODE_NONE;
    selected = true;
}

void QGCViewModeSelection::selectWifi() {
    emit customViewModeSelected(MainWindow::CUSTOM_MODE_WIFI);
    mode = MainWindow::CUSTOM_MODE_WIFI;
    selected = true;
}

void QGCViewModeSelection::selectPX4() {
    emit customViewModeSelected(MainWindow::CUSTOM_MODE_PX4);
    mode = MainWindow::CUSTOM_MODE_PX4;
    selected = true;
}
<|endoftext|>


<commit_before>#include "ui/QBouton.h"
#include <QPainter>
#include <QPaintEvent>
#include <QtMath>

QBouton::QBouton(const QVariant &id, bool resizeInsteadOfCropping, bool smartSizeHint, int border, QColor color, QWidget *parent)
	: QPushButton(parent), m_id(id), m_resizeInsteadOfCropping(resizeInsteadOfCropping), m_smartSizeHint(smartSizeHint), m_penColor(color), m_border(border), m_center(true), m_progress(0), m_progressMax(0)
{ }

void QBouton::scale(const QPixmap &image, float scale)
{
	QSize size;
	if (fabs(scale - 1.0f) < 0.001f)
	{
		size = image.size() * scale;
		setIcon(image.scaled(size));
	}
	else
	{
		setIcon(image);
		size = image.size();
	}
	setIconSize(size);
	resize(size);
}

QVariant QBouton::id()
{ return m_id; }
void QBouton::setId(const QVariant &id)
{ m_id = id; }

void QBouton::setProgress(qint64 current, qint64 max)
{
	m_progress = current;
	m_progressMax = max;

	repaint();
}

void QBouton::paintEvent(QPaintEvent *event)
{
	// Used for normal buttons
	if (!m_resizeInsteadOfCropping && m_border == 0 && m_progressMax == 0)
	{
		QPushButton::paintEvent(event);
		return;
	}

	QPainter painter(this);
	QRect region = m_smartSizeHint ? contentsRect() : event->rect();
	QSize iconSize = getIconSize(region.width(), region.height());
	int p = m_border;
	int x = region.x();
	int y = region.y();
	int w = iconSize.width() + 2*p;
	int h = iconSize.height() + 2*p;

	// Ignore invalid images
	if (w == 0 || h == 0)
		return;

	// Center the image
	if (m_center)
	{
		x += (region.width() - w) / 2;
		y += (region.height() - h) / 2;
	}

	// Draw image
	QIcon::Mode mode = this->isChecked() ? QIcon::Selected : QIcon::Normal;
	if (w > h)
	{
		icon().paint(&painter, x+p, y+p, w-2*p, w-2*p, Qt::AlignLeft | Qt::AlignTop, mode);
		h = h-((h*2*p)/w)+2*p-1;
	}
	else
	{
		icon().paint(&painter, x+p, y+p, h-2*p, h-2*p, Qt::AlignLeft | Qt::AlignTop, mode);
		w = w-((w*2*p)/h)+2*p-1;
	}

	// Clip borders overflows
	painter.setClipRect(x, y, w, h);

	// Draw progress
	if (m_progressMax > 0 && m_progress > 0 && m_progress != m_progressMax)
	{
		int lineHeight = 6;
		int a = p + lineHeight/2;

		float ratio = static_cast<float>(m_progress) / m_progressMax;
		QPoint p1(qMax(x, 0) + a, qMax(y, 0) + a);
		QPoint p2(qFloor(p1.x() + (iconSize.width() - a) * ratio), p1.y());

		if (p2.x() > p1.x())
		{
			QPen pen(QColor(0, 200, 0));
			pen.setWidth(lineHeight);
			painter.setPen(pen);
			painter.drawLine(p1, p2);
		}
	}

	// Draw borders
	if (p > 0 && m_penColor.isValid())
	{
		QPen pen(m_penColor);
		pen.setWidth(p*2);
		painter.setPen(pen);
		painter.drawRect(qMax(x, 0), qMax(y, 0), qMin(w, size().width()), qMin(h, size().height()));
	}
}

QSize QBouton::getIconSize(int regionWidth, int regionHeight, bool wOnly) const
{
	int w = iconSize().width();
	int h = iconSize().height();

	if (wOnly && w <= regionWidth)
		return iconSize();

	// Calculate ratio to resize by keeping proportions
	if (m_resizeInsteadOfCropping)
	{
		float coef = wOnly
					 ? qMin(1.0f, static_cast<float>(regionWidth) / static_cast<float>(w))
					 : qMin(1.0f, qMin(static_cast<float>(regionWidth) / static_cast<float>(w), static_cast<float>(regionHeight) / static_cast<float>(h)));
		w *= coef;
		h *= coef;
	}

	return QSize(w, h);
}

void QBouton::resizeEvent(QResizeEvent *event)
{
	QPushButton::resizeEvent(event);

	if (m_smartSizeHint)
		updateGeometry();
}

QSize QBouton::sizeHint() const
{
	// Used for normal buttons
	if (!m_smartSizeHint || (!m_resizeInsteadOfCropping && m_border == 0))
		return QPushButton::sizeHint();

	QSize current = size();
	return getIconSize(current.width(), current.height(), true);
}

void QBouton::mousePressEvent(QMouseEvent *event)
{
	// Ignore clicks outside the thumbnail
	QSize imgSize = sizeHint();
	QSize size = this->size();
	int wMargin = (size.width() - imgSize.width()) / 2;
	int hMargin = (size.height() - imgSize.height()) / 2;
	QPoint pos = event->pos();
	if (pos.x() < wMargin
			|| pos.y() < hMargin
			|| pos.x() > imgSize.width() + wMargin
			|| pos.y() > imgSize.height() + hMargin)
		return;

	if (event->button() == Qt::LeftButton)
	{
		if (event->modifiers() & Qt::ControlModifier)
		{
			this->toggle();
			bool range = event->modifiers() & Qt::ShiftModifier;
			emit this->toggled(m_id, this->isChecked(), range);
			emit this->toggled(m_id.toString(), this->isChecked(), range);
			emit this->toggled(m_id.toInt(), this->isChecked(), range);
		}
		else
		{
			emit this->appui(m_id);
			emit this->appui(m_id.toString());
			emit this->appui(m_id.toInt());
		}
	}
	if (event->button() == Qt::RightButton)
	{
		emit this->rightClick(m_id);
		emit this->rightClick(m_id.toString());
		emit this->rightClick(m_id.toInt());
	}
	if (event->button() == Qt::MidButton)
	{
		emit this->middleClick(m_id);
		emit this->middleClick(m_id.toString());
		emit this->middleClick(m_id.toInt());
	}
	event->accept();
}
<commit_msg>Fix upscaling (fix #1176)<commit_after>#include "ui/QBouton.h"
#include <QPainter>
#include <QPaintEvent>
#include <QtMath>

QBouton::QBouton(const QVariant &id, bool resizeInsteadOfCropping, bool smartSizeHint, int border, QColor color, QWidget *parent)
	: QPushButton(parent), m_id(id), m_resizeInsteadOfCropping(resizeInsteadOfCropping), m_smartSizeHint(smartSizeHint), m_penColor(color), m_border(border), m_center(true), m_progress(0), m_progressMax(0)
{ }

void QBouton::scale(const QPixmap &image, float scale)
{
	QSize size;
	if (scale - 1.0f > 0.001f)
	{
		size = image.size() * scale;
		setIcon(image.scaled(size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
	}
	else
	{
		setIcon(image);
		size = image.size();
	}
	setIconSize(size);
	resize(size);
}

QVariant QBouton::id()
{ return m_id; }
void QBouton::setId(const QVariant &id)
{ m_id = id; }

void QBouton::setProgress(qint64 current, qint64 max)
{
	m_progress = current;
	m_progressMax = max;

	repaint();
}

void QBouton::paintEvent(QPaintEvent *event)
{
	// Used for normal buttons
	if (!m_resizeInsteadOfCropping && m_border == 0 && m_progressMax == 0)
	{
		QPushButton::paintEvent(event);
		return;
	}

	QPainter painter(this);
	QRect region = m_smartSizeHint ? contentsRect() : event->rect();
	QSize iconSize = getIconSize(region.width(), region.height());
	int p = m_border;
	int x = region.x();
	int y = region.y();
	int w = iconSize.width() + 2*p;
	int h = iconSize.height() + 2*p;

	// Ignore invalid images
	if (w == 0 || h == 0)
		return;

	// Center the image
	if (m_center)
	{
		x += (region.width() - w) / 2;
		y += (region.height() - h) / 2;
	}

	// Draw image
	QIcon::Mode mode = this->isChecked() ? QIcon::Selected : QIcon::Normal;
	if (w > h)
	{
		icon().paint(&painter, x+p, y+p, w-2*p, w-2*p, Qt::AlignLeft | Qt::AlignTop, mode);
		h = h-((h*2*p)/w)+2*p-1;
	}
	else
	{
		icon().paint(&painter, x+p, y+p, h-2*p, h-2*p, Qt::AlignLeft | Qt::AlignTop, mode);
		w = w-((w*2*p)/h)+2*p-1;
	}

	// Clip borders overflows
	painter.setClipRect(x, y, w, h);

	// Draw progress
	if (m_progressMax > 0 && m_progress > 0 && m_progress != m_progressMax)
	{
		int lineHeight = 6;
		int a = p + lineHeight/2;

		float ratio = static_cast<float>(m_progress) / m_progressMax;
		QPoint p1(qMax(x, 0) + a, qMax(y, 0) + a);
		QPoint p2(qFloor(p1.x() + (iconSize.width() - a) * ratio), p1.y());

		if (p2.x() > p1.x())
		{
			QPen pen(QColor(0, 200, 0));
			pen.setWidth(lineHeight);
			painter.setPen(pen);
			painter.drawLine(p1, p2);
		}
	}

	// Draw borders
	if (p > 0 && m_penColor.isValid())
	{
		QPen pen(m_penColor);
		pen.setWidth(p*2);
		painter.setPen(pen);
		painter.drawRect(qMax(x, 0), qMax(y, 0), qMin(w, size().width()), qMin(h, size().height()));
	}
}

QSize QBouton::getIconSize(int regionWidth, int regionHeight, bool wOnly) const
{
	int w = iconSize().width();
	int h = iconSize().height();

	if (wOnly && w <= regionWidth)
		return iconSize();

	// Calculate ratio to resize by keeping proportions
	if (m_resizeInsteadOfCropping)
	{
		float coef = wOnly
					 ? qMin(1.0f, static_cast<float>(regionWidth) / static_cast<float>(w))
					 : qMin(1.0f, qMin(static_cast<float>(regionWidth) / static_cast<float>(w), static_cast<float>(regionHeight) / static_cast<float>(h)));
		w *= coef;
		h *= coef;
	}

	return QSize(w, h);
}

void QBouton::resizeEvent(QResizeEvent *event)
{
	QPushButton::resizeEvent(event);

	if (m_smartSizeHint)
		updateGeometry();
}

QSize QBouton::sizeHint() const
{
	// Used for normal buttons
	if (!m_smartSizeHint || (!m_resizeInsteadOfCropping && m_border == 0))
		return QPushButton::sizeHint();

	QSize current = size();
	return getIconSize(current.width(), current.height(), true);
}

void QBouton::mousePressEvent(QMouseEvent *event)
{
	// Ignore clicks outside the thumbnail
	QSize imgSize = sizeHint();
	QSize size = this->size();
	int wMargin = (size.width() - imgSize.width()) / 2;
	int hMargin = (size.height() - imgSize.height()) / 2;
	QPoint pos = event->pos();
	if (pos.x() < wMargin
			|| pos.y() < hMargin
			|| pos.x() > imgSize.width() + wMargin
			|| pos.y() > imgSize.height() + hMargin)
		return;

	if (event->button() == Qt::LeftButton)
	{
		if (event->modifiers() & Qt::ControlModifier)
		{
			this->toggle();
			bool range = event->modifiers() & Qt::ShiftModifier;
			emit this->toggled(m_id, this->isChecked(), range);
			emit this->toggled(m_id.toString(), this->isChecked(), range);
			emit this->toggled(m_id.toInt(), this->isChecked(), range);
		}
		else
		{
			emit this->appui(m_id);
			emit this->appui(m_id.toString());
			emit this->appui(m_id.toInt());
		}
	}
	if (event->button() == Qt::RightButton)
	{
		emit this->rightClick(m_id);
		emit this->rightClick(m_id.toString());
		emit this->rightClick(m_id.toInt());
	}
	if (event->button() == Qt::MidButton)
	{
		emit this->middleClick(m_id);
		emit this->middleClick(m_id.toString());
		emit this->middleClick(m_id.toInt());
	}
	event->accept();
}
<|endoftext|>


<commit_before>/*
 * Android File Transfer for Linux: MTP client for android devices
 * Copyright (C) 2015  Vladimir Menshakov

 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#include <mtp/ptp/Device.h>
#include <mtp/ptp/Response.h>
#include <mtp/ptp/Container.h>
#include <mtp/ptp/Messages.h>
#include <mtp/usb/Context.h>
#include <mtp/ptp/OperationRequest.h>

namespace mtp
{

	msg::DeviceInfo Device::GetDeviceInfo()
	{
		OperationRequest req(OperationCode::GetDeviceInfo, 0);
		Container container(req);
		_packeter.Write(container.Data);
		ByteArray data, response;
		_packeter.Read(0, data, response);
		//HexDump("payload", data);

		InputStream stream(data, 8); //operation code + session id
		msg::DeviceInfo gdi;
		gdi.Read(stream);
		return gdi;
	}

	SessionPtr Device::OpenSession(u32 sessionId)
	{
		OperationRequest req(OperationCode::OpenSession, 0, sessionId);
		Container container(req);
		_packeter.Write(container.Data);
		ByteArray data, response;
		_packeter.Read(0, data, response);
		//HexDump("payload", data);

		return std::make_shared<Session>(_packeter.GetPipe(), sessionId);
	}

	void PipePacketer::Write(const ByteArray &data, int timeout)
	{
		//HexDump("send", data);
		_pipe->Write(data, timeout);
	}

	ByteArray PipePacketer::ReadMessage(int timeout)
	{
		ByteArray result;
		u32 size = ~0u;
		size_t offset = 0;
		size_t packet_offset;
		while(true)
		{
			ByteArray data = _pipe->Read(timeout);
			if (size == ~0u)
			{
				InputStream stream(data);
				stream >> size;
				//fprintf(stderr, "DATA SIZE = %u\n", size);
				if (size < 4)
					throw std::runtime_error("invalid size");
				packet_offset = 4;
				result.resize(size - 4);
			}
			else
				packet_offset = 0;
			//HexDump("recv", data);

			size_t src_n = std::min(data.size() - packet_offset, result.size() - offset);
			std::copy(data.begin() + packet_offset, data.begin() + packet_offset + src_n, result.begin() + offset);
			offset += data.size();
			if (offset >= result.size())
				break;
		}
		return result;

	}

	void PipePacketer::PollEvent()
	{
		ByteArray interruptData = _pipe->ReadInterrupt();
		if (interruptData.empty())
			return;

		HexDump("interrupt", interruptData);
		InputStream stream(interruptData);
		ContainerType containerType;
		u32 size;
		u16 eventCode;
		u32 sessionId;
		u32 transactionId;
		stream >> size;
		stream >> containerType;
		stream >> eventCode;
		stream >> sessionId;
		stream >> transactionId;
		if (containerType != ContainerType::Event)
			throw std::runtime_error("not an event");
		fprintf(stderr, "event %04x\n", eventCode);
	}

	void PipePacketer::Read(u32 transaction, ByteArray &data, ByteArray &response, int timeout)
	{
		try
		{ PollEvent(); }
		catch(const std::exception &ex)
		{ fprintf(stderr, "exception in interrupt: %s\n", ex.what()); }

		data.clear();
		response.clear();

		ByteArray message;
		Response header;
		while(true)
		{
			message = ReadMessage(timeout);
			//HexDump("message", message);
			InputStream stream(message);
			header.Read(stream);
			if (header.Transaction == transaction)
				break;

			fprintf(stderr, "drop message %04x %04x, transaction %08x\n", header.ContainerType, header.ResponseType, header.Transaction);
		}

		if (header.ContainerType == ContainerType::Data)
		{
			data = std::move(message);
			response = ReadMessage(timeout);
		}
		else
		{
			response = std::move(message);
		}

		//HexDump("response", response);
	}

	DevicePtr Device::Find()
	{
		using namespace mtp;
		usb::ContextPtr ctx(new usb::Context);

		for (usb::DeviceDescriptorPtr desc : ctx->GetDevices())
		{
			usb::DevicePtr device = desc->TryOpen(ctx);
			if (!device)
				continue;
			int confs = desc->GetConfigurationsCount();
			//fprintf(stderr, "configurations: %d\n", confs);

			for(int i = 0; i < confs; ++i)
			{
				usb::ConfigurationPtr conf = desc->GetConfiguration(i);
				int interfaces = conf->GetInterfaceCount();
				//fprintf(stderr, "interfaces: %d\n", interfaces);
				for(int j = 0; j < interfaces; ++j)
				{
					usb::InterfacePtr iface = conf->GetInterface(conf, j, 0);
					//fprintf(stderr, "%d:%d index %u, eps %u\n", i, j, iface->GetIndex(), iface->GetEndpointsCount());
					int name_idx = iface->GetNameIndex();
					if (name_idx)
					{
						std::string name = device->GetString(name_idx);
						if (name == "MTP")
						{
							//device->SetConfiguration(configuration->GetIndex());
							usb::BulkPipePtr pipe = usb::BulkPipe::Create(device, conf, iface);
							return std::make_shared<Device>(pipe);
						}
					}
					if (iface->GetClass() == 6 && iface->GetSubclass() == 1)
					{
						usb::BulkPipePtr pipe = usb::BulkPipe::Create(device, conf, iface);
						return std::make_shared<Device>(pipe);
					}
				}
			}
		}

		return nullptr;
	}

}
<commit_msg>added expected transaction to logs<commit_after>/*
 * Android File Transfer for Linux: MTP client for android devices
 * Copyright (C) 2015  Vladimir Menshakov

 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#include <mtp/ptp/Device.h>
#include <mtp/ptp/Response.h>
#include <mtp/ptp/Container.h>
#include <mtp/ptp/Messages.h>
#include <mtp/usb/Context.h>
#include <mtp/ptp/OperationRequest.h>

namespace mtp
{

	msg::DeviceInfo Device::GetDeviceInfo()
	{
		OperationRequest req(OperationCode::GetDeviceInfo, 0);
		Container container(req);
		_packeter.Write(container.Data);
		ByteArray data, response;
		_packeter.Read(0, data, response);
		//HexDump("payload", data);

		InputStream stream(data, 8); //operation code + session id
		msg::DeviceInfo gdi;
		gdi.Read(stream);
		return gdi;
	}

	SessionPtr Device::OpenSession(u32 sessionId)
	{
		OperationRequest req(OperationCode::OpenSession, 0, sessionId);
		Container container(req);
		_packeter.Write(container.Data);
		ByteArray data, response;
		_packeter.Read(0, data, response);
		//HexDump("payload", data);

		return std::make_shared<Session>(_packeter.GetPipe(), sessionId);
	}

	void PipePacketer::Write(const ByteArray &data, int timeout)
	{
		//HexDump("send", data);
		_pipe->Write(data, timeout);
	}

	ByteArray PipePacketer::ReadMessage(int timeout)
	{
		ByteArray result;
		u32 size = ~0u;
		size_t offset = 0;
		size_t packet_offset;
		while(true)
		{
			ByteArray data = _pipe->Read(timeout);
			if (size == ~0u)
			{
				InputStream stream(data);
				stream >> size;
				//fprintf(stderr, "DATA SIZE = %u\n", size);
				if (size < 4)
					throw std::runtime_error("invalid size");
				packet_offset = 4;
				result.resize(size - 4);
			}
			else
				packet_offset = 0;
			//HexDump("recv", data);

			size_t src_n = std::min(data.size() - packet_offset, result.size() - offset);
			std::copy(data.begin() + packet_offset, data.begin() + packet_offset + src_n, result.begin() + offset);
			offset += data.size();
			if (offset >= result.size())
				break;
		}
		return result;

	}

	void PipePacketer::PollEvent()
	{
		ByteArray interruptData = _pipe->ReadInterrupt();
		if (interruptData.empty())
			return;

		HexDump("interrupt", interruptData);
		InputStream stream(interruptData);
		ContainerType containerType;
		u32 size;
		u16 eventCode;
		u32 sessionId;
		u32 transactionId;
		stream >> size;
		stream >> containerType;
		stream >> eventCode;
		stream >> sessionId;
		stream >> transactionId;
		if (containerType != ContainerType::Event)
			throw std::runtime_error("not an event");
		fprintf(stderr, "event %04x\n", eventCode);
	}

	void PipePacketer::Read(u32 transaction, ByteArray &data, ByteArray &response, int timeout)
	{
		try
		{ PollEvent(); }
		catch(const std::exception &ex)
		{ fprintf(stderr, "exception in interrupt: %s\n", ex.what()); }

		data.clear();
		response.clear();

		ByteArray message;
		Response header;
		while(true)
		{
			message = ReadMessage(timeout);
			//HexDump("message", message);
			InputStream stream(message);
			header.Read(stream);
			if (header.Transaction == transaction)
				break;

			fprintf(stderr, "drop message %04x %04x, transaction %08x, expected: %08x\n", header.ContainerType, header.ResponseType, header.Transaction, transaction);
		}

		if (header.ContainerType == ContainerType::Data)
		{
			data = std::move(message);
			response = ReadMessage(timeout);
		}
		else
		{
			response = std::move(message);
		}

		//HexDump("response", response);
	}

	DevicePtr Device::Find()
	{
		using namespace mtp;
		usb::ContextPtr ctx(new usb::Context);

		for (usb::DeviceDescriptorPtr desc : ctx->GetDevices())
		{
			usb::DevicePtr device = desc->TryOpen(ctx);
			if (!device)
				continue;
			int confs = desc->GetConfigurationsCount();
			//fprintf(stderr, "configurations: %d\n", confs);

			for(int i = 0; i < confs; ++i)
			{
				usb::ConfigurationPtr conf = desc->GetConfiguration(i);
				int interfaces = conf->GetInterfaceCount();
				//fprintf(stderr, "interfaces: %d\n", interfaces);
				for(int j = 0; j < interfaces; ++j)
				{
					usb::InterfacePtr iface = conf->GetInterface(conf, j, 0);
					//fprintf(stderr, "%d:%d index %u, eps %u\n", i, j, iface->GetIndex(), iface->GetEndpointsCount());
					int name_idx = iface->GetNameIndex();
					if (name_idx)
					{
						std::string name = device->GetString(name_idx);
						if (name == "MTP")
						{
							//device->SetConfiguration(configuration->GetIndex());
							usb::BulkPipePtr pipe = usb::BulkPipe::Create(device, conf, iface);
							return std::make_shared<Device>(pipe);
						}
					}
					if (iface->GetClass() == 6 && iface->GetSubclass() == 1)
					{
						usb::BulkPipePtr pipe = usb::BulkPipe::Create(device, conf, iface);
						return std::make_shared<Device>(pipe);
					}
				}
			}
		}

		return nullptr;
	}

}
<|endoftext|>


<commit_before><commit_msg>scale columns ported to SSSE3 BUG=208 TESTED=runyuv Scale*640* Review URL: https://webrtc-codereview.appspot.com/1292004<commit_after><|endoftext|>


<commit_before>#if ! defined (__CINT__) || defined (__MAKECINT__)
#include <TTree.h>
#include <TError.h>
#include <AliLog.h>
#include <AliAnalysisManager.h>
#include <AliAnalysisDataContainer.h>
#include <AliMESbaseTask.h>
#include <AliMEStenderV2.h>
#endif

AliMEStenderV2 *AddMEStenderV2(Bool_t mc, Int_t configuration = 1, const AliVEvent *event)
{
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();

  AliMEStenderV2 *tender = new AliMEStenderV2((char*)"MEStenderV2");
  mgr->AddTask(tender);

  // task set-up
  tender->SetMCdata(mc);
  tender->SetDebugLevel(1);
	switch (configuration) {
		case 0:
	 		tender->ConfigTask( AliMEStenderV2::AliMESconfigTender::k7TeV,      // event cuts
					  AliMEStenderV2::AliMESconfigTender::kStandardITSTPCTrackCuts2010, // track cuts
					  AliMEStenderV2::AliMESconfigTender::kIterative);                  // PID priors
  		break;
		case 1:
			tender->ConfigTask( AliMEStenderV2::AliMESconfigTender::k13TeV,       // event cuts
					AliMEStenderV2::AliMESconfigTender::kStandardITSTPCTrackCuts2011, // track cuts
					AliMEStenderV2::AliMESconfigTender::kTPC);                  // PID priors
			break;
		default: printf("Configuration not defined\n");
			break;
	}
	tender->SetPriors();  // always call this after ConfigTask !!

  // connect input
  mgr->ConnectInput (tender, 0, mgr->GetCommonInputContainer());

  // create output containers
  AliAnalysisDataContainer *co[AliMESbaseTask::kNcontainers] = {NULL};
  co[0]                          = mgr->CreateContainer("tenderQA", TList::Class(), AliAnalysisManager::kOutputContainer, Form("%s:MES", mgr->GetCommonFileName()));
  co[AliMESbaseTask::kEventInfo] = mgr->CreateContainer("MESeventInfo", AliMESeventInfo::Class(), AliAnalysisManager::kExchangeContainer);
  co[AliMESbaseTask::kTracks]    = mgr->CreateContainer("MEStracks", TObjArray::Class(), AliAnalysisManager::kExchangeContainer);
  if(mc){
	  co[AliMESbaseTask::kMCeventInfo] = mgr->CreateContainer("MESMCeventInfo", AliMESeventInfo::Class(), AliAnalysisManager::kExchangeContainer);
	  co[AliMESbaseTask::kMCtracks]    = mgr->CreateContainer("MESMCtracks", TObjArray::Class(), AliAnalysisManager::kExchangeContainer);
  }

  // connect output
  for(Int_t ios(0);ios<AliMESbaseTask::kNcontainers;ios++)
	  if(co[ios]) mgr->ConnectOutput(tender, ios+1, co[ios]);

  return tender;

}

<commit_msg>fix for train test<commit_after>#if ! defined (__CINT__) || defined (__MAKECINT__)
#include <TTree.h>
#include <TError.h>
#include <AliLog.h>
#include <AliAnalysisManager.h>
#include <AliAnalysisDataContainer.h>
#include <AliMESbaseTask.h>
#include <AliMEStenderV2.h>
#endif

AliMEStenderV2 *AddMEStenderV2(Bool_t mc, Int_t configuration = 1)
{
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();

  AliMEStenderV2 *tender = new AliMEStenderV2((char*)"MEStenderV2");
  mgr->AddTask(tender);

  // task set-up
  tender->SetMCdata(mc);
  tender->SetDebugLevel(1);
	switch (configuration) {
		case 0:
	 		tender->ConfigTask( AliMEStenderV2::AliMESconfigTender::k7TeV,      // event cuts
					  AliMEStenderV2::AliMESconfigTender::kStandardITSTPCTrackCuts2010, // track cuts
					  AliMEStenderV2::AliMESconfigTender::kIterative);                  // PID priors
  		break;
		case 1:
			tender->ConfigTask( AliMEStenderV2::AliMESconfigTender::k13TeV,       // event cuts
					AliMEStenderV2::AliMESconfigTender::kStandardITSTPCTrackCuts2011, // track cuts
					AliMEStenderV2::AliMESconfigTender::kIterative);                  // PID priors
			break;
		default: printf("Configuration not defined\n");
			break;
	}
	tender->SetPriors();  // always call this after ConfigTask !!

  // connect input
  mgr->ConnectInput (tender, 0, mgr->GetCommonInputContainer());

  // create output containers
  AliAnalysisDataContainer *co[AliMESbaseTask::kNcontainers] = {NULL};
  co[0]                          = mgr->CreateContainer("tenderQA", TList::Class(), AliAnalysisManager::kOutputContainer, Form("%s:MES", mgr->GetCommonFileName()));
  co[AliMESbaseTask::kEventInfo] = mgr->CreateContainer("MESeventInfo", AliMESeventInfo::Class(), AliAnalysisManager::kExchangeContainer);
  co[AliMESbaseTask::kTracks]    = mgr->CreateContainer("MEStracks", TObjArray::Class(), AliAnalysisManager::kExchangeContainer);
  if(mc){
	  co[AliMESbaseTask::kMCeventInfo] = mgr->CreateContainer("MESMCeventInfo", AliMESeventInfo::Class(), AliAnalysisManager::kExchangeContainer);
	  co[AliMESbaseTask::kMCtracks]    = mgr->CreateContainer("MESMCtracks", TObjArray::Class(), AliAnalysisManager::kExchangeContainer);
  }

  // connect output
  for(Int_t ios(0);ios<AliMESbaseTask::kNcontainers;ios++)
	  if(co[ios]) mgr->ConnectOutput(tender, ios+1, co[ios]);

  return tender;

}
<|endoftext|>