mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-04 00:51:42 +01:00 
			
		
		
		
	
		
			
	
	
		
			89 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			89 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#include <stdlib.h>
							 | 
						||
| 
								 | 
							
								#include <string.h>
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#include <assert.h>
							 | 
						||
| 
								 | 
							
								#include <ctype.h>
							 | 
						||
| 
								 | 
							
								#include <stdbool.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "expand_env.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static bool allowed_env_var_name(char c)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  return c != '\0' &&
							 | 
						||
| 
								 | 
							
								    !isblank(c) &&
							 | 
						||
| 
								 | 
							
								    !iscntrl(c) &&
							 | 
						||
| 
								 | 
							
								    c != '/' &&
							 | 
						||
| 
								 | 
							
								    c != '\\' &&
							 | 
						||
| 
								 | 
							
								    c != '=' &&
							 | 
						||
| 
								 | 
							
								    c != '$';
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define MAX_LEN (128 * 1024) /* Longest a result can expand to */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Very basic expansion that looks for variable references like $NAME and expands them
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								char *expand_environment(const char *input, const char *src_name, int src_line_no)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  char *result = malloc(MAX_LEN);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  char *out = result;
							 | 
						||
| 
								 | 
							
								  const char *in = input;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  while (*in != '\0') {
							 | 
						||
| 
								 | 
							
								    // check for buffer overflow
							 | 
						||
| 
								 | 
							
								    if (out >= result + MAX_LEN - 1) {
							 | 
						||
| 
								 | 
							
								      goto too_long;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (*in != '$') {
							 | 
						||
| 
								 | 
							
								      // not part of an environment variable name, copy directly
							 | 
						||
| 
								 | 
							
								      *out++ = *in++;
							 | 
						||
| 
								 | 
							
								      continue;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // *in points to start of an environment variable reference
							 | 
						||
| 
								 | 
							
								    in++;
							 | 
						||
| 
								 | 
							
								    const char *env_start = in;
							 | 
						||
| 
								 | 
							
								    while (allowed_env_var_name(*in)) { // scan to the end of the name
							 | 
						||
| 
								 | 
							
								      in++;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    size_t env_len = in - env_start;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // make a buffer to hold the environment variable name
							 | 
						||
| 
								 | 
							
								    //
							 | 
						||
| 
								 | 
							
								    // strndup is not available on mingw32, apparently.
							 | 
						||
| 
								 | 
							
								    char *env_name = calloc(1, env_len + 1);
							 | 
						||
| 
								 | 
							
								    assert(env_name != NULL);
							 | 
						||
| 
								 | 
							
								    strncpy(env_name, env_start, env_len);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const char *value = getenv(env_name);
							 | 
						||
| 
								 | 
							
								    if (value == NULL || strlen(value) == 0) {
							 | 
						||
| 
								 | 
							
								      printf("%s:%d: undefined environment variable \"%s\"\n",
							 | 
						||
| 
								 | 
							
								             src_name, src_line_no, env_name);
							 | 
						||
| 
								 | 
							
								      exit(1);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    free(env_name);
							 | 
						||
| 
								 | 
							
								    if (out + strlen(value) >= result + MAX_LEN - 1) {
							 | 
						||
| 
								 | 
							
								      goto too_long;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    strcpy(out, value); // append the value to the result (range checked in previous statement)
							 | 
						||
| 
								 | 
							
								    out += strlen(value);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  *out = '\0'; // null terminate the result string
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return result;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								too_long:
							 | 
						||
| 
								 | 
							
								  printf("%s:%d: Expansion is longer than %d bytes\n",
							 | 
						||
| 
								 | 
							
								         src_name, src_line_no, MAX_LEN);
							 | 
						||
| 
								 | 
							
								  free(result);
							 | 
						||
| 
								 | 
							
								  exit(1);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void free_expanded(char *expanded)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  free(expanded);
							 | 
						||
| 
								 | 
							
								}
							 |