Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #13919, make response->setFileToSend support non-ASCII filename. #14333

Merged
merged 14 commits into from
Aug 30, 2019
2 changes: 2 additions & 0 deletions .github/stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ exemptLabels:
- "Bug - High"
- WIP
- Locked
- "Feature - NFR"
- "Enhancement"

# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
Expand Down
42 changes: 42 additions & 0 deletions phalcon/Helper/Fs.zep
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

/**
* This file is part of the Phalcon.
*
* (c) Phalcon Team <team@phalcon.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Phalcon\Helper;

/**
* This class offers file operation helper
*/
class Fs {

/**
* Gets the filename from a given path, Same as PHP's basename() but has non-ASCII support.
* PHP's basename() does not properly support streams or filenames beginning with a non-US-ASCII character.
* see https://bugs.php.net/bug.php?id=37738
*
* @param string $uri
* @param string $suffix
*
* @return string
*/
final public static function basename(string! uri, string suffix = null) -> string
{
var filename;
var separators;
var matches;
ian4hu marked this conversation as resolved.
Show resolved Hide resolved
let separators = DIRECTORY_SEPARATOR;
ian4hu marked this conversation as resolved.
Show resolved Hide resolved
let uri = rtrim(uri, separators);
ian4hu marked this conversation as resolved.
Show resolved Hide resolved
let filename = preg_match("@[^" . preg_quote(separators, "@") . "]+$@", uri, matches) ? matches[0] : "";
if suffix {
let filename = preg_replace("@" . preg_quote(suffix, "@") . "$@", "", filename);
}

return filename;
}
}
13 changes: 10 additions & 3 deletions phalcon/Http/Response.zep
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use DateTime;
use DateTimeZone;
use Phalcon\Di;
use Phalcon\Di\DiInterface;
use Phalcon\Helper\Fs;
use Phalcon\Http\Response\Exception;
use Phalcon\Http\Response\HeadersInterface;
use Phalcon\Http\Response\CookiesInterface;
Expand Down Expand Up @@ -546,18 +547,24 @@ class Response implements ResponseInterface, InjectionAwareInterface, EventsAwar
public function setFileToSend(string filePath, attachmentName = null, attachment = true) -> <ResponseInterface>
{
var basePath;
var basePathEncoding;
ian4hu marked this conversation as resolved.
Show resolved Hide resolved
var basePathEncoded;

if typeof attachmentName != "string" {
let basePath = basename(filePath);
let basePath = Fs::basename(filePath);
} else {
let basePath = attachmentName;
}

if attachment {
let basePathEncoded = rawurlencode(basePath);
let basePathEncoding = mb_detect_encoding(basePath, mb_detect_order(), true);
ian4hu marked this conversation as resolved.
Show resolved Hide resolved
this->setRawHeader("Content-Description: File Transfer");
this->setRawHeader("Content-Type: application/octet-stream");
this->setRawHeader("Content-Disposition: attachment; filename=" . basePath . ";");
this->setRawHeader("Content-Disposition: attachment; filename=" . basePathEncoded . ";");
this->setRawHeader("Content-Transfer-Encoding: binary");
if basePathEncoding != "ASCII" {
this->setRawHeader("Content-Disposition: attachment; filename=" . basePathEncoded . "; filename*=". strtolower(basePathEncoding) . "''" . basePathEncoded . ";");
}
ian4hu marked this conversation as resolved.
Show resolved Hide resolved
}

let this->file = filePath;
Expand Down