Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11469ce0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Avoid KeyedVector and String8 in PropertyMap"

parents f6c47b3c 4f94c1ad
Loading
Loading
Loading
Loading
+11 −16
Original line number Diff line number Diff line
@@ -18,10 +18,8 @@
#define _UTILS_PROPERTY_MAP_H

#include <android-base/result.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/String8.h>
#include <utils/Tokenizer.h>
#include <unordered_map>

namespace android {

@@ -58,30 +56,27 @@ public:
    /* Adds a property.
     * Replaces the property with the same key if it is already present.
     */
    void addProperty(const String8& key, const String8& value);

    /* Returns true if the property map contains the specified key. */
    bool hasProperty(const String8& key) const;
    void addProperty(const std::string& key, const std::string& value);

    /* Gets the value of a property and parses it.
     * Returns true and sets outValue if the key was found and its value was parsed successfully.
     * Otherwise returns false and does not modify outValue.  (Also logs a warning.)
     */
    bool tryGetProperty(const String8& key, String8& outValue) const;
    bool tryGetProperty(const String8& key, bool& outValue) const;
    bool tryGetProperty(const String8& key, int32_t& outValue) const;
    bool tryGetProperty(const String8& key, float& outValue) const;
    bool tryGetProperty(const std::string& key, std::string& outValue) const;
    bool tryGetProperty(const std::string& key, bool& outValue) const;
    bool tryGetProperty(const std::string& key, int32_t& outValue) const;
    bool tryGetProperty(const std::string& key, float& outValue) const;

    /* Adds all values from the specified property map. */
    void addAll(const PropertyMap* map);

    /* Gets the underlying property map. */
    inline const KeyedVector<String8, String8>& getProperties() const { return mProperties; }

    /* Loads a property map from a file. */
    static android::base::Result<std::unique_ptr<PropertyMap>> load(const char* filename);

private:
    /* Returns true if the property map contains the specified key. */
    bool hasProperty(const std::string& key) const;

    class Parser {
        PropertyMap* mMap;
        Tokenizer* mTokenizer;
@@ -95,11 +90,11 @@ private:
        status_t parseType();
        status_t parseKey();
        status_t parseKeyProperty();
        status_t parseModifier(const String8& token, int32_t* outMetaState);
        status_t parseModifier(const std::string& token, int32_t* outMetaState);
        status_t parseCharacterLiteral(char16_t* outCharacter);
    };

