[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#260446: [libapt-pkg] No way to escape quotes in configuration files



Package: apt
Version: 0.5.26
Severity: minor

  The apt configuration class can't reliably be used to store and
retrieve configuration data, because it doesn't provide any mechanism
for escaping quotation marks.  In other words, storing a string like
'mail -s "the subject" foo' in a configuration file seems to be
impossible.

  A simple way of solving this is to allow quotation marks to be
escaped:

Program::MailCmd "mail -s \"the subject\" foo";

  *pokes around*

  Apparently %-escapes are already understood by libapt, so all that's
needed is to escape outgoing quotation marks...but placing %-escapes in
a configuration file manually doesn't seem to work.aaa  Ok, that only
works for tag names.  Tag values are handled by ParseCWord.

  I've attached a patch that does the following:

   - modifies LoadConfigFile to ignore backslash-escaped metacharacters.
   - modifies Dump to backslash-escape outgoing backslashes and
     quotation marks.
   - modifies ParseCWord to handle backslash-escapes.

  It seems to work in my tests here.

  Daniel

-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.6
Locale: LANG=en_US, LC_CTYPE=en_US (ignored: LC_ALL set to en_US)

Versions of packages apt depends on:
ii  libc6                       2.3.2.ds1-13 GNU C Library: Shared libraries an
ii  libgcc1                     1:3.3.4-3    GCC support library
ii  libstdc++5                  1:3.3.4-3    The GNU Standard C++ Library v3

-- no debconf information
--- /tmp/apt-0.6.25/apt-pkg/contrib/configuration.cc	2004-05-08 18:10:10.000000000 -0400
+++ apt-pkg/contrib/configuration.cc	2004-07-20 13:32:31.000000000 -0400
@@ -397,6 +397,26 @@
 
    return Exists(Name);
 }
+
+static string escape(const string &input)
+{
+  string::size_type start=0,end=input.find_first_of("\\\"");
+  string rval;
+
+  while(end!=string::npos)
+  {
+    rval+=string(input, start, end-start);
+    rval+='\\';
+    rval+=input[end];
+
+    start=end+1;
+    end=input.find_first_of("\\\"", start);
+  }
+
+  rval+=string(input, start);
+
+  return rval;
+}
 									/*}}}*/
 // Configuration::Dump - Dump the config				/*{{{*/
 // ---------------------------------------------------------------------
@@ -408,7 +428,7 @@
    const Configuration::Item *Top = Tree(0);
    for (; Top != 0;)
    {
-      str << Top->FullTag() << " \"" << Top->Value << "\";" << endl;
+      str << Top->FullTag() << " \"" << escape(Top->Value) << "\";" << endl;
       
       if (Top->Child != 0)
       {
@@ -491,8 +511,21 @@
       
       // Discard single line comments
       bool InQuote = false;
+      bool BackslashEscape = false;
       for (char *I = Buffer; *I != 0; I++)
       {
+	 if(BackslashEscape == true)
+	 {
+	    BackslashEscape=false;
+	    continue;
+	 }
+
+	 if (*I == '\\')
+	 {
+	    BackslashEscape = true;
+	    continue;
+	 }
+
 	 if (*I == '"')
 	    InQuote = !InQuote;
 	 if (InQuote == true)
@@ -507,8 +540,21 @@
 
       // Look for multi line comments
       InQuote = false;
+      BackslashEscape = false;
       for (char *I = Buffer; *I != 0; I++)
       {
+	 if (BackslashEscape == true)
+	 {
+	    BackslashEscape = false;
+	    continue;
+	 }
+
+	 if (*I == '\\')
+	 {
+	    BackslashEscape = true;
+	    continue;
+	 }
+
 	 if (*I == '"')
 	    InQuote = !InQuote;
 	 if (InQuote == true)
@@ -541,8 +587,24 @@
       
       // We now have a valid line fragment
       InQuote = false;
+      BackslashEscape = false;
       for (char *I = Buffer; *I != 0;)
       {
+	 if(BackslashEscape == true)
+	 {
+	    // Put this character into the buffer unconditionally
+	    BackslashEscape=false;
+	    ++I;
+	    continue;
+	 }
+
+	 if(*I == '\\')
+	 {
+	    BackslashEscape = true;
+	    ++I;
+	    continue;
+	 }
+
 	 if (*I == '"')
 	    InQuote = !InQuote;
 	 
--- /tmp/apt-0.6.25/apt-pkg/contrib/strutl.cc	2003-07-18 10:15:11.000000000 -0400
+++ apt-pkg/contrib/strutl.cc	2004-07-20 13:33:24.000000000 -0400
@@ -100,6 +100,8 @@
    understand [] brackets.*/
 bool ParseQuoteWord(const char *&String,string &Res)
 {
+  cout << String << endl;
+
    // Skip leading whitespace
    const char *C = String;
    for (;*C != 0 && *C == ' '; C++);
@@ -176,7 +178,12 @@
       if (*C == '"')
       {
 	 for (C++; *C != 0 && *C != '"'; C++)
+	 {
+	    if(*C=='\\' && *(C+1)!=0)
+	      ++C;
+
 	    *Buf++ = *C;
+	 }
 	 
 	 if (*C == 0)
 	    return false;

Reply to: