diff options
author | Igor Murashkin <iam@google.com> | 2014-04-08 11:22:42 -0700 |
---|---|---|
committer | Riley Andrews <riandrews@google.com> | 2014-06-20 20:01:49 +0000 |
commit | d8f2a8d34a5655d81fec2f56eb3ec36bd508886a (patch) | |
tree | e86242c509bcb44d84ac35c915a01a499bc5e029 /libcutils/properties.c | |
parent | 4f5392cb6c09618b968a4c86bbde079bef57afd1 (diff) | |
download | system_core-d8f2a8d34a5655d81fec2f56eb3ec36bd508886a.zip system_core-d8f2a8d34a5655d81fec2f56eb3ec36bd508886a.tar.gz system_core-d8f2a8d34a5655d81fec2f56eb3ec36bd508886a.tar.bz2 |
cutils: Add property_get_bool, _get_int32, _get_int64
* Read out system properties with same syntax as SystemProperties.java
* Also adds unit test suite to validate correctness of properties
* Also fixes buffer overrun in property_get
(cherry picked from commit d4507e9246e4855c5431cac5c3d1a9155caebc87)
Change-Id: Ifd42911f93e17da09e6ff1298e8875e02f3b6608
Diffstat (limited to 'libcutils/properties.c')
-rw-r--r-- | libcutils/properties.c | 84 |
1 files changed, 82 insertions, 2 deletions
diff --git a/libcutils/properties.c b/libcutils/properties.c index 28d8b2f..bfbd1b8 100644 --- a/libcutils/properties.c +++ b/libcutils/properties.c @@ -15,17 +15,94 @@ */ #define LOG_TAG "properties" +// #define LOG_NDEBUG 0 #include <stdlib.h> #include <string.h> +#include <ctype.h> #include <unistd.h> #include <cutils/sockets.h> #include <errno.h> #include <assert.h> #include <cutils/properties.h> +#include <stdbool.h> +#include <inttypes.h> #include "loghack.h" +int8_t property_get_bool(const char *key, int8_t default_value) { + if (!key) { + return default_value; + } + + int8_t result = default_value; + char buf[PROPERTY_VALUE_MAX] = {'\0',}; + + int len = property_get(key, buf, ""); + if (len == 1) { + char ch = buf[0]; + if (ch == '0' || ch == 'n') { + result = false; + } else if (ch == '1' || ch == 'y') { + result = true; + } + } else if (len > 1) { + if (!strcmp(buf, "no") || !strcmp(buf, "false") || !strcmp(buf, "off")) { + result = false; + } else if (!strcmp(buf, "yes") || !strcmp(buf, "true") || !strcmp(buf, "on")) { + result = true; + } + } + + return result; +} + +// Convert string property to int (default if fails); return default value if out of bounds +static intmax_t property_get_imax(const char *key, intmax_t lower_bound, intmax_t upper_bound, + intmax_t default_value) { + if (!key) { + return default_value; + } + + intmax_t result = default_value; + char buf[PROPERTY_VALUE_MAX] = {'\0',}; + char *end = NULL; + + int len = property_get(key, buf, ""); + if (len > 0) { + int tmp = errno; + errno = 0; + + // Infer base automatically + result = strtoimax(buf, &end, /*base*/0); + if ((result == INTMAX_MIN || result == INTMAX_MAX) && errno == ERANGE) { + // Over or underflow + result = default_value; + ALOGV("%s(%s,%lld) - overflow", __FUNCTION__, key, default_value); + } else if (result < lower_bound || result > upper_bound) { + // Out of range of requested bounds + result = default_value; + ALOGV("%s(%s,%lld) - out of range", __FUNCTION__, key, default_value); + } else if (end == buf) { + // Numeric conversion failed + result = default_value; + ALOGV("%s(%s,%lld) - numeric conversion failed", __FUNCTION__, key, default_value); + } + + errno = tmp; + } + + return result; +} + +int64_t property_get_int64(const char *key, int64_t default_value) { + return (int64_t)property_get_imax(key, INT64_MIN, INT64_MAX, default_value); +} + +int32_t property_get_int32(const char *key, int32_t default_value) { + return (int32_t)property_get_imax(key, INT32_MIN, INT32_MAX, default_value); +} + #ifdef HAVE_LIBC_SYSTEM_PROPERTIES #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ @@ -44,10 +121,13 @@ int property_get(const char *key, char *value, const char *default_value) if(len > 0) { return len; } - if(default_value) { len = strlen(default_value); - memcpy(value, default_value, len + 1); + if (len >= PROPERTY_VALUE_MAX) { + len = PROPERTY_VALUE_MAX - 1; + } + memcpy(value, default_value, len); + value[len] = '\0'; } return len; } |