diff options
author | Christopher Smith <chris@jalakai.co.uk> | 2011-02-06 15:21:22 +0000 |
---|---|---|
committer | Christopher Smith <chris@jalakai.co.uk> | 2011-02-06 15:21:22 +0000 |
commit | b842a02804e6c492963978620e61739485b7287f (patch) | |
tree | 00995d07d0c146bbba38a72fa6086547db949080 /inc | |
parent | 3893df8e5068f411ba16c2e37096e47c4ad102f2 (diff) | |
parent | 26497271fdd53b972af0b3a4411b6ce41a0629c0 (diff) | |
download | rpg-b842a02804e6c492963978620e61739485b7287f.tar.gz rpg-b842a02804e6c492963978620e61739485b7287f.tar.bz2 |
Merge branch 'master' of git@github.com:splitbrain/dokuwiki
Diffstat (limited to 'inc')
-rw-r--r-- | inc/EmailAddressValidator.php | 31 | ||||
-rw-r--r-- | inc/HTTPClient.php | 27 | ||||
-rw-r--r-- | inc/common.php | 2 | ||||
-rw-r--r-- | inc/html.php | 8 | ||||
-rw-r--r-- | inc/media.php | 150 | ||||
-rw-r--r-- | inc/parserutils.php | 48 |
6 files changed, 178 insertions, 88 deletions
diff --git a/inc/EmailAddressValidator.php b/inc/EmailAddressValidator.php index 31b34cc58..bb4ef0ca9 100644 --- a/inc/EmailAddressValidator.php +++ b/inc/EmailAddressValidator.php @@ -5,7 +5,7 @@ * @author Dave Child <dave@addedbytes.com> * @link http://code.google.com/p/php-email-address-validation/ * @license http://www.opensource.org/licenses/bsd-license.php - * @version SVN r10 + Issue 15 fix + * @version SVN r10 + Issue 15 fix + Issue 12 fix */ class EmailAddressValidator { /** @@ -121,13 +121,30 @@ class EmailAddressValidator { if (!$this->check_text_length($strDomainPortion, 1, 255)) { return false; } + + // some IPv4/v6 regexps borrowed from Feyd + // see: http://forums.devnetwork.net/viewtopic.php?f=38&t=53479 + $dec_octet = '(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|[0-9])'; + $hex_digit = '[A-Fa-f0-9]'; + $h16 = "{$hex_digit}{1,4}"; + $IPv4Address = "$dec_octet\\.$dec_octet\\.$dec_octet\\.$dec_octet"; + $ls32 = "(?:$h16:$h16|$IPv4Address)"; + $IPv6Address = + "(?:(?:{$IPv4Address})|(?:". + "(?:$h16:){6}$ls32" . + "|::(?:$h16:){5}$ls32" . + "|(?:$h16)?::(?:$h16:){4}$ls32" . + "|(?:(?:$h16:){0,1}$h16)?::(?:$h16:){3}$ls32" . + "|(?:(?:$h16:){0,2}$h16)?::(?:$h16:){2}$ls32" . + "|(?:(?:$h16:){0,3}$h16)?::(?:$h16:){1}$ls32" . + "|(?:(?:$h16:){0,4}$h16)?::$ls32" . + "|(?:(?:$h16:){0,5}$h16)?::$h16" . + "|(?:(?:$h16:){0,6}$h16)?::" . + ")(?:\\/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))?)"; + // Check if domain is IP, possibly enclosed in square brackets. - if (preg_match('/^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])' - .'(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}$/' - ,$strDomainPortion) || - preg_match('/^\[(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])' - .'(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\]$/' - ,$strDomainPortion)) { + if (preg_match("/^($IPv4Address|\[$IPv4Address\]|\[$IPv6Address\])$/", + $strDomainPortion)){ return true; } else { $arrDomainPortion = explode('.', $strDomainPortion); diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php index 1cb16714d..372769b71 100644 --- a/inc/HTTPClient.php +++ b/inc/HTTPClient.php @@ -299,8 +299,6 @@ class HTTPClient { $this->error = "Could not connect to $server:$port\n$errstr ($errno)"; return false; } - //set non blocking - stream_set_blocking($socket,0); // keep alive? if ($this->keep_alive) { @@ -310,6 +308,9 @@ class HTTPClient { } } + //set blocking + stream_set_blocking($socket,1); + // build request $request = "$method $request_url HTTP/".$this->http.HTTP_NL; $request .= $this->_buildHeaders($headers); @@ -319,11 +320,28 @@ class HTTPClient { $this->_debug('request',$request); + // select parameters + $sel_r = null; + $sel_w = array($socket); + $sel_e = null; + // send request $towrite = strlen($request); $written = 0; while($written < $towrite){ - $ret = fwrite($socket, substr($request,$written)); + // check timeout + if(time()-$start > $this->timeout){ + $this->status = -100; + $this->error = sprintf('Timeout while sending request (%.3fs)',$this->_time() - $this->start); + unset($this->connections[$connectionId]); + return false; + } + + // wait for stream ready or timeout (1sec) + if(stream_select($sel_r,$sel_w,$sel_e,1) === false) continue; + + // write to stream + $ret = fwrite($socket, substr($request,$written,4096)); if($ret === false){ $this->status = -100; $this->error = 'Failed writing to socket'; @@ -333,6 +351,9 @@ class HTTPClient { $written += $ret; } + // continue non-blocking + stream_set_blocking($socket,0); + // read headers from socket $r_headers = ''; do{ diff --git a/inc/common.php b/inc/common.php index eab5f1129..23d9c7155 100644 --- a/inc/common.php +++ b/inc/common.php @@ -639,7 +639,7 @@ function clientIP($single=false){ // decide which IP to use, trying to avoid local addresses $ip = array_reverse($ip); foreach($ip as $i){ - if(preg_match('/^(127\.|10\.|192\.168\.|172\.((1[6-9])|(2[0-9])|(3[0-1]))\.)/',$i)){ + if(preg_match('/^(::1|[fF][eE]80:|127\.|10\.|192\.168\.|172\.((1[6-9])|(2[0-9])|(3[0-1]))\.)/',$i)){ continue; }else{ return $i; diff --git a/inc/html.php b/inc/html.php index 4d5d557af..3afa4862f 100644 --- a/inc/html.php +++ b/inc/html.php @@ -1440,10 +1440,10 @@ function html_admin(){ } // data security check - echo '<a style="background: transparent url(data/security.png) left top no-repeat; - display: block; width:380px; height:73px; border:none; float:right" - target="_blank" - href="http://www.dokuwiki.org/security#web_access_security"></a>'; + // @todo: could be checked and only displayed if $conf['savedir'] is under the web root + echo '<a style="border:none; float:right;" target="_blank" + href="http://www.dokuwiki.org/security#web_access_security"> + <img src="data/security.png" alt="Broken image? Everything\'s alright!" /></a>'; print p_locale_xhtml('admin'); diff --git a/inc/media.php b/inc/media.php index 69441352b..3c9340d51 100644 --- a/inc/media.php +++ b/inc/media.php @@ -141,7 +141,7 @@ function media_metaform($id,$auth){ } /** - * Conveinience function to check if a media file is still in use + * Convenience function to check if a media file is still in use * * @author Michael Klier <chi@chimeric.de> */ @@ -160,19 +160,26 @@ function media_inuse($id) { } } +define('DOKU_MEDIA_DELETED', 1); +define('DOKU_MEDIA_NOT_AUTH', 2); +define('DOKU_MEDIA_INUSE', 4); +define('DOKU_MEDIA_EMPTY_NS', 8); + /** * Handles media file deletions * * If configured, checks for media references before deletion * * @author Andreas Gohr <andi@splitbrain.org> - * @return mixed false on error, true on delete or array with refs + * @return int One of: 0, + DOKU_MEDIA_DELETED, + DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS, + DOKU_MEDIA_NOT_AUTH, + DOKU_MEDIA_INUSE */ function media_delete($id,$auth){ - if($auth < AUTH_DELETE) return false; - if(!checkSecurityToken()) return false; - global $conf; - global $lang; + if($auth < AUTH_DELETE) return DOKU_MEDIA_NOT_AUTH; + if(media_inuse($id)) return DOKU_MEDIA_INUSE; $file = mediaFN($id); @@ -196,38 +203,22 @@ function media_delete($id,$auth){ unset($evt); if($data['unl'] && $data['del']){ - // current namespace was removed. redirecting to root ns passing msg along - send_redirect(DOKU_URL.'lib/exe/mediamanager.php?msg1='. - rawurlencode(sprintf(noNS($id),$lang['deletesucc']))); + return DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS; } - return $data['unl']; + return $data['unl'] ? DOKU_MEDIA_DELETED : 0; } /** * Handles media file uploads * - * This generates an action event and delegates to _media_upload_action(). - * Action plugins are allowed to pre/postprocess the uploaded file. - * (The triggered event is preventable.) - * - * Event data: - * $data[0] fn_tmp: the temporary file name (read from $_FILES) - * $data[1] fn: the file name of the uploaded file - * $data[2] id: the future directory id of the uploaded file - * $data[3] imime: the mimetype of the uploaded file - * $data[4] overwrite: if an existing file is going to be overwritten - * - * @triggers MEDIA_UPLOAD_FINISH * @author Andreas Gohr <andi@splitbrain.org> * @author Michael Klier <chi@chimeric.de> * @return mixed false on error, id of the new file on success */ function media_upload($ns,$auth){ - if($auth < AUTH_UPLOAD) return false; if(!checkSecurityToken()) return false; global $lang; - global $conf; // get file and id $id = $_POST['id']; @@ -249,8 +240,50 @@ function media_upload($ns,$auth){ msg(sprintf($lang['mediaextchange'],$fext,$iext)); } + $res = media_save(array('name' => $file['tmp_name'], + 'mime' => $imime, + 'ext' => $iext), $ns.':'.$id, + $_REQUEST['ow'], $auth, 'move_uploaded_file'); + if (is_array($res)) { + msg($res[0], $res[1]); + return false; + } + return $res; +} + +/** + * This generates an action event and delegates to _media_upload_action(). + * Action plugins are allowed to pre/postprocess the uploaded file. + * (The triggered event is preventable.) + * + * Event data: + * $data[0] fn_tmp: the temporary file name (read from $_FILES) + * $data[1] fn: the file name of the uploaded file + * $data[2] id: the future directory id of the uploaded file + * $data[3] imime: the mimetype of the uploaded file + * $data[4] overwrite: if an existing file is going to be overwritten + * + * @triggers MEDIA_UPLOAD_FINISH + */ +function media_save($file, $id, $ow, $auth, $move) { + if($auth < AUTH_UPLOAD) { + return array("You don't have permissions to upload files.", -1); + } + + if (!isset($file['mime']) || !isset($file['ext'])) { + list($ext, $mime) = mimetype($id); + if (!isset($file['mime'])) { + $file['mime'] = $mime; + } + if (!isset($file['ext'])) { + $file['ext'] = $ext; + } + } + + global $lang; + // get filename - $id = cleanID($ns.':'.$id,false,true); + $id = cleanID($id,false,true); $fn = mediaFN($id); // get filetype regexp @@ -259,40 +292,35 @@ function media_upload($ns,$auth){ $regex = join('|',$types); // because a temp file was created already - if(preg_match('/\.('.$regex.')$/i',$fn)){ - //check for overwrite - $overwrite = @file_exists($fn); - if($overwrite && (!$_REQUEST['ow'] || $auth < AUTH_DELETE)){ - msg($lang['uploadexist'],0); - return false; - } - // check for valid content - $ok = media_contentcheck($file['tmp_name'],$imime); - if($ok == -1){ - msg(sprintf($lang['uploadbadcontent'],".$iext"),-1); - return false; - }elseif($ok == -2){ - msg($lang['uploadspam'],-1); - return false; - }elseif($ok == -3){ - msg($lang['uploadxss'],-1); - return false; - } + if(!preg_match('/\.('.$regex.')$/i',$fn)) { + return array($lang['uploadwrong'],-1); + } - // prepare event data - $data[0] = $file['tmp_name']; - $data[1] = $fn; - $data[2] = $id; - $data[3] = $imime; - $data[4] = $overwrite; + //check for overwrite + $overwrite = @file_exists($fn); + if($overwrite && (!$ow || $auth < AUTH_DELETE)) { + return array($lang['uploadexist'], 0); + } + // check for valid content + $ok = media_contentcheck($file['name'], $file['mime']); + if($ok == -1){ + return array(sprintf($lang['uploadbadcontent'],'.' . $file['ext']),-1); + }elseif($ok == -2){ + return array($lang['uploadspam'],-1); + }elseif($ok == -3){ + return array($lang['uploadxss'],-1); + } - // trigger event - return trigger_event('MEDIA_UPLOAD_FINISH', $data, '_media_upload_action', true); + // prepare event data + $data[0] = $file['name']; + $data[1] = $fn; + $data[2] = $id; + $data[3] = $file['mime']; + $data[4] = $overwrite; + $data[5] = $move; - }else{ - msg($lang['uploadwrong'],-1); - } - return false; + // trigger event + return trigger_event('MEDIA_UPLOAD_FINISH', $data, '_media_upload_action', true); } /** @@ -301,8 +329,8 @@ function media_upload($ns,$auth){ */ function _media_upload_action($data) { // fixme do further sanity tests of given data? - if(is_array($data) && count($data)===5) { - return media_upload_finish($data[0], $data[1], $data[2], $data[3], $data[4]); + if(is_array($data) && count($data)===6) { + return media_upload_finish($data[0], $data[1], $data[2], $data[3], $data[4], $data[5]); } else { return false; //callback error } @@ -314,14 +342,14 @@ function _media_upload_action($data) { * @author Andreas Gohr <andi@splitbrain.org> * @author Michael Klier <chi@chimeric.de> */ -function media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite) { +function media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite, $move = 'move_uploaded_file') { global $conf; global $lang; // prepare directory io_createNamespace($id, 'media'); - if(move_uploaded_file($fn_tmp, $fn)) { + if($move($fn_tmp, $fn)) { // Set the correct permission here. // Always chmod media because they may be saved with different permissions than expected from the php umask. // (Should normally chmod to $conf['fperm'] only if $conf['fperm'] is set.) @@ -336,7 +364,7 @@ function media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite) { } return $id; }else{ - msg($lang['uploadfail'],-1); + return array($lang['uploadfail'],-1); } } diff --git a/inc/parserutils.php b/inc/parserutils.php index 6e349e984..9b2d99328 100644 --- a/inc/parserutils.php +++ b/inc/parserutils.php @@ -258,7 +258,7 @@ function p_get_metadata($id, $key='', $render=true){ if ($meta == $old_meta || p_save_metadata($id, $meta)) { // store a timestamp in order to make sure that the cachefile is touched $cachefile->storeCache(time()); - } else { + } elseif ($meta != $old_meta) { msg('Unable to save metadata file. Hint: disk full; file permissions; safe_mode setting.',-1); } } @@ -291,18 +291,25 @@ function p_get_metadata($id, $key='', $render=true){ * @return boolean true on success * * @author Esther Brunner <esther@kaffeehaus.ch> + * @author Michael Hamann <michael@content-space.de> */ function p_set_metadata($id, $data, $render=false, $persistent=true){ if (!is_array($data)) return false; - global $ID; + global $ID, $METADATA_RENDERERS; - // cache the current page - $cache = ($ID == $id); - $orig = p_read_metadata($id, $cache); + // if there is currently a renderer change the data in the renderer instead + if (isset($METADATA_RENDERERS[$id])) { + $orig =& $METADATA_RENDERERS[$id]; + $meta = $orig; + } else { + // cache the current page + $cache = ($ID == $id); + $orig = p_read_metadata($id, $cache); - // render metadata first? - $meta = $render ? p_render_metadata($id, $orig) : $orig; + // render metadata first? + $meta = $render ? p_render_metadata($id, $orig) : $orig; + } // now add the passed metadata $protected = array('description', 'date', 'contributor'); @@ -339,7 +346,13 @@ function p_set_metadata($id, $data, $render=false, $persistent=true){ // save only if metadata changed if ($meta == $orig) return true; - return p_save_metadata($id, $meta); + if (isset($METADATA_RENDERERS[$id])) { + // set both keys individually as the renderer has references to the individual keys + $METADATA_RENDERERS[$id]['current'] = $meta['current']; + $METADATA_RENDERERS[$id]['persistent'] = $meta['persistent']; + } else { + return p_save_metadata($id, $meta); + } } /** @@ -413,7 +426,15 @@ function p_save_metadata($id, $meta) { */ function p_render_metadata($id, $orig){ // make sure the correct ID is in global ID - global $ID; + global $ID, $METADATA_RENDERERS; + + // avoid recursive rendering processes for the same id + if (isset($METADATA_RENDERERS[$id])) + return $orig; + + // store the original metadata in the global $METADATA_RENDERERS so p_set_metadata can use it + $METADATA_RENDERERS[$id] =& $orig; + $keep = $ID; $ID = $id; @@ -428,13 +449,14 @@ function p_render_metadata($id, $orig){ $instructions = p_cached_instructions(wikiFN($id),false,$id); if(is_null($instructions)){ $ID = $keep; + unset($METADATA_RENDERERS[$id]); return null; // something went wrong with the instructions } // set up the renderer $renderer = new Doku_Renderer_metadata(); - $renderer->meta = $orig['current']; - $renderer->persistent = $orig['persistent']; + $renderer->meta =& $orig['current']; + $renderer->persistent =& $orig['persistent']; // loop through the instructions foreach ($instructions as $instruction){ @@ -442,11 +464,13 @@ function p_render_metadata($id, $orig){ call_user_func_array(array(&$renderer, $instruction[0]), (array) $instruction[1]); } - $evt->result = array('current'=>$renderer->meta,'persistent'=>$renderer->persistent); + $evt->result = array('current'=>&$renderer->meta,'persistent'=>&$renderer->persistent); } $evt->advise_after(); + // clean up $ID = $keep; + unset($METADATA_RENDERERS[$id]); return $evt->result; } |