    KeyedVector<String8, String8> mProperties;
    std::unordered_map<std::string, std::string> mProperties;
};

} // namespace android
+10 −13
Original line number Diff line number Diff line
@@ -49,25 +49,23 @@ status_t KeyMap::load(const InputDeviceIdentifier& deviceIdentifier,
        const PropertyMap* deviceConfiguration) {
    // Use the configured key layout if available.
    if (deviceConfiguration) {
        String8 keyLayoutName;
        if (deviceConfiguration->tryGetProperty(String8("keyboard.layout"),
                keyLayoutName)) {
        std::string keyLayoutName;
        if (deviceConfiguration->tryGetProperty("keyboard.layout", keyLayoutName)) {
            status_t status = loadKeyLayout(deviceIdentifier, keyLayoutName.c_str());
            if (status == NAME_NOT_FOUND) {
                ALOGE("Configuration for keyboard device '%s' requested keyboard layout '%s' but "
                      "it was not found.",
                        deviceIdentifier.name.c_str(), keyLayoutName.string());
                      deviceIdentifier.name.c_str(), keyLayoutName.c_str());
            }
        }

        String8 keyCharacterMapName;
        if (deviceConfiguration->tryGetProperty(String8("keyboard.characterMap"),
                keyCharacterMapName)) {
        std::string keyCharacterMapName;
        if (deviceConfiguration->tryGetProperty("keyboard.characterMap", keyCharacterMapName)) {
            status_t status = loadKeyCharacterMap(deviceIdentifier, keyCharacterMapName.c_str());
            if (status == NAME_NOT_FOUND) {
                ALOGE("Configuration for keyboard device '%s' requested keyboard character "
                      "map '%s' but it was not found.",
                        deviceIdentifier.name.c_str(), keyCharacterMapName.string());
                      deviceIdentifier.name.c_str(), keyCharacterMapName.c_str());
            }
        }

@@ -165,7 +163,7 @@ bool isKeyboardSpecialFunction(const PropertyMap* config) {
        return false;
    }
    bool isSpecialFunction = false;
    config->tryGetProperty(String8("keyboard.specialFunction"), isSpecialFunction);
    config->tryGetProperty("keyboard.specialFunction", isSpecialFunction);
    return isSpecialFunction;
}

@@ -180,8 +178,7 @@ bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentifier,

    if (deviceConfiguration) {
        bool builtIn = false;
        if (deviceConfiguration->tryGetProperty(String8("keyboard.builtIn"), builtIn)
                && builtIn) {
        if (deviceConfiguration->tryGetProperty("keyboard.builtIn", builtIn) && builtIn) {
            return true;
        }
    }
+24 −23
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#define LOG_TAG "PropertyMap"

#include <input/PropertyMap.h>
#include <log/log.h>

// Enables debug output for the parser.
#define DEBUG_PARSER 0
@@ -39,25 +40,25 @@ void PropertyMap::clear() {
    mProperties.clear();
}

void PropertyMap::addProperty(const String8& key, const String8& value) {
    mProperties.add(key, value);
void PropertyMap::addProperty(const std::string& key, const std::string& value) {
    mProperties.emplace(key, value);
}

bool PropertyMap::hasProperty(const String8& key) const {
    return mProperties.indexOfKey(key) >= 0;
bool PropertyMap::hasProperty(const std::string& key) const {
    return mProperties.find(key) != mProperties.end();
}

bool PropertyMap::tryGetProperty(const String8& key, String8& outValue) const {
    ssize_t index = mProperties.indexOfKey(key);
    if (index < 0) {
bool PropertyMap::tryGetProperty(const std::string& key, std::string& outValue) const {
    auto it = mProperties.find(key);
    if (it == mProperties.end()) {
        return false;
    }

    outValue = mProperties.valueAt(index);
    outValue = it->second;
    return true;
}

bool PropertyMap::tryGetProperty(const String8& key, bool& outValue) const {
bool PropertyMap::tryGetProperty(const std::string& key, bool& outValue) const {
    int32_t intValue;
    if (!tryGetProperty(key, intValue)) {
        return false;
@@ -67,34 +68,34 @@ bool PropertyMap::tryGetProperty(const String8& key, bool& outValue) const {
    return true;
}

bool PropertyMap::tryGetProperty(const String8& key, int32_t& outValue) const {
    String8 stringValue;
bool PropertyMap::tryGetProperty(const std::string& key, int32_t& outValue) const {
    std::string stringValue;
    if (!tryGetProperty(key, stringValue) || stringValue.length() == 0) {
        return false;
    }

    char* end;
    int value = strtol(stringValue.string(), &end, 10);
    int value = strtol(stringValue.c_str(), &end, 10);
    if (*end != '\0') {
        ALOGW("Property key '%s' has invalid value '%s'.  Expected an integer.", key.string(),
              stringValue.string());
        ALOGW("Property key '%s' has invalid value '%s'.  Expected an integer.", key.c_str(),
              stringValue.c_str());
        return false;
    }
    outValue = value;
    return true;
}

bool PropertyMap::tryGetProperty(const String8& key, float& outValue) const {
    String8 stringValue;
bool PropertyMap::tryGetProperty(const std::string& key, float& outValue) const {
    std::string stringValue;
    if (!tryGetProperty(key, stringValue) || stringValue.length() == 0) {
        return false;
    }

    char* end;
    float value = strtof(stringValue.string(), &end);
    float value = strtof(stringValue.c_str(), &end);
    if (*end != '\0') {
        ALOGW("Property key '%s' has invalid value '%s'.  Expected a float.", key.string(),
              stringValue.string());
        ALOGW("Property key '%s' has invalid value '%s'.  Expected a float.", key.c_str(),
              stringValue.c_str());
        return false;
    }
    outValue = value;
@@ -102,8 +103,8 @@ bool PropertyMap::tryGetProperty(const String8& key, float& outValue) const {
}

void PropertyMap::addAll(const PropertyMap* map) {
    for (size_t i = 0; i < map->mProperties.size(); i++) {
        mProperties.add(map->mProperties.keyAt(i), map->mProperties.valueAt(i));
    for (const auto& [key, value] : map->mProperties) {
        mProperties.emplace(key, value);
    }
}

@@ -184,13 +185,13 @@ status_t PropertyMap::Parser::parse() {
                return BAD_VALUE;
            }

            if (mMap->hasProperty(keyToken)) {
            if (mMap->hasProperty(keyToken.string())) {
                ALOGE("%s: Duplicate property value for key '%s'.",
                      mTokenizer->getLocation().string(), keyToken.string());
                return BAD_VALUE;
            }

            mMap->addProperty(keyToken, valueToken);
            mMap->addProperty(keyToken.string(), valueToken.string());
        }

        mTokenizer->nextLine();
+10 −22
Original line number Diff line number Diff line
@@ -17,32 +17,22 @@
#include "android-base/file.h"
#include "fuzzer/FuzzedDataProvider.h"
#include "input/PropertyMap.h"
#include "utils/String8.h"

static constexpr int MAX_FILE_SIZE = 256;
static constexpr int MAX_STR_LEN = 2048;
static constexpr int MAX_OPERATIONS = 1000;

static const std::vector<std::function<void(FuzzedDataProvider*, android::PropertyMap)>>
static const std::vector<std::function<void(FuzzedDataProvider*, android::PropertyMap&)>>
        operations = {
                [](FuzzedDataProvider*, android::PropertyMap propertyMap) -> void {
                    propertyMap.getProperties();
                },
                [](FuzzedDataProvider*, android::PropertyMap propertyMap) -> void {
                [](FuzzedDataProvider*, android::PropertyMap& propertyMap) -> void {
                    propertyMap.clear();
                },
                [](FuzzedDataProvider* dataProvider, android::PropertyMap propertyMap) -> void {
                    std::string keyStr = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
                    android::String8 key = android::String8(keyStr.c_str());
                    propertyMap.hasProperty(key);
                },
                [](FuzzedDataProvider* dataProvider, android::PropertyMap propertyMap) -> void {
                    std::string keyStr = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
                    android::String8 key = android::String8(keyStr.c_str());
                    android::String8 out;
                [](FuzzedDataProvider* dataProvider, android::PropertyMap& propertyMap) -> void {
                    std::string key = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
                    std::string out;
                    propertyMap.tryGetProperty(key, out);
                },
                [](FuzzedDataProvider* dataProvider, android::PropertyMap /*unused*/) -> void {
                [](FuzzedDataProvider* dataProvider, android::PropertyMap& /*unused*/) -> void {
                    TemporaryFile tf;
                    // Generate file contents
                    std::string contents = dataProvider->ConsumeRandomLengthString(MAX_FILE_SIZE);
@@ -54,17 +44,15 @@ static const std::vector<std::function<void(FuzzedDataProvider*, android::Proper
                    }
                    android::PropertyMap::load(tf.path);
                },
                [](FuzzedDataProvider* dataProvider, android::PropertyMap propertyMap) -> void {
                    std::string keyStr = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
                    std::string valStr = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
                    android::String8 key = android::String8(keyStr.c_str());
                    android::String8 val = android::String8(valStr.c_str());
                [](FuzzedDataProvider* dataProvider, android::PropertyMap& propertyMap) -> void {
                    std::string key = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
                    std::string val = dataProvider->ConsumeRandomLengthString(MAX_STR_LEN);
                    propertyMap.addProperty(key, val);
                },
};
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    FuzzedDataProvider dataProvider(data, size);
    android::PropertyMap propertyMap = android::PropertyMap();
    android::PropertyMap propertyMap;

    int opsRun = 0;
    while (dataProvider.remaining_bytes() > 0 && opsRun++ < MAX_OPERATIONS) {
+8 −11
Original line number Diff line number Diff line
@@ -240,19 +240,16 @@ input_property_map_t* InputDriver::inputGetDevicePropertyMap(input_device_identi
    return nullptr;
}

input_property_t* InputDriver::inputGetDeviceProperty(input_property_map_t* map,
        const char* key) {
    String8 keyString(key);
input_property_t* InputDriver::inputGetDeviceProperty(input_property_map_t* map, const char* key) {
    if (map != nullptr) {
        if (map->propertyMap->hasProperty(keyString)) {
            auto prop = new input_property_t();
            if (!map->propertyMap->tryGetProperty(keyString, prop->value)) {
                delete prop;
        std::string value;
        auto prop = std::make_unique<input_property_t>();
        if (!map->propertyMap->tryGetProperty(key, value)) {
            return nullptr;
        }
            prop->key = keyString;
            return prop;
        }
        prop->key = key;
        prop->value = value.c_str();
        return prop.release();
    }
    return nullptr;
}
Loading