Просмотр исходного кода

normalize a bit by replacing // and /./ with / in FindFile

David Kalnischkies лет назад: 14
Родитель
Сommit
ec76891fa1
3 измененных файлов с 53 добавлено и 31 удалено
  1. 38 30
      apt-pkg/contrib/configuration.cc
  2. 2 1
      debian/changelog
  3. 13 0
      test/libapt/configuration_test.cc

+ 38 - 30
apt-pkg/contrib/configuration.cc

@@ -171,48 +171,56 @@ string Configuration::Find(const char *Name,const char *Default) const
 string Configuration::FindFile(const char *Name,const char *Default) const
 {
    const Item *RootItem = Lookup("RootDir");
-   std::string rootDir =  (RootItem == 0) ? "" : RootItem->Value;
-   if(rootDir.size() > 0 && rootDir[rootDir.size() - 1] != '/')
-     rootDir.push_back('/');
+   std::string result =  (RootItem == 0) ? "" : RootItem->Value;
+   if(result.empty() == false && result[result.size() - 1] != '/')
+     result.push_back('/');
 
    const Item *Itm = Lookup(Name);
    if (Itm == 0 || Itm->Value.empty() == true)
    {
-      if (Default == 0)
-	 return rootDir;
-      else
-	 return rootDir + Default;
+      if (Default != 0)
+	 result.append(Default);
    }
-   
-   string val = Itm->Value;
-   while (Itm->Parent != 0)
+   else
    {
-      if (Itm->Parent->Value.empty() == true)
+      string val = Itm->Value;
+      while (Itm->Parent != 0)
       {
-	 Itm = Itm->Parent;
-	 continue;
-      }
+	 if (Itm->Parent->Value.empty() == true)
+	 {
+	    Itm = Itm->Parent;
+	    continue;
+	 }
 
-      // Absolute
-      if (val.length() >= 1 && val[0] == '/')
-         break;
+	 // Absolute
+	 if (val.length() >= 1 && val[0] == '/')
+	    break;
 
-      // ~/foo or ./foo 
-      if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
-	 break;
-	 
-      // ../foo 
-      if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
-	 break;
-      
-      if (Itm->Parent->Value.end()[-1] != '/')
-	 val.insert(0, "/");
+	 // ~/foo or ./foo
+	 if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
+	    break;
+
+	 // ../foo
+	 if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
+	    break;
+
+	 if (Itm->Parent->Value.end()[-1] != '/')
+	    val.insert(0, "/");
 
-      val.insert(0, Itm->Parent->Value);
-      Itm = Itm->Parent;
+	 val.insert(0, Itm->Parent->Value);
+	 Itm = Itm->Parent;
+      }
+      result.append(val);
    }
 
-   return rootDir + val;
+   // do some normalisation by removing // and /./ from the path
+   size_t found = string::npos;
+   while ((found = result.find("/./")) != string::npos)
+      result.replace(found, 3, "/");
+   while ((found = result.find("//")) != string::npos)
+      result.replace(found, 2, "/");
+
+   return result;
 }
 									/*}}}*/
 // Configuration::FindDir - Find a directory name			/*{{{*/

+ 2 - 1
debian/changelog

@@ -5,6 +5,7 @@ apt (0.9.3) unstable; urgency=low
     - remove the message size limit from ioprintf and strprintf
   * apt-pkg/contrib/configuration.cc:
     - add a more versatile Dump() method
+    - normalize a bit by replacing // and /./ with / in FindFile
   * apt-pkg/acquire-worker.cc:
     - use Dump() to generate the configuration message for sending
   * cmdline/apt-config.cc:
@@ -20,7 +21,7 @@ apt (0.9.3) unstable; urgency=low
     - check with RealFileExists for scenario file as otherwise a directory
       like one provided with RootDir triggers the usage of EDSP
 
- -- David Kalnischkies <kalnischkies@gmail.com>  Mon, 23 Apr 2012 18:23:10 +0200
+ -- David Kalnischkies <kalnischkies@gmail.com>  Mon, 23 Apr 2012 19:10:13 +0200
 
 apt (0.9.2) unstable; urgency=low
 

+ 13 - 0
test/libapt/configuration_test.cc

@@ -80,6 +80,19 @@ int main(int argc,const char *argv[]) {
 	equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
 	equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
 
+	Cnf.Set("RootDir", "/");
+	equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
+	equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
+	Cnf.Set("RootDir", "//./////.////");
+	equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
+	equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
+	Cnf.Set("RootDir", "/rootdir");
+	equals(Cnf.FindFile("Dir::State"), "/rootdir/srv/sid/var/lib/apt");
+	equals(Cnf.FindFile("Dir::Aptitude::State"), "/rootdir/srv/sid/var/lib/aptitude");
+	Cnf.Set("RootDir", "/rootdir/");
+	equals(Cnf.FindFile("Dir::State"), "/rootdir/srv/sid/var/lib/apt");
+	equals(Cnf.FindFile("Dir::Aptitude::State"), "/rootdir/srv/sid/var/lib/aptitude");
+
 	//FIXME: Test for configuration file parsing;
 	// currently only integration/ tests test them implicitly