first and last commit
This commit is contained in:
commit
1bf4efd552
2612 files changed
+636500
No files matched your search
Vendored
+560
@@ -0,0 +1,560 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2014 Apple Inc. All rights reserved.
|
||||
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Computer, Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Computer, Inc.
|
||||
*/
|
||||
#include <debug.h>
|
||||
#include <list.h>
|
||||
#include <lib/env.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/menu.h>
|
||||
|
||||
static struct list_node env_list = LIST_INITIAL_VALUE(env_list);
|
||||
|
||||
#define ENV_VAR_ENTRY_NAME_LEN 64
|
||||
|
||||
struct env_var_entry {
|
||||
struct list_node node;
|
||||
struct env_var var;
|
||||
char name[ENV_VAR_ENTRY_NAME_LEN];
|
||||
};
|
||||
|
||||
static int str2ip(const char *str, uint32_t *ip);
|
||||
static int str2mac(const char *str, uint8_t addr[6]);
|
||||
|
||||
#define kIBootHiddenEnvDomain "com.apple.System."
|
||||
|
||||
#if DEBUG_BUILD
|
||||
static bool nvram_whitelist_override = false;
|
||||
#else
|
||||
static const bool nvram_whitelist_override = false;
|
||||
#endif
|
||||
|
||||
static bool hide_key(const char *str)
|
||||
{
|
||||
if (0 == strncmp(str, kIBootHiddenEnvDomain, sizeof(kIBootHiddenEnvDomain)-1))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct env_var_entry *find_var_entry(const char *name)
|
||||
{
|
||||
struct env_var_entry *entry;
|
||||
|
||||
list_for_every_entry(&env_list, entry, struct env_var_entry, node) {
|
||||
if (!strcmp(entry->name, name))
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct env_var *env_get_etc(const char *name)
|
||||
{
|
||||
struct env_var_entry *entry;
|
||||
|
||||
entry = find_var_entry(name);
|
||||
if (!entry)
|
||||
return NULL;
|
||||
|
||||
if ((entry->var.flags & ENV_SHADOW) && !nvram_whitelist_override) {
|
||||
dprintf(DEBUG_CRITICAL, "\x1b[1;5;31mBlocked read\x1b[m from shadowed variable \"%s\"\n", name);
|
||||
dprintf(DEBUG_CRITICAL, "Disable NVRAM whitelist with DEBUG iBoot command envprot off\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &entry->var;
|
||||
}
|
||||
|
||||
const char *env_get(const char *name)
|
||||
{
|
||||
const struct env_var *var;
|
||||
|
||||
var = env_get_etc(name);
|
||||
if (!var)
|
||||
return NULL;
|
||||
|
||||
return var->str;
|
||||
}
|
||||
|
||||
size_t env_get_uint(const char *name, size_t default_val)
|
||||
{
|
||||
const struct env_var *var;
|
||||
|
||||
var = env_get_etc(name);
|
||||
if (!var)
|
||||
return default_val;
|
||||
|
||||
return var->u;
|
||||
}
|
||||
|
||||
bool env_get_bool(const char *name, bool default_val)
|
||||
{
|
||||
const struct env_var *var;
|
||||
|
||||
var = env_get_etc(name);
|
||||
if (NULL == var)
|
||||
return default_val;
|
||||
|
||||
if (!strcmp(var->str, "true"))
|
||||
return true;
|
||||
if (0 != var->u)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int str2ip(const char *str, uint32_t *ip)
|
||||
{
|
||||
char numstr[16];
|
||||
int num;
|
||||
int field = 0;
|
||||
const char *ptr;
|
||||
|
||||
if (str == NULL)
|
||||
return -1;
|
||||
|
||||
*ip = 0;
|
||||
|
||||
ptr = str;
|
||||
for (field = 0; field < 4; field++) {
|
||||
char *dot = strchr(ptr, '.');
|
||||
|
||||
if (dot) {
|
||||
strlcpy(numstr, ptr, __min((unsigned)(dot - ptr + 1), sizeof(numstr)));
|
||||
} else {
|
||||
strlcpy(numstr, ptr, sizeof(numstr));
|
||||
}
|
||||
|
||||
// printf("numstr '%s'\n", numstr);
|
||||
|
||||
num = strtol(numstr, NULL, 0);
|
||||
if (num < 0 || num > 255) {
|
||||
return -1;
|
||||
}
|
||||
*ip |= (num << (8 * field));
|
||||
|
||||
if (dot)
|
||||
ptr = dot + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int env_get_ipaddr(const char *name, uint32_t *ip)
|
||||
{
|
||||
const char *env;
|
||||
|
||||
env = env_get(name);
|
||||
if (!env)
|
||||
return -1;
|
||||
|
||||
if (str2ip(env, ip) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int str2mac(const char *str, uint8_t addr[6])
|
||||
{
|
||||
char numstr[16];
|
||||
int num;
|
||||
int field = 0;
|
||||
const char *ptr;
|
||||
char *endptr;
|
||||
|
||||
if (str == NULL)
|
||||
return -1;
|
||||
|
||||
addr[0] = addr[1] = addr[2] = addr[3] = addr[4] = addr[5] = 0;
|
||||
|
||||
ptr = str;
|
||||
for (field = 0; field < 6; field++) {
|
||||
char *sep = strchr(ptr, ':');
|
||||
|
||||
if (sep) {
|
||||
strlcpy(numstr, ptr, __min((unsigned)(sep - ptr + 1), sizeof(numstr)));
|
||||
} else {
|
||||
strlcpy(numstr, ptr, sizeof(numstr));
|
||||
}
|
||||
|
||||
// printf("numstr '%s'\n", numstr);
|
||||
|
||||
num = strtol(numstr, &endptr, 16);
|
||||
if (endptr == numstr) {
|
||||
dprintf(DEBUG_INFO, "malformed MAC address %s\n", str);
|
||||
return -1;
|
||||
}
|
||||
if (num < 0 || num > 255) {
|
||||
dprintf(DEBUG_INFO, "makformed MAC address %s\n", str);
|
||||
return -1;
|
||||
}
|
||||
addr[field] = num;
|
||||
|
||||
if (sep)
|
||||
ptr = sep + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int env_get_ethaddr(const char *name, uint8_t ethaddr[6])
|
||||
{
|
||||
const char *env;
|
||||
|
||||
env = env_get(name);
|
||||
if (!env)
|
||||
return -1;
|
||||
|
||||
if (str2mac(env, ethaddr) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int env_set(const char *name, const char *val, uint32_t flags)
|
||||
{
|
||||
struct env_var_entry *entry;
|
||||
|
||||
if (flags & ENV_PERSISTENT) {
|
||||
if (env_blacklist_nvram(name))
|
||||
flags |= ENV_SHADOW;
|
||||
}
|
||||
|
||||
/* see if it already exists */
|
||||
entry = find_var_entry(name);
|
||||
if (entry) {
|
||||
if ((flags & ENV_SHADOW) && !(entry->var.flags & ENV_SHADOW) && !nvram_whitelist_override) {
|
||||
dprintf(DEBUG_CRITICAL, "\x1b[1;5;31mBlocked shadowed write\x1b[m to variable \"%s\"\n", name);
|
||||
dprintf(DEBUG_CRITICAL, "Disable NVRAM whitelist with DEBUG iBoot command envprot off\n");
|
||||
// If the variable exists, is not on the whitelist for NVRAM variables,
|
||||
// and the value was generated internally (probably from the default environment),
|
||||
// refuse to modify the existing value.
|
||||
// This will result in the variable getting removed from nvram on saveenv, but
|
||||
// protects us from people removing things from the default environment.
|
||||
return -1;
|
||||
} else {
|
||||
// If the variable exists and either is on the whitelist or was not
|
||||
// generated internally, delete the old value
|
||||
env_unset(name);
|
||||
}
|
||||
}
|
||||
|
||||
entry = malloc(sizeof(struct env_var_entry));
|
||||
|
||||
strlcpy(entry->name, name, sizeof(entry->name));
|
||||
|
||||
entry->var.str = strdup(val);
|
||||
if (entry->var.str == NULL) {
|
||||
free(entry);
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry->var.u = strtoul(entry->var.str, NULL, 0);
|
||||
|
||||
/* save the flags */
|
||||
entry->var.flags = flags;
|
||||
|
||||
list_add_tail(&env_list, &entry->node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int env_set_uint(const char *name, size_t val, uint32_t flags)
|
||||
{
|
||||
char numbuf[(sizeof(size_t) * 2) + 3]; // plus '3' to store "0x" and null terminator
|
||||
|
||||
snprintf(numbuf, sizeof(numbuf), "0x%lx", val);
|
||||
|
||||
return env_set(name, numbuf, flags);
|
||||
}
|
||||
|
||||
int env_unset(const char *name)
|
||||
{
|
||||
struct env_var_entry *entry;
|
||||
|
||||
entry = find_var_entry(name);
|
||||
if (!entry)
|
||||
return 0;
|
||||
|
||||
list_delete(&entry->node);
|
||||
|
||||
free(entry->var.str);
|
||||
free(entry);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* used by the nvram code to write the environment out to nvram.
|
||||
* serialize all of the persistent environment variables with a simple
|
||||
* <name>=<value>NULL...
|
||||
* strategy.
|
||||
*/
|
||||
size_t env_serialize(uint8_t *buf, size_t buf_len)
|
||||
{
|
||||
size_t offset;
|
||||
struct env_var_entry *entry;
|
||||
|
||||
offset = 0;
|
||||
list_for_every_entry(&env_list, entry, struct env_var_entry, node) {
|
||||
if (entry->var.flags & ENV_PERSISTENT) {
|
||||
/* print one var into the buffer, avoiding overflow */
|
||||
offset += snprintf((void *)(buf + offset), buf_len - offset, "%s=%s", entry->name, entry->var.str) + 1;
|
||||
|
||||
/* effectively require there to always be at least one free byte */
|
||||
if (offset >= buf_len)
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* opposite of the above */
|
||||
int env_unserialize(const uint8_t *buf, size_t buf_len)
|
||||
{
|
||||
size_t offset;
|
||||
|
||||
#if 0
|
||||
dprintf(DEBUG_SPEW, "serialized environment vars:\n");
|
||||
dhexdump(DEBUG_SPEW, buf, buf_len);
|
||||
#endif
|
||||
|
||||
offset = 0;
|
||||
while (offset < buf_len) {
|
||||
char envname[64];
|
||||
char envval[256];
|
||||
uint32_t var_start, var_end;
|
||||
uint32_t val_start, val_end;
|
||||
|
||||
if (buf[offset] == 0) {
|
||||
offset++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* find the start and end of the variable name */
|
||||
var_start = offset;
|
||||
for (var_end = var_start; buf[var_end] != '=' && buf[var_end] != 0; var_end++)
|
||||
;
|
||||
if (buf[var_end] == 0) // malformed variable, no '='
|
||||
break;
|
||||
|
||||
/* find the start and end of the value component */
|
||||
val_start = var_end + 1; /* skip the '=' */
|
||||
for (val_end = val_start; buf[val_end] != 0; val_end++)
|
||||
;
|
||||
|
||||
/* copy them out */
|
||||
strlcpy(envname, (const char *)&buf[var_start], __min(var_end - var_start + 1, sizeof(envname)));
|
||||
strlcpy(envval, (const char *)&buf[val_start], __min(val_end - val_start + 1, sizeof(envval)));
|
||||
|
||||
dprintf(DEBUG_SPEW, "'%s' = '%s'\n", envname, envval);
|
||||
|
||||
/* load the environment */
|
||||
if (strlen(envname) > 0 && strlen(envval) > 0) {
|
||||
uint32_t flags = ENV_PERSISTENT;
|
||||
if (env_blacklist_nvram(envname))
|
||||
flags |= ENV_SHADOW;
|
||||
env_set(envname, envval, flags);
|
||||
}
|
||||
|
||||
offset = val_end + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* for unit testing testing purposes only, remove every environment
|
||||
* variable
|
||||
*/
|
||||
void env_reset(void)
|
||||
{
|
||||
struct env_var_entry *entry;
|
||||
struct env_var_entry *temp;
|
||||
|
||||
list_for_every_entry_safe(&env_list, entry, temp, struct env_var_entry, node) {
|
||||
env_unset(entry->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* command prompt routines */
|
||||
static void dump_var(const struct env_var_entry *entry)
|
||||
{
|
||||
int i, binary = 0;
|
||||
uint32_t flags;
|
||||
|
||||
/* filter out non-ascii strings in variable values */
|
||||
for (i = 0; i < ENV_VAR_ENTRY_NAME_LEN; i++) {
|
||||
if (entry->var.str[i] == 0)
|
||||
break;
|
||||
if (entry->var.str[i] < 0x20 || entry->var.str[i] > 0x7e)
|
||||
binary = 1;
|
||||
}
|
||||
|
||||
flags = entry->var.flags;
|
||||
printf("%c %s = %s%s%s\n",
|
||||
(flags & ENV_SHADOW) ? 'S' : ((flags & ENV_PERSISTENT) ? 'P' : ' '),
|
||||
entry->name,
|
||||
binary ? "" : "\"",
|
||||
binary ? "<DATA>" : entry->var.str,
|
||||
binary ? "" : "\"");
|
||||
}
|
||||
|
||||
int do_printenv(int argc, struct cmd_arg *args)
|
||||
{
|
||||
struct env_var_entry *entry;
|
||||
|
||||
if (argc >= 2) {
|
||||
/* display a single variable */
|
||||
entry = find_var_entry(args[1].str);
|
||||
if (entry) {
|
||||
if (!hide_key(entry->name))
|
||||
dump_var(entry);
|
||||
} else {
|
||||
printf("variable %s not set\n", args[1].str);
|
||||
}
|
||||
} else {
|
||||
/* display all variables */
|
||||
list_for_every_entry(&env_list, entry, struct env_var_entry, node) {
|
||||
if (hide_key(entry->name)) continue;
|
||||
dump_var(entry);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_getenv(int argc, struct cmd_arg *args)
|
||||
{
|
||||
struct env_var_entry *entry;
|
||||
if(argc != 2)
|
||||
{
|
||||
#if !RELEASE_BUILD
|
||||
printf("%s <var>\n", args[0].str);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry = find_var_entry(args[1].str);
|
||||
if(!entry)
|
||||
return -1;
|
||||
if(hide_key(entry->name))
|
||||
return -1;
|
||||
if(env_blacklist(entry->name, false))
|
||||
return -1;
|
||||
return env_set("cmd-results", entry->var.str, 0);
|
||||
}
|
||||
|
||||
int do_setenv(int argc, struct cmd_arg *args)
|
||||
{
|
||||
if (argc < 2) {
|
||||
#if !RELEASE_BUILD
|
||||
printf("not enough arguments.\n");
|
||||
printf("%s <var> [<value>] ...\n", args[0].str);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hide_key(args[1].str)) return -1;
|
||||
|
||||
if (env_blacklist(args[1].str, true)) return -1;
|
||||
|
||||
if (argc < 3) {
|
||||
env_unset(args[1].str);
|
||||
} else {
|
||||
size_t buf_size = 512;
|
||||
char *envbuf = malloc(buf_size);
|
||||
int i;
|
||||
|
||||
/* reassemble a string from all the command line args */
|
||||
envbuf[0] = 0;
|
||||
for (i = 2; i < argc; i++) {
|
||||
strlcat(envbuf, args[i].str, buf_size);
|
||||
if (i != (argc - 1))
|
||||
strlcat(envbuf, " ", buf_size);
|
||||
}
|
||||
|
||||
env_set(args[1].str, envbuf, ENV_PERSISTENT);
|
||||
|
||||
free(envbuf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_clearenv(int argc, struct cmd_arg *args)
|
||||
{
|
||||
struct env_var_entry *entry, *pentry;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("not enough arguments.\n");
|
||||
printf("Usage: It's a two step process. Run the following commands to clear\n");
|
||||
printf("\t\tclearenv <var>\n");
|
||||
printf("\t\tclearenv 1 \t {confirms the clear}\n");
|
||||
printf("ex: clearenv auto-boot boot-args\n");
|
||||
printf(" clearenv 1\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (args[1].u == 0) {
|
||||
printf("Clear pending. Run command \"clearenv 1\" to confirm\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* clear all persistent variables */
|
||||
while (1) {
|
||||
pentry = 0;
|
||||
list_for_every_entry(&env_list, entry, struct env_var_entry, node) {
|
||||
if (hide_key(entry->name)) continue;
|
||||
if (entry->var.flags & ENV_PERSISTENT) {
|
||||
pentry = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pentry == 0) break;
|
||||
|
||||
env_unset(pentry->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if DEBUG_BUILD
|
||||
int
|
||||
do_envprot(int argc, struct cmd_arg *args)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (argc != 2) {
|
||||
result = -1;
|
||||
} else {
|
||||
if (strcmp(args[1].str, "off") == 0) {
|
||||
nvram_whitelist_override = true;
|
||||
printf("Disabled NVRAM whitelist\n");
|
||||
} else if (strcmp(args[1].str, "on") == 0) {
|
||||
nvram_whitelist_override = false;
|
||||
printf("Enabled NVRAM whitelist\n");
|
||||
} else {
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (result < 0)
|
||||
printf("Usage: envprot {on | off}\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
# Copyright (C) 2014 Apple Inc. All rights reserved.
|
||||
#
|
||||
# This document is the property of Apple Inc.
|
||||
# It is considered confidential and proprietary.
|
||||
#
|
||||
# This document may not be reproduced or transmitted in any form,
|
||||
# in whole or in part, without the express written permission of
|
||||
# Apple Inc.
|
||||
#
|
||||
|
||||
LIBENV_DIR := $(GET_LOCAL_DIR)
|
||||
LIBENV_BUILD := $(call TOLIBDIR,$(LIBENV_DIR)/LIBENV.a)
|
||||
COMMONLIBS += LIBENV
|
||||
|
||||
# Only process the remainder of the makefile if we are building libraries
|
||||
#
|
||||
ifeq ($(MAKEPHASE),libraries)
|
||||
|
||||
LIBENV_OBJS := $(LIBENV_DIR)/env.o
|
||||
|
||||
LIBENV_OBJS := $(call TOLIBOBJDIR,$(LIBENV_OBJS))
|
||||
|
||||
ALL_DEPS += $(LIBENV_OBJS:%o=%d)
|
||||
|
||||
$(LIBENV_BUILD): $(LIBENV_OBJS)
|
||||
|
||||
endif
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2014 Apple Inc. All rights reserved.
|
||||
# Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
|
||||
#
|
||||
# This document is the property of Apple Inc.
|
||||
# It is considered confidential and proprietary.
|
||||
#
|
||||
# This document may not be reproduced or transmitted in any form,
|
||||
# in whole or in part, without the express written permission of
|
||||
# Apple Inc.
|
||||
#
|
||||
|
||||
OPTIONS += WITH_ENV=1
|
||||
LIBRARY_MODULES += lib/env
|
||||
Vendored
+231
@@ -0,0 +1,231 @@
|
||||
#include <unittest.h>
|
||||
#include <lib/env.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern int do_printenv(int argc, void *);
|
||||
extern void env_reset(void);
|
||||
|
||||
/* Before each test case is called, empty out the environment */
|
||||
void test_env_suite_setup(void)
|
||||
{
|
||||
env_reset();
|
||||
}
|
||||
|
||||
void test_env(uintptr_t context)
|
||||
{
|
||||
const uint8_t source[] =
|
||||
"numvar=1234567890\0"
|
||||
"truevar=true\0"
|
||||
"falsevar=false\0"
|
||||
"zerovar=0\0"
|
||||
"strvar=hi mom 123=abc-_*\0"
|
||||
"ethaddr=12:34:56:78:ab:cd\0"
|
||||
"ipaddr=32.1.0.100\0"
|
||||
"blacklisted=nocando\0"
|
||||
"com.apple.System.hideme=hidden";
|
||||
uint8_t ethaddr[6];
|
||||
uint32_t ipaddr;
|
||||
|
||||
TEST_ASSERT_EQ(env_unserialize(source, sizeof(source)), 0);
|
||||
|
||||
// Test getting variables as strings
|
||||
TEST_ASSERT_STR_EQ(env_get("numvar"), "1234567890");
|
||||
TEST_ASSERT_STR_EQ(env_get("truevar"), "true");
|
||||
TEST_ASSERT_STR_EQ(env_get("falsevar"), "false");
|
||||
TEST_ASSERT_STR_EQ(env_get("zerovar"), "0");
|
||||
TEST_ASSERT_STR_EQ(env_get("strvar"), "hi mom 123=abc-_*");
|
||||
TEST_ASSERT_STR_EQ(env_get("ethaddr"), "12:34:56:78:ab:cd");
|
||||
TEST_ASSERT_STR_EQ(env_get("ipaddr"), "32.1.0.100");
|
||||
TEST_ASSERT_STR_EQ(env_get("com.apple.System.hideme"), "hidden");
|
||||
|
||||
// Test getting variables as booleans
|
||||
TEST_ASSERT_EQ(env_get_bool("truevar", false), true);
|
||||
TEST_ASSERT_EQ(env_get_bool("truevar", true), true);
|
||||
TEST_ASSERT_EQ(env_get_bool("falsevar", false), false);
|
||||
TEST_ASSERT_EQ(env_get_bool("falsevar", true), false);
|
||||
TEST_ASSERT_EQ(env_get_bool("zerovar", false), false);
|
||||
TEST_ASSERT_EQ(env_get_bool("zerovar", true), false);
|
||||
TEST_ASSERT_EQ(env_get_bool("numvar", false), true);
|
||||
TEST_ASSERT_EQ(env_get_bool("numvar", true), true);
|
||||
TEST_ASSERT_EQ(env_get_bool("strvar", false), false);
|
||||
TEST_ASSERT_EQ(env_get_bool("strvar", true), false);
|
||||
// Test default value for env_get_bool
|
||||
TEST_ASSERT_EQ(env_get_bool("notavar", true), true);
|
||||
TEST_ASSERT_EQ(env_get_bool("notavar", false), false);
|
||||
|
||||
// Test getting variables as numbers
|
||||
TEST_ASSERT_EQ(env_get_uint("numvar", 0), 1234567890ULL);
|
||||
// Test default value for env_get_uint
|
||||
TEST_ASSERT_EQ(env_get_uint("notavar", 123456), 123456);
|
||||
|
||||
// Test getting variables as MAC addresses
|
||||
TEST_ASSERT_EQ(env_get_ethaddr("ethaddr", ethaddr), 0);
|
||||
TEST_ASSERT_MEM_EQ(ethaddr, TEST_ARRAY(uint8_t, 0x12, 0x34, 0x56, 0x78, 0xab, 0xcd), sizeof(ethaddr));
|
||||
// Test rejecting malformed MAC addresses
|
||||
TEST_ASSERT_NEQ(env_get_ethaddr("strvar", ethaddr), 0);
|
||||
TEST_ASSERT_NEQ(env_get_ethaddr("numvar", ethaddr), 0);
|
||||
TEST_ASSERT_NEQ(env_get_ethaddr("notavar", ethaddr), 0);
|
||||
|
||||
// Test getting variables as IP addresses
|
||||
TEST_ASSERT_EQ(env_get_ipaddr("ipaddr", &ipaddr), 0);
|
||||
TEST_ASSERT_EQ(ipaddr, 0x64000120);
|
||||
|
||||
// Test getting a blacklisted variable fails
|
||||
TEST_ASSERT_NULL(env_get("blacklisted"));
|
||||
|
||||
// Test setting a non-persistent variable
|
||||
TEST_ASSERT_EQ(env_set("temp", "don't save me", 0), 0);
|
||||
TEST_ASSERT_STR_EQ(env_get("temp"), "don't save me");
|
||||
|
||||
// Test setting a persistent variable
|
||||
TEST_ASSERT_EQ(env_set("persist", "save this var", ENV_PERSISTENT), 0);
|
||||
TEST_ASSERT_STR_EQ(env_get("persist"), "save this var");
|
||||
|
||||
// Test env_set_uint
|
||||
TEST_ASSERT_EQ(env_set_uint("uint", 0xabcd1234, 0), 0);
|
||||
TEST_ASSERT_EQ(env_get_uint("uint", 0), 0xabcd1234);
|
||||
|
||||
// Test overwriting a persistent variable
|
||||
TEST_ASSERT_EQ(env_set("overwrite", "will not be saved", ENV_PERSISTENT), 0);
|
||||
TEST_ASSERT_STR_EQ(env_get("overwrite"), "will not be saved");
|
||||
TEST_ASSERT_EQ(env_set("overwrite", "save this value", ENV_PERSISTENT), 0);
|
||||
TEST_ASSERT_STR_EQ(env_get("overwrite"), "save this value");
|
||||
|
||||
// Test unsetting a value
|
||||
TEST_ASSERT_EQ(env_set("unset", "about to unset", ENV_PERSISTENT), 0);
|
||||
TEST_ASSERT_STR_EQ(env_get("unset"), "about to unset");
|
||||
TEST_ASSERT_EQ(env_unset("unset"), 1);
|
||||
TEST_ASSERT_NULL(env_get("unset"));
|
||||
// unsetting a non-existant variable should fail
|
||||
TEST_ASSERT_EQ(env_unset("unset"), 0);
|
||||
|
||||
// Test serializing - everything from the source should be serialized,
|
||||
// plus persistent variables set with env_set
|
||||
const uint8_t expected[] =
|
||||
"numvar=1234567890\0"
|
||||
"truevar=true\0"
|
||||
"falsevar=false\0"
|
||||
"zerovar=0\0"
|
||||
"strvar=hi mom 123=abc-_*\0"
|
||||
"ethaddr=12:34:56:78:ab:cd\0"
|
||||
"ipaddr=32.1.0.100\0"
|
||||
"blacklisted=nocando\0"
|
||||
"com.apple.System.hideme=hidden\0"
|
||||
"persist=save this var\0"
|
||||
"overwrite=save this value";
|
||||
|
||||
uint8_t *serialized = malloc(sizeof(expected) * 2);
|
||||
|
||||
TEST_ASSERT_EQ(env_serialize(serialized, sizeof(expected) * 2), sizeof(expected));
|
||||
TEST_ASSERT_MEM_EQ(serialized, expected, sizeof(expected));
|
||||
|
||||
memset(serialized, 0, sizeof(expected));
|
||||
TEST_ASSERT_EQ(env_serialize(serialized, sizeof(expected) + 1), sizeof(expected));
|
||||
TEST_ASSERT_MEM_EQ(serialized, expected, sizeof(expected));
|
||||
|
||||
// Too small buffer should fail serialization
|
||||
TEST_ASSERT_EQ(env_serialize(serialized, sizeof(expected) - 1), 0);
|
||||
}
|
||||
|
||||
void test_env_max_len_var(uintptr_t context)
|
||||
{
|
||||
int result;
|
||||
size_t serialized_len;
|
||||
const char *long_var =
|
||||
"0001020304050607"
|
||||
"08090a0b0c0d0e0f"
|
||||
"1011121314151617"
|
||||
"18191a1b1c1d1e1f"
|
||||
"2021222324252627"
|
||||
"28292a2b2c2d2e2f"
|
||||
"3031323334353637"
|
||||
"38393a3b3c3d3e3f"
|
||||
"4041424344454647"
|
||||
"48494a4b4c4d4e4f"
|
||||
"5051525354555657"
|
||||
"58595a5b5c5d5e5f"
|
||||
"6061626364656667"
|
||||
"68696a6b6c6d6e6f"
|
||||
"7071727374757677"
|
||||
"78797a7b7c7d7e_";
|
||||
|
||||
const uint8_t expected[] =
|
||||
"testvar="
|
||||
"0001020304050607"
|
||||
"08090a0b0c0d0e0f"
|
||||
"1011121314151617"
|
||||
"18191a1b1c1d1e1f"
|
||||
"2021222324252627"
|
||||
"28292a2b2c2d2e2f"
|
||||
"3031323334353637"
|
||||
"38393a3b3c3d3e3f"
|
||||
"4041424344454647"
|
||||
"48494a4b4c4d4e4f"
|
||||
"5051525354555657"
|
||||
"58595a5b5c5d5e5f"
|
||||
"6061626364656667"
|
||||
"68696a6b6c6d6e6f"
|
||||
"7071727374757677"
|
||||
"78797a7b7c7d7e_"
|
||||
"\0testvar2=abc";
|
||||
|
||||
// Setting the variable should succeed
|
||||
result = env_set("testvar", long_var, ENV_PERSISTENT);
|
||||
TEST_ASSERT_EQ(result, 0);
|
||||
|
||||
// Add a dummy variable after testvar for serialization test
|
||||
result = env_set("testvar2", "abc", ENV_PERSISTENT);
|
||||
TEST_ASSERT_EQ(result, 0);
|
||||
|
||||
// The variable should read back correctly
|
||||
TEST_ASSERT_STR_EQ(env_get("testvar"), long_var);
|
||||
|
||||
// The variable should serialize correctly
|
||||
uint8_t *serialized = malloc(sizeof(expected) * 2);
|
||||
serialized_len = env_serialize(serialized, sizeof(expected) * 2);
|
||||
TEST_ASSERT_EQ(serialized_len, sizeof(expected));
|
||||
TEST_ASSERT_MEM_EQ(serialized, expected, sizeof(expected));
|
||||
|
||||
// Clear out the environment to prepare for deserialization
|
||||
env_reset();
|
||||
|
||||
// Make sure the environment really was cleared
|
||||
TEST_ASSERT_NULL(env_get("testvar"));
|
||||
TEST_ASSERT_NULL(env_get("testvar2"));
|
||||
|
||||
// Now load the environment back in from the serialized buffer
|
||||
result = env_unserialize(serialized, serialized_len);
|
||||
TEST_ASSERT_EQ(result, 0);
|
||||
|
||||
// And make sure everything came through OK
|
||||
TEST_ASSERT_STR_EQ(env_get("testvar"), long_var);
|
||||
TEST_ASSERT_STR_EQ(env_get("testvar2"), "abc");
|
||||
}
|
||||
|
||||
bool env_blacklist(const char *name, bool write)
|
||||
{
|
||||
if (strcmp(name, "set-blacklisted") == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool env_blacklist_nvram(const char *name)
|
||||
{
|
||||
if (strcmp(name, "blacklisted") == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct test_suite env_test_suite = {
|
||||
.name = "env",
|
||||
.description = "tests the environment module",
|
||||
.setup_function = test_env_suite_setup,
|
||||
.test_cases = {
|
||||
{ "env", test_env, 0 },
|
||||
{ "env_max_len_var", test_env_max_len_var, 0 },
|
||||
TEST_CASE_LAST
|
||||
}
|
||||
};
|
||||
|
||||
TEST_SUITE(env_test_suite);
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2014 Apple Inc. All rights reserved.
|
||||
#
|
||||
# This document is the property of Apple Inc.
|
||||
# It is considered confidential and proprietary.
|
||||
#
|
||||
# This document may not be reproduced or transmitted in any form,
|
||||
# in whole or in part, without the express written permission of
|
||||
# Apple Inc.
|
||||
#
|
||||
|
||||
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||
|
||||
TEST_NAME := env
|
||||
|
||||
TEST_OBJS := \
|
||||
$(LOCAL_DIR)/env.o
|
||||
|
||||
TEST_SUPPORT_OBJS := \
|
||||
tests/unittest-main.o \
|
||||
$(LOCAL_DIR)/tests.o
|
||||
Reference in new issue
Block a user