Skip to content

Commit baa97fb

Browse files
committed
Fix: finfo_file() issue
1 parent 1faf17b commit baa97fb

File tree

3 files changed

+109
-8
lines changed

3 files changed

+109
-8
lines changed

ext/fileinfo/fileinfo.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,12 @@ static const char* php_fileinfo_from_path(struct magic_set *magic, const zend_st
268268
if (php_stream_stat(stream, &ssb) == SUCCESS) {
269269
if (ssb.sb.st_mode & S_IFDIR) {
270270
ret_val = "directory";
271-
} else {
272-
ret_val = magic_stream(magic, stream);
273-
if (UNEXPECTED(ret_val == NULL)) {
274-
php_error_docref(NULL, E_WARNING, "Failed identify data %d:%s", magic_errno(magic), magic_error(magic));
275-
}
271+
}
272+
}
273+
if (!ret_val) {
274+
ret_val = magic_stream(magic, stream);
275+
if (UNEXPECTED(ret_val == NULL)) {
276+
php_error_docref(NULL, E_WARNING, "Failed identify data %d:%s", magic_errno(magic), magic_error(magic));
276277
}
277278
}
278279

@@ -430,8 +431,10 @@ PHP_FUNCTION(mime_content_type)
430431
if (path) {
431432
php_stream_context *context = php_stream_context_get_default(false);
432433
ret_val = php_fileinfo_from_path(magic, path, context);
433-
} else {
434-
/* remember stream position for restoration */
434+
}
435+
436+
if (!path) {
437+
/* Remember stream position for restoration */
435438
zend_off_t current_stream_pos = php_stream_tell(stream);
436439
php_stream_seek(stream, 0, SEEK_SET);
437440

@@ -440,7 +443,7 @@ PHP_FUNCTION(mime_content_type)
440443
php_error_docref(NULL, E_WARNING, "Failed identify data %d:%s", magic_errno(magic), magic_error(magic));
441444
}
442445

443-
php_stream_seek(stream, current_stream_pos, SEEK_SET);
446+
php_stream_seek(stream, current_stream_pos, SEEK_SET);
444447
}
445448

446449
if (UNEXPECTED(ret_val == NULL)) {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
GH-20679 (finfo_file() doesn't work on remote resources)
3+
--EXTENSIONS--
4+
fileinfo
5+
--INI--
6+
allow_url_fopen=1
7+
--SKIPIF--
8+
<?php
9+
if (@!include "./ext/standard/tests/http/server.inc") die('skip server.inc not available');
10+
http_server_skipif();
11+
?>
12+
--FILE--
13+
<?php
14+
require "./ext/standard/tests/http/server.inc";
15+
16+
['pid' => $pid, 'uri' => $uri] = http_server([
17+
"data://text/plain,HTTP/1.0 200 Ok\r\n\r\n<html>foo",
18+
], $output);
19+
20+
$f = finfo_open();
21+
var_dump(finfo_file($f, $uri));
22+
23+
http_server_kill($pid);
24+
?>
25+
--EXPECT--
26+
string(51) "HTML document, ASCII text, with no line terminators"

test_finfo_remote.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
/**
3+
* Test script for finfo_file() with remote URLs
4+
* This tests the fix for the bug where finfo_file() returned false for remote URLs
5+
*/
6+
7+
echo "Testing finfo_file() with remote URLs\n";
8+
echo str_repeat("=", 50) . "\n\n";
9+
10+
$finfo = finfo_open();
11+
12+
// Check if HTTPS wrapper is available
13+
$wrappers = stream_get_wrappers();
14+
$hasHttps = in_array('https', $wrappers);
15+
16+
// Test 1: Remote URL (the original failing case)
17+
echo "Test 1: Remote URL (https://example.com)\n";
18+
if (!$hasHttps) {
19+
echo "⚠ SKIPPED: HTTPS wrapper not available (OpenSSL support required)\n";
20+
echo " To enable HTTPS support, rebuild PHP with: ./configure --with-openssl\n\n";
21+
} else {
22+
$result = finfo_file($finfo, "https://example.com");
23+
if ($result === false) {
24+
echo "❌ FAILED: finfo_file() returned false (this is the bug we're fixing)\n";
25+
} else {
26+
echo "✅ PASSED: finfo_file() returned: " . var_export($result, true) . "\n";
27+
// Expected something like: "HTML document, ASCII text, with very long lines (512)"
28+
if (stripos($result, "HTML") !== false || stripos($result, "text") !== false) {
29+
echo " ✓ Result contains expected content type indicators\n";
30+
}
31+
}
32+
}
33+
echo "\n";
34+
35+
// Test 2: Local file (should still work)
36+
echo "Test 2: Local file (this script itself)\n";
37+
$result = finfo_file($finfo, __FILE__);
38+
if ($result === false) {
39+
echo "❌ FAILED: finfo_file() returned false for local file\n";
40+
} else {
41+
echo "✅ PASSED: finfo_file() returned: " . var_export($result, true) . "\n";
42+
}
43+
echo "\n";
44+
45+
// Test 3: Directory (should still work and return "directory")
46+
echo "Test 3: Directory\n";
47+
$result = finfo_file($finfo, __DIR__);
48+
if ($result === false) {
49+
echo "❌ FAILED: finfo_file() returned false for directory\n";
50+
} else {
51+
echo "✅ PASSED: finfo_file() returned: " . var_export($result, true) . "\n";
52+
if ($result === "directory") {
53+
echo " ✓ Correctly identified as directory\n";
54+
} else {
55+
echo " ⚠ WARNING: Expected 'directory', got something else\n";
56+
}
57+
}
58+
echo "\n";
59+
60+
// Test 4: Another remote URL (different domain)
61+
echo "Test 4: Another remote URL (http://httpbin.org/html)\n";
62+
$result = finfo_file($finfo, "http://httpbin.org/html");
63+
if ($result === false) {
64+
echo "❌ FAILED: finfo_file() returned false for remote URL\n";
65+
} else {
66+
echo "✅ PASSED: finfo_file() returned: " . var_export($result, true) . "\n";
67+
}
68+
echo "\n";
69+
70+
echo str_repeat("=", 50) . "\n";
71+
echo "Test completed!\n";
72+

0 commit comments

Comments
 (0)