diff --git a/src/aphront/configuration/AphrontApplicationConfiguration.php b/src/aphront/configuration/AphrontApplicationConfiguration.php --- a/src/aphront/configuration/AphrontApplicationConfiguration.php +++ b/src/aphront/configuration/AphrontApplicationConfiguration.php @@ -772,6 +772,11 @@ $multipart_parser->continueParse($raw_input); $parts = $multipart_parser->endParse(); + // We're building and then parsing a query string so that requests + // with arrays (like "x[]=apple&x[]=banana") work correctly. This also + // means we can't use "phutil_build_http_querystring()", since it + // can't build a query string with duplicate names. + $query_string = array(); foreach ($parts as $part) { if (!$part->isVariable()) { @@ -780,8 +785,7 @@ $name = $part->getName(); $value = $part->getVariableValue(); - - $query_string[] = urlencode($name).'='.urlencode($value); + $query_string[] = rawurlencode($name).'='.rawurlencode($value); } $query_string = implode('&', $query_string); $post = $parser->parseQueryString($query_string); diff --git a/src/applications/auth/factor/PhabricatorDuoAuthFactor.php b/src/applications/auth/factor/PhabricatorDuoAuthFactor.php --- a/src/applications/auth/factor/PhabricatorDuoAuthFactor.php +++ b/src/applications/auth/factor/PhabricatorDuoAuthFactor.php @@ -504,10 +504,7 @@ $push_info = array( pht('Domain') => $this->getInstallDisplayName(), ); - foreach ($push_info as $k => $v) { - $push_info[$k] = rawurlencode($k).'='.rawurlencode($v); - } - $push_info = implode('&', $push_info); + $push_info = phutil_build_http_querystring($push_info); $parameters = array( 'username' => $duo_user, diff --git a/src/applications/auth/future/PhabricatorDuoFuture.php b/src/applications/auth/future/PhabricatorDuoFuture.php --- a/src/applications/auth/future/PhabricatorDuoFuture.php +++ b/src/applications/auth/future/PhabricatorDuoFuture.php @@ -91,11 +91,7 @@ $http_method = $this->getHTTPMethod(); ksort($data); - $data_parts = array(); - foreach ($data as $key => $value) { - $data_parts[] = rawurlencode($key).'='.rawurlencode($value); - } - $data_parts = implode('&', $data_parts); + $data_parts = phutil_build_http_querystring($data); $corpus = array( $date, diff --git a/src/applications/diffusion/controller/DiffusionServeController.php b/src/applications/diffusion/controller/DiffusionServeController.php --- a/src/applications/diffusion/controller/DiffusionServeController.php +++ b/src/applications/diffusion/controller/DiffusionServeController.php @@ -528,7 +528,7 @@ unset($query_data[$key]); } } - $query_string = http_build_query($query_data, '', '&'); + $query_string = phutil_build_http_querystring($query_data); // We're about to wipe out PATH with the rest of the environment, so // resolve the binary first.