PEAR is discontinued

This is a static archive preserving historical releases and metadata. No new packages or updates will be published. For updates to existing packages, or to publish new packages, please use Composer and Packagist.

Home » Internationalization » Translation2 » Bug #3420

XML Container lacks shared lock

Details

Submitted2005-02-09 22:49 UTC
Fromylf at xung dot org
Assignedquipo
StatusClosed
PackageTranslation2
PHP Version4.3.4
OSLinux Debian
Roadmaps(Not assigned)

Comments

[2005-02-09 22:49 UTC] ylf at xung dot org

Description:
------------
Hi,

Translation2 version : 2.0.0beta6

AFAIK, flock() provides _advisory_ locks. In Translation2/Admin/Container/xml.php, line 340, you state :

@flock($f, LOCK_EX);
fwrite ($f, $xml);
@flock($f, LOCK_UN);
fclose ($f);

Sidenote: @flock ($f,LOCK_UN) is useless, fclose() unlocks the file.

An "exclusive" (LOCK_EX) advisory lock does not forbid other processes to read from the file. These processes need to explicitly acquire a shared lock.

From the flock Linux manpage :
"flock(2) places advisory locks only; given suitable permissions on a file, a process is free to ignore the use of flock(2) and perform I/O on the file."

In our case it means that you correctly acquire an exclusive lock when writing to the xml file, but you forget to acquire a shared lock when reading.

Consequence : the lock is ignored by reading processes. The call to flock($f,LOCK_EX) should protect the file from getting corrupted, but there are chances to read junk from it.

You should turn, in Container/xml.php, line 137 :

$unserializer = &new XML_Unserializer (array('keyAttribute' => $keyAttr));
if (PEAR::isError($status = $unserializer->unserialize($this->_filename, true))) {
return $status;
}

into :

if (!$fp = @fopen ($this->_filename, 'r')) {
return new PEAR_Error ("Can\'t read from the XML source : {$this->_filename}");
}
@flock ($fp, LOCK_SH);
$unserializer = &new XML_Unserializer (array('keyAttribute' => $keyAttr));
if (PEAR::isError($status = $unserializer->unserialize($this->_filename, true))) {
fclose ($fp);
return $status;
}
fclose($fp);

Cheers