Anomie has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/51041


Change subject: (bug 44909) Add "upload" type to API
......................................................................

(bug 44909) Add "upload" type to API

If a file upload is not formatted correctly for PHP to recognize it as a
file upload rather than a regular field, the API will wind up trying to
load the file contents as a text field. Since these file contents are
often a large binary file, this will tend to run out of memory trying to
apply Unicode normalization.

To prevent this and to allow for a helpful error message, mark
parameters that are supposed to be file uploads.

Change-Id: Ia4586953e2ad2d72d08852689e060e39e7920d50
---
M RELEASE-NOTES-1.21
M includes/api/ApiBase.php
M includes/api/ApiMain.php
M includes/api/ApiUpload.php
4 files changed, 47 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/41/51041/1

diff --git a/RELEASE-NOTES-1.21 b/RELEASE-NOTES-1.21
index 3737932..19a7fbf 100644
--- a/RELEASE-NOTES-1.21
+++ b/RELEASE-NOTES-1.21
@@ -243,6 +243,10 @@
   currently in use on the wiki.
 * (bug 44921) ApiMain::execute() will now return after the CORS check for an
   HTTP OPTIONS request.
+* (bug 44909) API parameters may now be marked as type "upload", which is now
+  used for action=upload's 'file' and 'chunk' parameters. This type will raise
+  an error during parameter validation if the parameter is given but not
+  recognized as an uploaded file.
 
 === API internal changes in 1.21 ===
 * For debugging only, a new global $wgDebugAPI removes many API restrictions 
when true.
diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php
index aff7a2e..3338f7b 100644
--- a/includes/api/ApiBase.php
+++ b/includes/api/ApiBase.php
@@ -917,6 +917,29 @@
                        }
 
                        $value = $this->getMain()->getCheck( $encParamName );
+               } elseif ( $type == 'upload' ) {
+                       if ( isset( $default ) ) {
+                               // Having a default value is not allowed
+                               ApiBase::dieDebug( __METHOD__, "File upload 
param $encParamName's default is set to '$default'. File upload parameters may 
not have a default." );
+                       }
+                       if ( $multi ) {
+                               ApiBase::dieDebug( __METHOD__, "Multi-values 
not supported for $encParamName" );
+                       }
+                       $value = $this->getMain()->getUpload( $encParamName );
+                       if ( !$value->exists() ) {
+                               // This will get the value without trying to 
normalize it
+                               // (because trying to normalize a large binary 
file
+                               // accidentally uploaded as a field fails 
spectacularly)
+                               $value = 
$this->getMain()->getRequest()->unsetVal( $encParamName );
+                               if ( $value !== null ) {
+                                       $this->dieUsage(
+                                               "File upload param 
$encParamName is not a file upload; " .
+                                               "be sure to use 
multipart/form-data for your POST and include " .
+                                               "a filename in the 
Content-Disposition header.",
+                                               "badupload_{$encParamName}"
+                                       );
+                               }
+                       }
                } else {
                        $value = $this->getMain()->getVal( $encParamName, 
$default );
 
@@ -1013,6 +1036,8 @@
                                                        $value = $value[0];
                                                }
                                                break;
+                                       case 'upload': // nothing to do
+                                               break;
                                        default:
                                                ApiBase::dieDebug( __METHOD__, 
"Param $encParamName's type is unknown - $type" );
                                }
diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php
index 1dabbbf..74032e5 100644
--- a/includes/api/ApiMain.php
+++ b/includes/api/ApiMain.php
@@ -920,6 +920,18 @@
        }
 
        /**
+        * Get a request upload, and register the fact that it was used, for 
logging.
+        *
+        * @since 1.21
+        * @param $name string Parameter name
+        * @return WebRequestUpload
+        */
+       public function getUpload( $name ) {
+               $this->mParamsUsed[$name] = true;
+               return $this->getRequest()->getUpload( $name );
+       }
+
+       /**
         * Report unused parameters, so the client gets a hint in case it gave 
us parameters we don't know,
         * for example in case of spelling mistakes or a missing 'g' prefix for 
generators.
         */
diff --git a/includes/api/ApiUpload.php b/includes/api/ApiUpload.php
index a0da765..31675b9 100644
--- a/includes/api/ApiUpload.php
+++ b/includes/api/ApiUpload.php
@@ -696,7 +696,9 @@
                                ),
                        ),
                        'ignorewarnings' => false,
-                       'file' => null,
+                       'file' => array(
+                               ApiBase::PARAM_TYPE => 'upload',
+                       ),
                        'url' => null,
                        'filekey' => null,
                        'sessionkey' => array(
@@ -707,7 +709,9 @@
 
                        'filesize' => null,
                        'offset' => null,
-                       'chunk' => null,
+                       'chunk' => array(
+                               ApiBase::PARAM_TYPE => 'upload',
+                       ),
 
                        'async' => false,
                        'asyncdownload' => false,

-- 
To view, visit https://gerrit.wikimedia.org/r/51041
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia4586953e2ad2d72d08852689e060e39e7920d50
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Anomie <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to