PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.15
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.15
6.2.15 6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 All 197 releases
← All changes | app/Services/Migrator/Classes/BaseMigrator.php +65 -2 6.2.3 → 6.2.15 View file →
@@ -1537,8 +1537,10 @@
1537 1537
1538 1538 $formattedTypes = explode(', ', ArrayHelper::get($field, $arg, ''));
1539 1539 $fileTypeOptions = [];
1540 1540 foreach ($formattedTypes as $format) {
1541 + // $allFileTypes is lowercase; the source plugin's list is user-entered.
1542 + $format = strtolower($format);
1541 1543 foreach ($allFileTypes as $fileTypes) {
1542 1544 if (!empty($format) && (strpos($fileTypes, $format) !== false)) {
1543 1545 array_push($fileTypeOptions, $fileTypes);
1544 1546 }
@@ -1713,9 +1715,13 @@
1713 1715 $urls = [$urls];
1714 1716 }
1715 1717 $values = [];
1716 1718 foreach ($urls as $url) {
1717 - $file_name = 'ff-' . wp_basename($url);
1719 + $source = $this->resolveMigrationSource($url);
1720 + if (!$source) {
1721 + continue;
1722 + }
1723 +
1718 1724 $basDir = wp_upload_dir()['basedir'] . '/fluentform/';
1719 1725 $baseurl = wp_upload_dir()['baseurl'] . '/fluentform/';
1720 1726
1721 1727 if (!file_exists($basDir) || (file_exists($basDir) && !is_dir($basDir))) {
@@ -1721,17 +1727,74 @@
1721 1727 if (!file_exists($basDir) || (file_exists($basDir) && !is_dir($basDir))) {
1722 1728 wp_mkdir_p($basDir);
1723 1729 }
1724 1730
1731 + // Unique name so two sources that sanitise alike do not overwrite.
1732 + $file_name = wp_unique_filename($basDir, $source['name']);
1725 1733 $destination = $basDir . $file_name;
1726 1734 require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php');
1727 1735 require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php');
1728 1736 $fileSystemDirect = new \WP_Filesystem_Direct(false);
1729 - if ($fileSystemDirect->copy($url, $destination, true)) {
1737 + if ($fileSystemDirect->copy($source['path'], $destination, true)) {
1730 1738 $values[] = $baseurl . $file_name;
1731 1739 }
1740 + @unlink($source['path']);
1732 1741 }
1733 1742 return $values;
1743 + }
1744 +
1745 + // Entry values come from the source plugin's export. PHP copy() would also read local
1746 + // server paths, so only an upload-allowed type fetched over http(s) reaches the
1747 + // web-reachable destination; download_url() refuses internal addresses on its own.
1748 + protected function resolveMigrationSource($url)
1749 + {
1750 + $name = $this->safeMigrationFileName($url);
1751 + if (!$name) {
1752 + return null;
1753 + }
1754 +
1755 + if (!function_exists('download_url')) {
1756 + require_once ABSPATH . 'wp-admin/includes/file.php';
1757 + }
1758 + $tmp = download_url((string) $url);
1759 + if (is_wp_error($tmp)) {
1760 + return null;
1761 + }
1762 +
1763 + return ['path' => $tmp, 'name' => $name];
1764 + }
1765 +
1766 + /**
1767 + * Build the destination name from the URL PATH, not the raw URL: the raw basename
1768 + * keeps the query string (scan.pdf?/shell.php -> shell.php). Inner dots are collapsed
1769 + * so exactly one gate-approved extension survives.
1770 + *
1771 + * @param string $url
1772 + * @return string|null ff-<name>.<ext>, or null when the type/scheme is not allowed
1773 + */
1774 + protected function safeMigrationFileName($url)
1775 + {
1776 + $url = (string) $url;
1777 + if (!preg_match('#^https?://#i', $url)) {
1778 + return null;
1779 + }
1780 +
1781 + $base = wp_basename((string) wp_parse_url($url, PHP_URL_PATH));
1782 + // The upload list grows with unfiltered_html and upload_mimes; HTML, script and SVG would run on the site's origin.
1783 + $mimes = array_filter(get_allowed_mime_types(), function ($mime) {
1784 + return !preg_match('#html|javascript|xml$#i', $mime);
1785 + });
1786 + $ext = wp_check_filetype($base, $mimes)['ext'];
1787 + if (!$ext) {
1788 + return null;
1789 + }
1790 +
1791 + $stem = str_replace('.', '_', sanitize_file_name(pathinfo($base, PATHINFO_FILENAME)));
1792 + if ('' === $stem) {
1793 + $stem = 'file';
1794 + }
1795 +
1796 + return 'ff-' . $stem . '.' . strtolower($ext);
1734 1797 }
1735 1798
1736 1799 protected function getResolveOperator($key)
1737 1800 {