Преглед на файлове

* apt-pkg/contrib/fileutl.cc:
- add a RealFileExists method and check that your configuration files
are real files to avoid endless loops if not (Closes: #604401)

David Kalnischkies преди 15 години
родител
ревизия
36f1098aed

+ 19 - 1
apt-pkg/contrib/fileutl.cc

@@ -191,7 +191,7 @@ int GetLock(string File,bool Errors)
 									/*}}}*/
 // FileExists - Check if a file exists					/*{{{*/
 // ---------------------------------------------------------------------
-/* */
+/* Beware: Directories are also files! */
 bool FileExists(string File)
 {
    struct stat Buf;
@@ -200,6 +200,17 @@ bool FileExists(string File)
    return true;
 }
 									/*}}}*/
+// RealFileExists - Check if a file exists and if it is really a file	/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool RealFileExists(string File)
+{
+   struct stat Buf;
+   if (stat(File.c_str(),&Buf) != 0)
+      return false;
+   return ((Buf.st_mode & S_IFREG) != 0);
+}
+									/*}}}*/
 // DirectoryExists - Check if a directory exists and is really one	/*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -304,6 +315,13 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
    }
 
    std::vector<string> List;
+
+   if (DirectoryExists(Dir.c_str()) == false)
+   {
+      _error->Error(_("List of files can't be created as '%s' is not a directory"), Dir.c_str());
+      return List;
+   }
+
    Configuration::MatchAgainstConfig SilentIgnore("Dir::Ignore-Files-Silently");
    DIR *D = opendir(Dir.c_str());
    if (D == 0) 

+ 1 - 0
apt-pkg/contrib/fileutl.h

@@ -93,6 +93,7 @@ bool RunScripts(const char *Cnf);
 bool CopyFile(FileFd &From,FileFd &To);
 int GetLock(string File,bool Errors = true);
 bool FileExists(string File);
+bool RealFileExists(string File);
 bool DirectoryExists(string const &Path) __attrib_const;
 bool CreateDirectory(string const &Parent, string const &Path);
 

+ 2 - 2
apt-pkg/depcache.cc

@@ -167,7 +167,7 @@ bool pkgDepCache::readStateFile(OpProgress *Prog)			/*{{{*/
 {
    FileFd state_file;
    string const state = _config->FindFile("Dir::State::extended_states");
-   if(FileExists(state)) {
+   if(RealFileExists(state)) {
       state_file.Open(state, FileFd::ReadOnly);
       int const file_size = state_file.Size();
       if(Prog != NULL)
@@ -226,7 +226,7 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly)	/*{{{*/
    string const state = _config->FindFile("Dir::State::extended_states");
 
    // if it does not exist, create a empty one
-   if(!FileExists(state)) 
+   if(!RealFileExists(state)) 
    {
       StateFile.Open(state, FileFd::WriteAtomic);
       StateFile.Close();

+ 3 - 3
apt-pkg/init.cc

@@ -94,10 +94,10 @@ bool pkgInitConfig(Configuration &Cnf)
    const char *Cfg = getenv("APT_CONFIG");
    if (Cfg != 0)
    {
-      if (FileExists(Cfg) == true)
+      if (RealFileExists(Cfg) == true)
 	 Res &= ReadConfigFile(Cnf,Cfg);
       else
-	 _error->WarningE("FileExists",_("Unable to read %s"),Cfg);
+	 _error->WarningE("RealFileExists",_("Unable to read %s"),Cfg);
    }
 
    // Read the configuration parts dir
@@ -109,7 +109,7 @@ bool pkgInitConfig(Configuration &Cnf)
 
    // Read the main config file
    string FName = Cnf.FindFile("Dir::Etc::main");
-   if (FileExists(FName) == true)
+   if (RealFileExists(FName) == true)
       Res &= ReadConfigFile(Cnf,FName);
 
    if (Res == false)

+ 1 - 1
apt-pkg/policy.cc

@@ -328,7 +328,7 @@ bool ReadPinFile(pkgPolicy &Plcy,string File)
    if (File.empty() == true)
       File = _config->FindFile("Dir::Etc::Preferences");
 
-   if (FileExists(File) == false)
+   if (RealFileExists(File) == false)
       return true;
    
    FileFd Fd(File,FileFd::ReadOnly);

+ 3 - 3
apt-pkg/sourcelist.cc

@@ -197,7 +197,7 @@ bool pkgSourceList::ReadMainList()
    string Main = _config->FindFile("Dir::Etc::sourcelist");
    string Parts = _config->FindDir("Dir::Etc::sourceparts");
    
-   if (FileExists(Main) == true)
+   if (RealFileExists(Main) == true)
       Res &= ReadAppend(Main);
    else if (DirectoryExists(Parts) == false)
       // Only warn if there are no sources.list.d.
@@ -205,9 +205,9 @@ bool pkgSourceList::ReadMainList()
 
    if (DirectoryExists(Parts) == true)
       Res &= ReadSourceDir(Parts);
-   else if (FileExists(Main) == false)
+   else if (RealFileExists(Main) == false)
       // Only warn if there is no sources.list file.
-      _error->WarningE("FileExists", _("Unable to read %s"), Main.c_str());
+      _error->WarningE("RealFileExists", _("Unable to read %s"), Main.c_str());
 
    return Res;
 }

+ 2 - 2
apt-pkg/vendorlist.cc

@@ -21,11 +21,11 @@ bool pkgVendorList::ReadMainList()
    Configuration Cnf;
 
    string CnfFile = _config->FindDir("Dir::Etc::vendorparts");
-   if (FileExists(CnfFile) == true)
+   if (DirectoryExists(CnfFile) == true)
       if (ReadConfigDir(Cnf,CnfFile,true) == false)
 	 return false;
    CnfFile = _config->FindFile("Dir::Etc::vendorlist");
-   if (FileExists(CnfFile) == true)
+   if (RealFileExists(CnfFile) == true)
       if (ReadConfigFile(Cnf,CnfFile,true) == false)
 	 return false;
 

+ 4 - 1
debian/changelog

@@ -17,8 +17,11 @@ apt (0.8.11+wheezy) unstable; urgency=low
       requested on the commandline, e.g. with a modifier
   * debian/control:
     - add Vcs-Browser now that loggerhead works again (Closes: #511168)
+  * apt-pkg/contrib/fileutl.cc:
+    - add a RealFileExists method and check that your configuration files
+      are real files to avoid endless loops if not (Closes: #604401)
 
- -- David Kalnischkies <kalnischkies@gmail.com>  Fri, 03 Dec 2010 17:30:52 +0100
+ -- David Kalnischkies <kalnischkies@gmail.com>  Wed, 12 Jan 2011 16:53:41 +0100
 
 apt (0.8.10) unstable; urgency=low
 

+ 66 - 0
test/integration/test-bug-604401-files-are-directories

@@ -0,0 +1,66 @@
+#!/bin/sh
+set -e
+
+local TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture "i386"
+setupaptarchive
+
+test ! -e rootdir/etc/apt/apt.conf || mv rootdir/etc/apt/apt.conf rootdir/etc/apt/apt.conf.d/000move-away-apt.conf
+
+msgtest "Directory instead of a file as apt.conf ignored"
+mkdir -p rootdir/etc/apt/apt.conf
+aptconfig dump > /dev/null && msgpass || msgfail
+rmdir rootdir/etc/apt/apt.conf
+
+msgtest "Good link instead of a file as apt.conf ignored"
+echo 'Test::APT::Link "good";' > rootdir/etc/apt/good-link.conf
+ln -s rootdir/etc/apt/good-link.conf rootdir/etc/apt/apt.conf
+test -n "$(aptconfig shell TestLink 'Test::APT::Link')" && msgfail || msgpass
+rm rootdir/etc/apt/apt.conf
+
+msgtest "Broken link instead of a file as apt.conf ignored"
+ln -s /tmp/doesnt-exist rootdir/etc/apt/apt.conf
+aptconfig dump > /dev/null && msgpass || msgfail
+rm rootdir/etc/apt/apt.conf
+
+
+test ! -e rootdir/etc/apt/sources.list || mv rootdir/etc/apt/sources.list rootdir/etc/apt/sources.list.d/000move-away-sources.list
+
+msgtest "Directory instead of a file as sources.list ignored"
+mkdir -p rootdir/etc/apt/sources.list
+aptget update --print-uris 2> /dev/null && msgpass || msgfail
+rmdir rootdir/etc/apt/sources.list
+
+msgtest "Good link instead of a file as sources.list ignored"
+echo 'deb file:///tmp/debian sid main' > rootdir/etc/apt/good-link.list
+ln -s rootdir/etc/apt/good-link.list rootdir/etc/apt/sources.list
+test -n "$(aptget update --print-uris)" && msgfail || msgpass
+rm rootdir/etc/apt/sources.list
+
+msgtest "Broken link instead of a file as sources.list ignored"
+ln -s /tmp/doesnt-exist rootdir/etc/apt/sources.list
+test -n "$(aptget update --print-uris)" && msgfail || msgpass
+rm rootdir/etc/apt/sources.list
+
+
+test ! -e rootdir/etc/apt/preferences || mv rootdir/etc/apt/preferences rootdir/etc/apt/preferences.d/000move-away-preferences
+
+msgtest "Directory instead of a file as preferences ignored"
+mkdir -p rootdir/etc/apt/preferences
+aptcache policy > /dev/null 2> /dev/null && msgpass || msgfail
+rmdir rootdir/etc/apt/preferences
+
+msgtest "Good link instead of a file as preferences ignored"
+echo 'Package: apt
+Pin: release a=now
+Pin-Value: 1000' > rootdir/etc/apt/good-link.pref
+ln -s rootdir/etc/apt/good-link.pref rootdir/etc/apt/preferences
+test -n "$(aptcache policy | grep 1000)" && msgfail || msgpass
+rm rootdir/etc/apt/preferences
+
+msgtest "Broken link instead of a file as preferences ignored"
+ln -s /tmp/doesnt-exist rootdir/etc/apt/preferences
+aptcache policy > /dev/null 2> /dev/null && msgpass || msgfail
+rm rootdir/etc/apt/preferences