summaryrefslogtreecommitdiff
path: root/inc
diff options
context:
space:
mode:
authorChristopher Smith <chris@jalakai.co.uk>2011-02-06 15:21:22 +0000
committerChristopher Smith <chris@jalakai.co.uk>2011-02-06 15:21:22 +0000
commitb842a02804e6c492963978620e61739485b7287f (patch)
tree00995d07d0c146bbba38a72fa6086547db949080 /inc
parent3893df8e5068f411ba16c2e37096e47c4ad102f2 (diff)
parent26497271fdd53b972af0b3a4411b6ce41a0629c0 (diff)
downloadrpg-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.php31
-rw-r--r--inc/HTTPClient.php27
-rw-r--r--inc/common.php2
-rw-r--r--inc/html.php8
-rw-r--r--inc/media.php150
-rw-r--r--inc/parserutils.php48
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;
}