@@ -723,6 +723,102 @@ TEST_F(Test_File_Canonical,
723
723
EXPECT_SAME_FILE (canonical->path (), input_path);
724
724
}
725
725
726
+ #if defined(_WIN32)
727
+ TEST_F (Test_File_Canonical, canonical_path_resolves_directory_junctions) {
728
+ std::string temp_dir = this ->make_temporary_directory ();
729
+ create_directory_or_exit (temp_dir + " /realdir" );
730
+ create_windows_junction_or_exit (
731
+ (temp_dir + " /linkdir" ).c_str (),
732
+ (" \\ ??\\ " + temp_dir + QLJS_PREFERRED_PATH_DIRECTORY_SEPARATOR " realdir" )
733
+ .c_str ());
734
+ write_file_or_exit (temp_dir + " /realdir/temp.js" , u8" " _sv);
735
+
736
+ std::string input_path = temp_dir + " /linkdir/temp.js" ;
737
+ Result<Canonical_Path_Result, Canonicalize_Path_IO_Error> canonical =
738
+ canonicalize_path (input_path);
739
+ ASSERT_TRUE (canonical.ok ()) << canonical.error ().to_string ();
740
+
741
+ EXPECT_THAT (std::string (canonical->path ()),
742
+ AnyOf (HasSubstr (" /realdir/" ), HasSubstr (" \\ realdir\\ " )));
743
+ EXPECT_THAT (std::string (canonical->path ()), Not (HasSubstr (" /linkdir/" )));
744
+ EXPECT_THAT (std::string (canonical->path ()), Not (HasSubstr (" \\ linkdir\\ " )));
745
+ EXPECT_SAME_FILE (canonical->path (), temp_dir + " /realdir/temp.js" );
746
+ EXPECT_SAME_FILE (canonical->path (), input_path);
747
+ }
748
+ #endif
749
+
750
+ #if defined(_WIN32)
751
+ TEST_F (Test_File_Canonical, symlink_with_dot_dot_escapes_symlinked_dir) {
752
+ // $temp_dir\dir [directory]
753
+ // $temp_dir\dir\file.txt [file]
754
+ // $temp_dir\dir\subdir [directory]
755
+ // $temp_dir\dir\subdir\filelink.txt [symlink] -> ..\file.txt
756
+ // $temp_dir\linkdir [junction] -> $temp_dir\dir\subdir
757
+ // $temp_dir\file.txt [file]
758
+ //
759
+ // $temp_dir\linkdir\filelink.txt
760
+ // is the same as $temp_dir\dir\subdir\..\file.txt
761
+ // is the same as $temp_dir\dir\file.txt
762
+
763
+ std::string temp_dir = this ->make_temporary_directory ();
764
+ create_directory_or_exit (temp_dir + " /dir" );
765
+ write_file_or_exit (temp_dir + " /dir/file.txt" , u8" $tempdir/dir/file.txt" );
766
+ create_directory_or_exit (temp_dir + " /dir/subdir" );
767
+ create_posix_file_symbolic_link_or_exit (
768
+ (temp_dir + " /dir/subdir/filelink.txt" ).c_str (), " ..\\ file.txt" );
769
+ create_posix_directory_symbolic_link (
770
+ (temp_dir + " /linkdir" ).c_str (),
771
+ " dir" QLJS_PREFERRED_PATH_DIRECTORY_SEPARATOR " subdir" );
772
+ write_file_or_exit (temp_dir + " /file.txt" , u8" $tempdir/file.txt" );
773
+
774
+ std::string input_path = temp_dir + " /linkdir/filelink.txt" ;
775
+ Result<Canonical_Path_Result, Canonicalize_Path_IO_Error> canonical =
776
+ canonicalize_path (input_path);
777
+ ASSERT_TRUE (canonical.ok ()) << canonical.error ().to_string ();
778
+
779
+ EXPECT_SAME_FILE (canonical->path (), temp_dir + " /dir/subdir/../file.txt" );
780
+ EXPECT_SAME_FILE (canonical->path (), temp_dir + " /dir/file.txt" );
781
+ }
782
+ #endif
783
+
784
+ #if defined(_WIN32)
785
+ // TODO(#1200): Fix canonicalize_file when it encounters junctions.
786
+ TEST_F (Test_File_Canonical, DISABLED_symlink_with_dot_dot_escapes_junction) {
787
+ // $temp_dir\dir [directory]
788
+ // $temp_dir\dir\file.txt [file]
789
+ // $temp_dir\dir\subdir [directory]
790
+ // $temp_dir\dir\subdir\filelink.txt [symlink] -> ..\file.txt
791
+ // $temp_dir\linkdir [junction] -> $temp_dir\dir\subdir
792
+ // $temp_dir\file.txt [file]
793
+ //
794
+ // $temp_dir\linkdir\filelink.txt
795
+ // is the same as $temp_dir\linkdir\..\file.txt
796
+ // is the same as $temp_dir\file.txt
797
+
798
+ std::string temp_dir = this ->make_temporary_directory ();
799
+ create_directory_or_exit (temp_dir + " /dir" );
800
+ write_file_or_exit (temp_dir + " /dir/file.txt" , u8" $tempdir/dir/file.txt" );
801
+ create_directory_or_exit (temp_dir + " /dir/subdir" );
802
+ create_posix_file_symbolic_link_or_exit (
803
+ (temp_dir + " /dir/subdir/filelink.txt" ).c_str (), " ..\\ file.txt" );
804
+ create_windows_junction_or_exit (
805
+ (temp_dir + " /linkdir" ).c_str (),
806
+ (" \\ ??\\ " + temp_dir +
807
+ QLJS_PREFERRED_PATH_DIRECTORY_SEPARATOR
808
+ " dir" QLJS_PREFERRED_PATH_DIRECTORY_SEPARATOR " subdir" )
809
+ .c_str ());
810
+ write_file_or_exit (temp_dir + " /file.txt" , u8" $tempdir/file.txt" );
811
+
812
+ std::string input_path = temp_dir + " /linkdir/filelink.txt" ;
813
+ Result<Canonical_Path_Result, Canonicalize_Path_IO_Error> canonical =
814
+ canonicalize_path (input_path);
815
+ ASSERT_TRUE (canonical.ok ()) << canonical.error ().to_string ();
816
+
817
+ EXPECT_SAME_FILE (canonical->path (), temp_dir + " /linkdir/../file.txt" );
818
+ EXPECT_SAME_FILE (canonical->path (), temp_dir + " /file.txt" );
819
+ }
820
+ #endif
821
+
726
822
TEST_F (Test_File_Canonical,
727
823
canonical_path_resolves_directory_relative_symlinks) {
728
824
std::string temp_dir = this ->make_temporary_directory ();
0 commit comments