{"sha":"f872ab18ca670f5867b2241745daa30cd0fab861","node_id":"C_kwDOKSzhv9oAKGY4NzJhYjE4Y2E2NzBmNTg2N2IyMjQxNzQ1ZGFhMzBjZDBmYWI4NjE","commit":{"author":{"name":"Kazuto Takeshita","email":"info@mt8.biz","date":"2026-04-08T02:34:16Z"},"committer":{"name":"GitHub","email":"noreply@github.com","date":"2026-04-08T02:34:16Z"},"message":"Merge pull request #32 from web-soudan/security/fix-file-upload-path-validation\n\nsecurity: ファイルアップロード処理のパス検証を強化 (5.1.2)","tree":{"sha":"e6d799547faed00cd3648810cfa96752c5bdf4ba","url":"https://api.github.com/repos/web-soudan/mw-wp-form/git/trees/e6d799547faed00cd3648810cfa96752c5bdf4ba"},"url":"https://api.github.com/repos/web-soudan/mw-wp-form/git/commits/f872ab18ca670f5867b2241745daa30cd0fab861","comment_count":0,"verification":{"verified":true,"reason":"valid","signature":"-----BEGIN PGP SIGNATURE-----\n\nwsFcBAABCAAQBQJp1b6oCRC1aQ7uu5UhlAAA+Q0QABvw4p/nz4yhvlF6Rij4pbtv\nUpPCoPjR8AxPDQTSJMkTi0HtCGXdO1hVwYyI6+e02z4bsdekYcjAvU5yY6wl6Iwz\nwyfWNDgU4/twdn1f9rBFTTVhbgHLmwOZjXKNnXRYh5wPwdI0ER5ShYTReVWEp7+A\nUFf39RnJJcaGI7C4KEW22VdNW04iILHTsj59Re7HJF3LF9C1mZ3jcHtPRcZD1RyJ\nQfftIFwSG/0h1lR+xIWlb1JwE5vwyolxbWa2RdckKIDkgvF9wg0QQb2TfrtLH0VN\n94UzkRmb/kCA7mveKZ6fCzEW0TD6GkbGmI7EjI6lD0PAvhouS0Zos4TLCXm0SJIv\nyHJ5pbqZeILPm//XNzwQ7pru6bvQrqNZ+EiYaIvJR9ryowKjOSg6MlQoqDydTuTp\neFsepAsOtKCv2JejXLpmsvkF4aWqFLBP+W6bY1p+QrelU2TN8N33AEq5nuJC0RsR\n2EPb2TLM3YdCHeA1evaKU4Z+PB0BK3JT0/ILsVrC7we/zQyMUYRsWWXP+r6FI9h+\npyJYu+p6Dg7CKQrN47+6LrFk5tq2BqLMXPIcjpBB4FL4AOkcV9hT9PKnnfeiigmw\nSuxXtyBllV659T3RoFupx53RxGujrL8ALUGfD2+M7EbNaugQ4SzyA/6CLRxv4N4n\nYFQVLhQNKSdwExCEDpOL\n=SgXM\n-----END PGP SIGNATURE-----\n","payload":"tree e6d799547faed00cd3648810cfa96752c5bdf4ba\nparent 3b2c1579431a8559cf3d15f2f0748933b313a132\nparent a6ae8e54bc41979c019f8da12b50e7f9a707fe7c\nauthor Kazuto Takeshita <info@mt8.biz> 1775615656 +0900\ncommitter GitHub <noreply@github.com> 1775615656 +0900\n\nMerge pull request #32 from web-soudan/security/fix-file-upload-path-validation\n\nsecurity: ファイルアップロード処理のパス検証を強化 (5.1.2)","verified_at":"2026-04-08T02:34:16Z"}},"url":"https://api.github.com/repos/web-soudan/mw-wp-form/commits/f872ab18ca670f5867b2241745daa30cd0fab861","html_url":"https://github.com/web-soudan/mw-wp-form/commit/f872ab18ca670f5867b2241745daa30cd0fab861","comments_url":"https://api.github.com/repos/web-soudan/mw-wp-form/commits/f872ab18ca670f5867b2241745daa30cd0fab861/comments","author":{"login":"mt8","id":2771396,"node_id":"MDQ6VXNlcjI3NzEzOTY=","avatar_url":"https://avatars.githubusercontent.com/u/2771396?v=4","gravatar_id":"","url":"https://api.github.com/users/mt8","html_url":"https://github.com/mt8","followers_url":"https://api.github.com/users/mt8/followers","following_url":"https://api.github.com/users/mt8/following{/other_user}","gists_url":"https://api.github.com/users/mt8/gists{/gist_id}","starred_url":"https://api.github.com/users/mt8/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mt8/subscriptions","organizations_url":"https://api.github.com/users/mt8/orgs","repos_url":"https://api.github.com/users/mt8/repos","events_url":"https://api.github.com/users/mt8/events{/privacy}","received_events_url":"https://api.github.com/users/mt8/received_events","type":"User","user_view_type":"public","site_admin":false},"committer":{"login":"web-flow","id":19864447,"node_id":"MDQ6VXNlcjE5ODY0NDQ3","avatar_url":"https://avatars.githubusercontent.com/u/19864447?v=4","gravatar_id":"","url":"https://api.github.com/users/web-flow","html_url":"https://github.com/web-flow","followers_url":"https://api.github.com/users/web-flow/followers","following_url":"https://api.github.com/users/web-flow/following{/other_user}","gists_url":"https://api.github.com/users/web-flow/gists{/gist_id}","starred_url":"https://api.github.com/users/web-flow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/web-flow/subscriptions","organizations_url":"https://api.github.com/users/web-flow/orgs","repos_url":"https://api.github.com/users/web-flow/repos","events_url":"https://api.github.com/users/web-flow/events{/privacy}","received_events_url":"https://api.github.com/users/web-flow/received_events","type":"User","user_view_type":"public","site_admin":false},"parents":[{"sha":"3b2c1579431a8559cf3d15f2f0748933b313a132","url":"https://api.github.com/repos/web-soudan/mw-wp-form/commits/3b2c1579431a8559cf3d15f2f0748933b313a132","html_url":"https://github.com/web-soudan/mw-wp-form/commit/3b2c1579431a8559cf3d15f2f0748933b313a132"},{"sha":"a6ae8e54bc41979c019f8da12b50e7f9a707fe7c","url":"https://api.github.com/repos/web-soudan/mw-wp-form/commits/a6ae8e54bc41979c019f8da12b50e7f9a707fe7c","html_url":"https://github.com/web-soudan/mw-wp-form/commit/a6ae8e54bc41979c019f8da12b50e7f9a707fe7c"}],"stats":{"total":223,"additions":203,"deletions":20},"files":[{"sha":"fba7ec70b5f1d1d92e867ba3bfd103697f881eb8","filename":"classes/controllers/class.main.php","status":"modified","additions":10,"deletions":3,"changes":13,"blob_url":"https://github.com/web-soudan/mw-wp-form/blob/f872ab18ca670f5867b2241745daa30cd0fab861/classes%2Fcontrollers%2Fclass.main.php","raw_url":"https://github.com/web-soudan/mw-wp-form/raw/f872ab18ca670f5867b2241745daa30cd0fab861/classes%2Fcontrollers%2Fclass.main.php","contents_url":"https://api.github.com/repos/web-soudan/mw-wp-form/contents/classes%2Fcontrollers%2Fclass.main.php?ref=f872ab18ca670f5867b2241745daa30cd0fab861","patch":"@@ -332,9 +332,16 @@ protected function _get_attachments() {\n \t\t\t\tcontinue;\n \t\t\t}\n \n-\t\t\t$form_id  = MWF_Functions::get_form_id_from_form_key( $this->Data->get_form_key() );\n-\t\t\t$filepath = MW_WP_Form_Directory::generate_user_filepath( $form_id, $key, $upload_filename );\n-\t\t\tif ( ! file_exists( $filepath ) ) {\n+\t\t\t$form_id = MWF_Functions::get_form_id_from_form_key( $this->Data->get_form_key() );\n+\n+\t\t\ttry {\n+\t\t\t\t$filepath = MW_WP_Form_Directory::generate_user_filepath( $form_id, $key, $upload_filename );\n+\t\t\t} catch ( \\Exception $e ) {\n+\t\t\t\terror_log( $e->getMessage() );\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tif ( ! $filepath || ! file_exists( $filepath ) ) {\n \t\t\t\tcontinue;\n \t\t\t}\n "},{"sha":"41c6ddf6f6414a50e178e0f27c1a35246c0a8def","filename":"classes/models/class.data.php","status":"modified","additions":11,"deletions":2,"changes":13,"blob_url":"https://github.com/web-soudan/mw-wp-form/blob/f872ab18ca670f5867b2241745daa30cd0fab861/classes%2Fmodels%2Fclass.data.php","raw_url":"https://github.com/web-soudan/mw-wp-form/raw/f872ab18ca670f5867b2241745daa30cd0fab861/classes%2Fmodels%2Fclass.data.php","contents_url":"https://api.github.com/repos/web-soudan/mw-wp-form/contents/classes%2Fmodels%2Fclass.data.php?ref=f872ab18ca670f5867b2241745daa30cd0fab861","patch":"@@ -607,8 +607,17 @@ public function regenerate_upload_file_keys() {\n \t\tforeach ( $upload_file_keys as $key => $upload_file_key ) {\n \t\t\t$upload_filename = $this->get_post_value_by_key( $upload_file_key );\n \t\t\t$form_id         = MWF_Functions::get_form_id_from_form_key( $this->get_form_key() );\n-\t\t\t$filepath        = MW_WP_Form_Directory::generate_user_filepath( $form_id, $upload_file_key, $upload_filename );\n-\t\t\tif ( ! $upload_filename || ! file_exists( $filepath ) ) {\n+\n+\t\t\ttry {\n+\t\t\t\t$filepath = MW_WP_Form_Directory::generate_user_filepath( $form_id, $upload_file_key, $upload_filename );\n+\t\t\t} catch ( \\Exception $e ) {\n+\t\t\t\terror_log( $e->getMessage() );\n+\t\t\t\tunset( $upload_file_keys[ $key ] );\n+\t\t\t\t$this->set( $upload_file_key, '' );\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\tif ( ! $upload_filename || ! $filepath || ! file_exists( $filepath ) ) {\n \t\t\t\tunset( $upload_file_keys[ $key ] );\n \t\t\t\t$this->set( $upload_file_key, '' );\n \t\t\t}"},{"sha":"eeab63047ba56a40fe18984edbba5ff4525ade91","filename":"classes/models/class.directory.php","status":"modified","additions":104,"deletions":6,"changes":110,"blob_url":"https://github.com/web-soudan/mw-wp-form/blob/f872ab18ca670f5867b2241745daa30cd0fab861/classes%2Fmodels%2Fclass.directory.php","raw_url":"https://github.com/web-soudan/mw-wp-form/raw/f872ab18ca670f5867b2241745daa30cd0fab861/classes%2Fmodels%2Fclass.directory.php","contents_url":"https://api.github.com/repos/web-soudan/mw-wp-form/contents/classes%2Fmodels%2Fclass.directory.php?ref=f872ab18ca670f5867b2241745daa30cd0fab861","patch":"@@ -39,6 +39,10 @@ public static function generate_user_dirpath( $form_id ) {\n \t\t\tthrow new \\RuntimeException( '[MW WP Form] Failed to create user directory.' );\n \t\t}\n \n+\t\tif ( ! preg_match( '/^\\d+$/', (string) $form_id ) ) {\n+\t\t\tthrow new \\RuntimeException( '[MW WP Form] Invalid form ID.' );\n+\t\t}\n+\n \t\t$user_dir = path_join( static::get(), $saved_token );\n \t\t$user_dir = path_join( $user_dir, (string) $form_id );\n \n@@ -54,9 +58,17 @@ public static function generate_user_dirpath( $form_id ) {\n \t * @throws \\RuntimeException When directory name is not token value.\n \t */\n \tpublic static function generate_user_file_dirpath( $form_id, $name ) {\n+\t\tif ( ! static::_is_valid_path_segment( $name ) ) {\n+\t\t\tthrow new \\RuntimeException( '[MW WP Form] Invalid file reference requested.' );\n+\t\t}\n+\n \t\t$user_dir      = static::generate_user_dirpath( $form_id );\n \t\t$user_file_dir = path_join( $user_dir, $name );\n \n+\t\tif ( ! static::_is_within_expected_dir_candidate( $form_id, $user_file_dir ) ) {\n+\t\t\tthrow new \\RuntimeException( '[MW WP Form] Invalid file reference requested.' );\n+\t\t}\n+\n \t\treturn $user_file_dir;\n \t}\n \n@@ -140,20 +152,20 @@ public static function generate_user_filepath( $form_id, $name, $filename ) {\n \t\t\treturn false;\n \t\t}\n \n+\t\tif ( ! static::_is_valid_path_segment( $filename ) ) {\n+\t\t\tthrow new \\RuntimeException( '[MW WP Form] Invalid file reference requested.' );\n+\t\t}\n+\n \t\t$user_file_dir = static::generate_user_file_dirpath( $form_id, $name );\n \t\tif ( ! $user_file_dir || ! is_dir( $user_file_dir ) ) {\n \t\t\treturn false;\n \t\t}\n \n-\t\t$normalized_filename = wp_normalize_path( $filename );\n-\t\tif (\n-\t\t\twp_basename( $normalized_filename ) !== $normalized_filename ||\n-\t\t\tstrstr( $normalized_filename, \"\\0\" )\n-\t\t) {\n+\t\t$filepath = path_join( $user_file_dir, $filename );\n+\t\tif ( ! static::_is_within_expected_dir_candidate( $form_id, $filepath ) ) {\n \t\t\tthrow new \\RuntimeException( '[MW WP Form] Invalid file reference requested.' );\n \t\t}\n \n-\t\t$filepath      = path_join( $user_file_dir, $filename );\n \t\t$filepath      = wp_normalize_path( $filepath );\n \t\t$user_file_dir = trailingslashit( wp_normalize_path( $user_file_dir ) );\n \n@@ -176,6 +188,92 @@ public static function generate_user_filepath( $form_id, $name, $filename ) {\n \t\treturn $filepath;\n \t}\n \n+\t/**\n+\t * Return true when path segment is valid.\n+\t *\n+\t * @param string $value Path segment.\n+\t * @return boolean\n+\t */\n+\tprotected static function _is_valid_path_segment( $value ) {\n+\t\tif ( ! is_string( $value ) || '' === $value ) {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\t$value = wp_normalize_path( $value );\n+\n+\t\tif ( strstr( $value, \"\\0\" ) ) {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\tif ( '.' === $value || '..' === $value ) {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\tif ( path_is_absolute( $value ) ) {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\tif ( wp_basename( $value ) !== $value ) {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\treturn true;\n+\t}\n+\n+\t/**\n+\t * Return true when candidate path is inside the current user's temp directory.\n+\t *\n+\t * @param int    $form_id Form ID.\n+\t * @param string $path    Target path.\n+\t * @return boolean\n+\t */\n+\tprotected static function _is_within_expected_dir_candidate( $form_id, $path ) {\n+\t\t$path = wp_normalize_path( $path );\n+\n+\t\t$user_dir = static::_get_expected_user_dir( $form_id, static::get() );\n+\t\tif ( false === $user_dir ) {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\t$path           = untrailingslashit( $path );\n+\t\t$user_dir       = untrailingslashit( $user_dir );\n+\t\t$user_dir_slash = trailingslashit( $user_dir );\n+\n+\t\treturn $path === $user_dir || 0 === strpos( $path, $user_dir_slash );\n+\t}\n+\n+\t/**\n+\t * Return the expected user directory path.\n+\t *\n+\t * @param int         $form_id  Form ID.\n+\t * @param string|bool $base_dir Base directory path.\n+\t * @return string|false\n+\t */\n+\tprotected static function _get_expected_user_dir( $form_id, $base_dir ) {\n+\t\t$saved_token = MW_WP_Form_Csrf::saved_token();\n+\t\t$saved_token = $saved_token ? $saved_token : MW_WP_Form_Csrf::token();\n+\t\tif ( ! preg_match( '|^[a-z0-9]+$|', $saved_token ) ) {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\tif ( ! preg_match( '/^\\d+$/', (string) $form_id ) ) {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\tif ( ! $base_dir ) {\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\t$base_dir = wp_normalize_path( $base_dir );\n+\n+\t\treturn wp_normalize_path(\n+\t\t\tpath_join(\n+\t\t\t\tpath_join( $base_dir, $saved_token ),\n+\t\t\t\t(string) $form_id\n+\t\t\t)\n+\t\t);\n+\t}\n+\n \t/**\n \t * Returns a list of saved file paths.\n \t *"},{"sha":"efe1fd8a8dbd1f989f361569e3475536de300505","filename":"mw-wp-form.php","status":"modified","additions":1,"deletions":1,"changes":2,"blob_url":"https://github.com/web-soudan/mw-wp-form/blob/f872ab18ca670f5867b2241745daa30cd0fab861/mw-wp-form.php","raw_url":"https://github.com/web-soudan/mw-wp-form/raw/f872ab18ca670f5867b2241745daa30cd0fab861/mw-wp-form.php","contents_url":"https://api.github.com/repos/web-soudan/mw-wp-form/contents/mw-wp-form.php?ref=f872ab18ca670f5867b2241745daa30cd0fab861","patch":"@@ -3,7 +3,7 @@\n  * Plugin Name: MW WP Form\n  * Plugin URI: https://mw-wp-form.web-soudan.co.jp\n  * Description: MW WP Form is shortcode base contact form plugin. This plugin have many features. For example you can use many validation rules, inquiry data saving, and chart aggregation using saved inquiry data.\n- * Version: 5.1.1\n+ * Version: 5.1.2\n  * Requires at least: 6.0\n  * Requires PHP: 8.0\n  * Author: websoudan"},{"sha":"487f931665ec54172dd8bbd4014885f23bc44672","filename":"readme.txt","status":"modified","additions":11,"deletions":8,"changes":19,"blob_url":"https://github.com/web-soudan/mw-wp-form/blob/f872ab18ca670f5867b2241745daa30cd0fab861/readme.txt","raw_url":"https://github.com/web-soudan/mw-wp-form/raw/f872ab18ca670f5867b2241745daa30cd0fab861/readme.txt","contents_url":"https://api.github.com/repos/web-soudan/mw-wp-form/contents/readme.txt?ref=f872ab18ca670f5867b2241745daa30cd0fab861","patch":"@@ -5,7 +5,7 @@ Tags: plugin, form, confirm, preview, shortcode, mail, chart, graph, html, conta\n Requires at least: 6.0\r\n Requires PHP: 8.0\r\n Tested up to: 6.4\r\n-Stable tag: 5.1.1\n+Stable tag: 5.1.2\r\n License: GPLv2 or later\r\n License URI: http://www.gnu.org/licenses/gpl-2.0.html\r\n \r\n@@ -79,13 +79,16 @@ Do you have questions or issues with MW WP Form? Use these support channels appr\n 4. List page of inquiry data that has been saved.\r\n 5. Supports chart display of saved inquiry data.\r\n \r\n-== Changelog ==\n-\n-= 5.1.1 =\n-* Security Fix insufficient file path validation in upload file handling\n-\n-= 5.1.0 =\n-* Security Use wp_kses_post to form content/complete message\n+== Changelog ==\r\n+\r\n+= 5.1.2 =\r\n+* Security Fix insufficient file path validation in upload file handling\r\n+\r\n+= 5.1.1 =\r\n+* Security Fix insufficient file path validation in upload file handling\r\n+\r\n+= 5.1.0 =\r\n+* Security Use wp_kses_post to form content/complete message\r\n \r\n = 5.0.6 =\r\n * Fixed Fixed an error during uninstallation. ( later 5.0.0 )\r"},{"sha":"8451530f72714f24155095ddecb7580d329ecf48","filename":"tests/classes/models/test-data.php","status":"modified","additions":18,"deletions":0,"changes":18,"blob_url":"https://github.com/web-soudan/mw-wp-form/blob/f872ab18ca670f5867b2241745daa30cd0fab861/tests%2Fclasses%2Fmodels%2Ftest-data.php","raw_url":"https://github.com/web-soudan/mw-wp-form/raw/f872ab18ca670f5867b2241745daa30cd0fab861/tests%2Fclasses%2Fmodels%2Ftest-data.php","contents_url":"https://api.github.com/repos/web-soudan/mw-wp-form/contents/tests%2Fclasses%2Fmodels%2Ftest-data.php?ref=f872ab18ca670f5867b2241745daa30cd0fab861","patch":"@@ -679,6 +679,24 @@ public function regenerate_upload_file_keys() {\n \t\tunlink( $dirpath . '/1.txt' );\n \t}\n \n+\t/**\n+\t * @test\n+\t * @group regenerate_upload_file_keys\n+\t */\n+\tpublic function regenerate_upload_file_keys_should_drop_invalid_keys() {\n+\t\t$Data = $this->_instantiation_Data( array(\n+\t\t\tMWF_Config::UPLOAD_FILE_KEYS => array( '/var/www/wordpress', '../../../wordpress' ),\n+\t\t) );\n+\n+\t\t$Data->set( '/var/www/wordpress', 'wp-config.php' );\n+\t\t$Data->set( '../../../wordpress', 'wp-config.php' );\n+\t\t$Data->regenerate_upload_file_keys();\n+\n+\t\t$this->assertEquals( array(), $Data->get_post_value_by_key( MWF_Config::UPLOAD_FILE_KEYS ) );\n+\t\t$this->assertSame( '', $Data->get_post_value_by_key( '/var/www/wordpress' ) );\n+\t\t$this->assertSame( '', $Data->get_post_value_by_key( '../../../wordpress' ) );\n+\t}\n+\n \t/**\n \t * @test\n \t * @group push_uploaded_file_keys"},{"sha":"3fee7d62a2841045bedfd5ba38116136b3f641e8","filename":"tests/classes/models/test-directory.php","status":"modified","additions":48,"deletions":0,"changes":48,"blob_url":"https://github.com/web-soudan/mw-wp-form/blob/f872ab18ca670f5867b2241745daa30cd0fab861/tests%2Fclasses%2Fmodels%2Ftest-directory.php","raw_url":"https://github.com/web-soudan/mw-wp-form/raw/f872ab18ca670f5867b2241745daa30cd0fab861/tests%2Fclasses%2Fmodels%2Ftest-directory.php","contents_url":"https://api.github.com/repos/web-soudan/mw-wp-form/contents/tests%2Fclasses%2Fmodels%2Ftest-directory.php?ref=f872ab18ca670f5867b2241745daa30cd0fab861","patch":"@@ -76,4 +76,52 @@ public function generate_user_filepath_should_reject_windows_absolute_path() {\n \t\t$this->expectException( '\\RuntimeException' );\n \t\tMW_WP_Form_Directory::generate_user_filepath( $form_id, $name, 'C:\\\\tmp\\\\evil.php' );\n \t}\n+\n+\t/**\n+\t * @test\n+\t * @group generate_user_file_dirpath\n+\t */\n+\tpublic function generate_user_file_dirpath_should_reject_absolute_path_name() {\n+\t\tMW_WP_Form_Csrf::save_token();\n+\t\t$form_id = $this->_create_form();\n+\n+\t\t$this->expectException( '\\RuntimeException' );\n+\t\tMW_WP_Form_Directory::generate_user_file_dirpath( $form_id, '/var/www/wordpress' );\n+\t}\n+\n+\t/**\n+\t * @test\n+\t * @group generate_user_file_dirpath\n+\t */\n+\tpublic function generate_user_file_dirpath_should_reject_nested_path_name() {\n+\t\tMW_WP_Form_Csrf::save_token();\n+\t\t$form_id = $this->_create_form();\n+\n+\t\t$this->expectException( '\\RuntimeException' );\n+\t\tMW_WP_Form_Directory::generate_user_file_dirpath( $form_id, 'nested/file-1' );\n+\t}\n+\n+\t/**\n+\t * @test\n+\t * @group generate_user_file_dirpath\n+\t */\n+\tpublic function generate_user_file_dirpath_should_reject_path_outside_user_dir() {\n+\t\tMW_WP_Form_Csrf::save_token();\n+\t\t$form_id = $this->_create_form();\n+\n+\t\t$this->expectException( '\\RuntimeException' );\n+\t\tMW_WP_Form_Directory::generate_user_file_dirpath( $form_id, '../../../wordpress' );\n+\t}\n+\n+\t/**\n+\t * @test\n+\t * @group generate_user_file_dirpath\n+\t */\n+\tpublic function generate_user_file_dirpath_should_reject_windows_absolute_path_name() {\n+\t\tMW_WP_Form_Csrf::save_token();\n+\t\t$form_id = $this->_create_form();\n+\n+\t\t$this->expectException( '\\RuntimeException' );\n+\t\tMW_WP_Form_Directory::generate_user_file_dirpath( $form_id, 'C:\\\\xampp\\\\htdocs\\\\wordpress' );\n+\t}\n }"}]}