Fix storing / regurgitating of XML fragments in dead properties.

Requires updated AWL to match.
This commit is contained in:
Andrew McMillan 2012-05-20 21:41:32 +12:00
parent 0070914394
commit b32e2cc452
4 changed files with 58 additions and 11 deletions

View File

@ -627,11 +627,37 @@ EOQRY;
$qry = new AwlQuery('SELECT property_name, property_value FROM property WHERE dav_name= :dav_name', array(':dav_name' => $this->dav_name) );
if ( $qry->Exec('DAVResource') ) {
while ( $property = $qry->Fetch() ) {
$this->dead_properties[$property->property_name] = $property->property_value;
$this->dead_properties[$property->property_name] = self::BuildDeadPropertyXML($property->property_name,$property->property_value);
}
}
}
public static function BuildDeadPropertyXML($property_name, $raw_string) {
if ( !preg_match('{^\s*<.*>\s*$}s', $raw_string) ) return $raw_string;
$xmlns = null;
if ( preg_match( '{^(.*):([^:]+)$}', $property_name, $matches) ) {
$xmlns = $matches[1];
$property_name = $matches[2];
}
$xml = sprintf('<%s%s>%s</%s>', $property_name, (isset($xmlns)?' xmlns="'.$xmlns.'"':''), $raw_string, $property_name);
$xml_parser = xml_parser_create_ns('UTF-8');
$xml_tags = array();
xml_parser_set_option ( $xml_parser, XML_OPTION_SKIP_WHITE, 1 );
xml_parser_set_option ( $xml_parser, XML_OPTION_CASE_FOLDING, 0 );
$rc = xml_parse_into_struct( $xml_parser, $xml, $xml_tags );
if ( $rc == false ) {
dbg_error_log( 'ERROR', 'XML parsing error: %s at line %d, column %d',
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser), xml_get_current_column_number($xml_parser) );
dbg_error_log( 'ERROR', "Error occurred in:\n%s\n",$xml);
return $raw_string;
}
xml_parser_free($xml_parser);
$position = 0;
$xmltree = BuildXMLTree( $xml_tags, $position);
$content = $xmltree->GetContent();
return $content[0];
}
/**
* Build permissions for this URL

View File

@ -398,7 +398,7 @@ class Principal {
$qry = new AwlQuery('SELECT property_name, property_value FROM property WHERE dav_name= :dav_name', array(':dav_name' => $this->dav_name()) );
if ( $qry->Exec('Principal') ) {
while ( $property = $qry->Fetch() ) {
$this->dead_properties[$property->property_name] = $property->property_value;
$this->dead_properties[$property->property_name] = DAVResource::BuildDeadPropertyXML($property->property_value);
}
}
}

View File

@ -65,8 +65,8 @@ if ( isset($request->xml_tags) ) {
foreach( $setprops AS $k => $setting ) {
$tag = $setting->GetNSTag();
$content = $setting->RenderContent();
$content = $setting->RenderContent(0,null,true);
dbg_error_log( 'MKCOL', 'Processing tag "%s"', $tag);
switch( $tag ) {

View File

@ -79,7 +79,7 @@ $qry->Begin();
$setcalendar = count($xmltree->GetPath('/DAV::propertyupdate/DAV::set/DAV::prop/DAV::resourcetype/urn:ietf:params:xml:ns:caldav:calendar'));
foreach( $setprops AS $k => $setting ) {
$tag = $setting->GetNSTag();
$content = $setting->RenderContent();
$content = $setting->RenderContent(0,null,true);
switch( $tag ) {
@ -113,18 +113,39 @@ foreach( $setprops AS $k => $setting ) {
* We only allow resourcetype setting on a normal collection, and not on a resource, a principal or a bind.
* Only collections may be CalDAV calendars or addressbooks, and they may not be both.
*/
$setcollection = count($setting->GetPath('DAV::resourcetype/DAV::collection'));
$setaddressbook = count($setting->GetPath('DAV::resourcetype/urn:ietf:params:xml:ns:carddav:addressbook'));
if ( $dav_resource->IsCollection() && $setcollection && ! $dav_resource->IsPrincipal()
&& ! $dav_resource->IsBinding() && ! ($setaddressbook && $setcalendar) ) {
$resourcetypes = $setting->GetPath('DAV::resourcetype/*');
$resourcetypes = str_replace( "\n", "", implode('',$resourcetypes));
$resourcetypes = $setting->GetPath('DAV::resourcetype/*');
$setcollection = false;
$setcalendar = false;
$setaddressbook = false;
$setother = false;
foreach( $resourcetypes AS $xnode ) {
switch( $xnode->GetNSTag() ) {
case 'urn:ietf:params:xml:ns:caldav:calendar': $setcalendar = true; break;
case 'urn:ietf:params:xml:ns:carddav:addressbook': $setaddressbook = true; break;
case 'DAV::collection': $setcollection = true; break;
default:
$setother = true;
}
}
if ( $dav_resource->IsCollection() && $setcollection && ! $dav_resource->IsPrincipal() && ! $dav_resource->IsBinding()
&& !($setcalendar && $setaddressbook) && !$setother ) {
$resourcetypes = '<collection xmlns="DAV:"/>';
if ( $setcalendar ) $resourcetypes .= '<calendar xmlns="urn:ietf:params:xml:ns:caldav"/>';
else if ( $setaddressbook ) $resourcetypes .= '<addressbook xmlns="urn:ietf:params:xml:ns:carddav"/>';
$qry->QDo('UPDATE collection SET is_calendar = :is_calendar::boolean, is_addressbook = :is_addressbook::boolean,
resourcetypes = :resourcetypes WHERE dav_name = :dav_name',
array( ':dav_name' => $dav_resource->dav_name(), ':resourcetypes' => $resourcetypes,
':is_calendar' => $setcalendar, ':is_addressbook' => $setaddressbook ) );
$success[$tag] = 1;
}
else if ( $setcalendar && $setaddressbook ) {
add_failure('set', $tag, 'HTTP/1.1 409 Conflict',
translate("A collection may not be both a calendar and an addressbook."));
}
else if ( $setother ) {
add_failure('set', $tag, 'HTTP/1.1 403 Forbidden',
translate("Unsupported resourcetype modification."), 'cannot-modify-protected-property');
}
else {
add_failure('set', $tag, 'HTTP/1.1 403 Forbidden',
translate("Resources may not be changed to / from collections."), 'cannot-modify-protected-property');