Index: subversion/libsvn_subr/config_file.c
===================================================================
--- subversion/libsvn_subr/config_file.c	(revision 8085)
+++ subversion/libsvn_subr/config_file.c	(working copy)
@@ -18,6 +18,7 @@
 
 
 
+#include <apr_env.h>
 #include <apr_lib.h>
 #include <apr_md5.h>
 #include "config_impl.h"
@@ -85,6 +86,73 @@
 }
 
 
+/* Expand an evironment variable encountered in a value */
+static svn_error_t *
+parse_expand_env_in_value(parse_context_t *ctx)
+{
+  svn_stringbuf_t *var_name;
+  svn_error_t *err = SVN_NO_ERROR;
+  int ch = getc (ctx->fd); /* Last ch seen was $ that started us off. */
+
+  switch(ch)
+    {
+    case '$':
+      /* Escaped $ encountered. */
+      svn_stringbuf_appendbytes (ctx->value, "$", 1);
+      break;
+
+    case '{':
+      var_name = svn_stringbuf_create("", ctx->pool);
+      
+      for (ch = getc (ctx->fd);
+           err == SVN_NO_ERROR && ch != '}';
+           ch = getc (ctx->fd))
+        {
+          char char_from_int;
+          switch(ch)
+            {
+            case '\n':
+            case EOF:
+              /* Bad environment variable: EOL or EOF found while looking
+                 for the closing brace. */
+              err = svn_error_createf (SVN_ERR_MALFORMED_FILE, NULL,
+                                       "%s:%d: Closing brace '}' not found",
+                                       ctx->file, ctx->line);
+              break;
+
+            default:
+              char_from_int = ch;
+              svn_stringbuf_appendbytes (var_name, &char_from_int, 1);
+            }
+        }
+
+      /* Dereference the environment variable, appending it to the value. */
+      if (err == SVN_NO_ERROR && !svn_stringbuf_isempty (var_name))
+        {
+          char *value;
+          if (apr_env_get (&value, var_name->data, ctx->pool) == APR_SUCCESS)
+            {
+              /* Like typical shell expansion, this means a non-existent
+                 environment variable expends to nothing. */
+              svn_stringbuf_appendcstr (ctx->value, value);
+            }
+        }
+      /* The buffer holding the env variable name is not freed since it came
+         from the pool. */
+      break;
+
+    default:
+      /* Expansion was neither ${ nor $$, so throw an error. */
+      err = svn_error_createf (SVN_ERR_MALFORMED_FILE, NULL,
+                               "%s:%d: Expected either"
+                               " '${..}' or '$$' in value",
+                               ctx->file, ctx->line);
+    }
+
+  return err;
+}
+
+
 /* Parse a single option value */
 static svn_error_t *
 parse_value (int *pch, parse_context_t *ctx)
@@ -96,17 +164,27 @@
   /* Read the first line of the value */
   svn_stringbuf_setempty (ctx->value);
   for (ch = getc (ctx->fd); /* last ch seen was ':' or '=' in parse_option. */
-       ch != EOF && ch != '\n';
+       err == SVN_NO_ERROR && ch != EOF && ch != '\n';
        ch = getc (ctx->fd))
     {
-      const char char_from_int = ch;
-      svn_stringbuf_appendbytes (ctx->value, &char_from_int, 1);
+      char char_from_int;
+      switch(ch)
+        {
+        case '$':
+          /* This indicates an environment variable needs to be expanded. */
+          err = parse_expand_env_in_value (ctx);
+          break;
+
+        default:
+          char_from_int = ch;
+          svn_stringbuf_appendbytes (ctx->value, &char_from_int, 1);
+        }
     }
   /* Leading and trailing whitespace is ignored. */
   svn_stringbuf_strip_whitespace (ctx->value);
 
   /* Look for any continuation lines. */
-  for (;;)
+  for (;err == SVN_NO_ERROR;)
     {
       if (ch == EOF || end_of_val)
         {
@@ -155,12 +233,23 @@
                   svn_stringbuf_appendbytes (ctx->value, " ", 1);
 
                   for (;
-                       ch != EOF && ch != '\n';
+                       err == SVN_NO_ERROR && ch != EOF && ch != '\n';
                        ch = getc (ctx->fd))
                     {
-                      const char char_from_int = ch;
-                      svn_stringbuf_appendbytes (ctx->value,
-                                                 &char_from_int, 1);
+                      char char_from_int;
+                      switch(ch)
+                        {
+                        case '$':
+                          /* This indicates an environment variable needs
+                             to be expanded. */
+                          err = parse_expand_env_in_value (ctx);
+                          break;
+
+                        default:
+                          char_from_int = ch;
+                          svn_stringbuf_appendbytes (ctx->value,
+                                                     &char_from_int, 1);
+                        }
                     }
                   /* Trailing whitespace is ignored. */
                   svn_stringbuf_strip_whitespace (ctx->value);


