11use std:: ffi:: { OsStr , OsString } ;
2- use std:: path:: Path ;
2+ use std:: path:: { Path , PathBuf } ;
33use std:: { iter, mem} ;
44use std:: convert:: TryFrom ;
55use std:: borrow:: Cow ;
66
7+ #[ cfg( unix) ]
8+ use std:: os:: unix:: ffi:: { OsStrExt , OsStringExt } ;
9+ #[ cfg( windows) ]
10+ use std:: os:: windows:: ffi:: { OsStrExt , OsStringExt } ;
11+
712use rustc:: mir;
813use rustc:: ty:: {
914 self ,
@@ -479,7 +484,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
479484 {
480485 #[ cfg( unix) ]
481486 fn bytes_to_os_str < ' tcx , ' a > ( bytes : & ' a [ u8 ] ) -> InterpResult < ' tcx , & ' a OsStr > {
482- Ok ( std :: os :: unix :: ffi :: OsStrExt :: from_bytes ( bytes) )
487+ Ok ( OsStr :: from_bytes ( bytes) )
483488 }
484489 #[ cfg( not( unix) ) ]
485490 fn bytes_to_os_str < ' tcx , ' a > ( bytes : & ' a [ u8 ] ) -> InterpResult < ' tcx , & ' a OsStr > {
@@ -499,8 +504,34 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
499504 ' tcx : ' a ,
500505 ' mir : ' a ,
501506 {
502- let os_str = self . read_os_str_from_c_str ( scalar) ?;
503- Ok ( Cow :: Borrowed ( Path :: new ( os_str) ) )
507+ let this = self . eval_context_ref ( ) ;
508+ let os_str = this. read_os_str_from_c_str ( scalar) ?;
509+
510+ #[ cfg( windows) ]
511+ return Ok ( if this. tcx . sess . target . target . target_os == "windows" {
512+ // Windows-on-Windows, all fine.
513+ Cow :: Borrowed ( Path :: new ( os_str) )
514+ } else {
515+ // Unix target, Windows host. Need to convert target '/' to host '\'.
516+ let converted = os_str
517+ . encode_wide ( )
518+ . map ( |wchar| if wchar == '/' as u16 { '\\' as u16 } else { wchar } )
519+ . collect :: < Vec < _ > > ( ) ;
520+ Cow :: Owned ( PathBuf :: from ( OsString :: from_wide ( & converted) ) )
521+ } ) ;
522+ #[ cfg( unix) ]
523+ return Ok ( if this. tcx . sess . target . target . target_os == "windows" {
524+ // Windows target, Unix host. Need to convert target '\' to host '/'.
525+ let converted = os_str
526+ . as_bytes ( )
527+ . iter ( )
528+ . map ( |& wchar| if wchar == '/' as u8 { '\\' as u8 } else { wchar } )
529+ . collect :: < Vec < _ > > ( ) ;
530+ Cow :: Owned ( PathBuf :: from ( OsString :: from_vec ( converted) ) )
531+ } else {
532+ // Unix-on-Unix, all is fine.
533+ Cow :: Borrowed ( Path :: new ( os_str) )
534+ } ) ;
504535 }
505536
506537 /// Helper function to read an OsString from a 0x0000-terminated sequence of u16,
@@ -512,7 +543,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
512543 {
513544 #[ cfg( windows) ]
514545 pub fn u16vec_to_osstring < ' tcx , ' a > ( u16_vec : Vec < u16 > ) -> InterpResult < ' tcx , OsString > {
515- Ok ( std :: os :: windows :: ffi :: OsStringExt :: from_wide ( & u16_vec[ ..] ) )
546+ Ok ( OsString :: from_wide ( & u16_vec[ ..] ) )
516547 }
517548 #[ cfg( not( windows) ) ]
518549 pub fn u16vec_to_osstring < ' tcx , ' a > ( u16_vec : Vec < u16 > ) -> InterpResult < ' tcx , OsString > {
@@ -538,7 +569,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
538569 ) -> InterpResult < ' tcx , ( bool , u64 ) > {
539570 #[ cfg( unix) ]
540571 fn os_str_to_bytes < ' tcx , ' a > ( os_str : & ' a OsStr ) -> InterpResult < ' tcx , & ' a [ u8 ] > {
541- Ok ( std :: os :: unix :: ffi :: OsStrExt :: as_bytes ( os_str ) )
572+ Ok ( os_str . as_bytes ( ) )
542573 }
543574 #[ cfg( not( unix) ) ]
544575 fn os_str_to_bytes < ' tcx , ' a > ( os_str : & ' a OsStr ) -> InterpResult < ' tcx , & ' a [ u8 ] > {
@@ -571,8 +602,37 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
571602 scalar : Scalar < Tag > ,
572603 size : u64 ,
573604 ) -> InterpResult < ' tcx , ( bool , u64 ) > {
574- let os_str = path. as_os_str ( ) ;
575- self . write_os_str_to_c_str ( os_str, scalar, size)
605+ let this = self . eval_context_mut ( ) ;
606+
607+ #[ cfg( windows) ]
608+ let os_str = if this. tcx . sess . target . target . target_os == "windows" {
609+ // Windows-on-Windows, all fine.
610+ Cow :: Borrowed ( path. as_os_str ( ) )
611+ } else {
612+ // Unix target, Windows host. Need to convert host '\\' to target '/'.
613+ let converted = path
614+ . as_os_str ( )
615+ . encode_wide ( )
616+ . map ( |wchar| if wchar == '\\' as u16 { '/' as u16 } else { wchar } )
617+ . collect :: < Vec < _ > > ( ) ;
618+ Cow :: Owned ( OsString :: from_wide ( & converted) )
619+ } ;
620+ #[ cfg( unix) ]
621+ let os_str = if this. tcx . sess . target . target . target_os == "windows" {
622+ // Windows target, Unix host. Need to convert host '/' to target '\'.
623+ let converted = path
624+ . as_os_str ( )
625+ . as_bytes ( )
626+ . iter ( )
627+ . map ( |& wchar| if wchar == '/' as u8 { '\\' as u8 } else { wchar } )
628+ . collect :: < Vec < _ > > ( ) ;
629+ Cow :: Owned ( OsString :: from_vec ( converted) )
630+ } else {
631+ // Unix-on-Unix, all is fine.
632+ Cow :: Borrowed ( path. as_os_str ( ) )
633+ } ;
634+
635+ this. write_os_str_to_c_str ( & os_str, scalar, size)
576636 }
577637
578638 /// Helper function to write an OsStr as a 0x0000-terminated u16-sequence, which is what
@@ -588,7 +648,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
588648 ) -> InterpResult < ' tcx , ( bool , u64 ) > {
589649 #[ cfg( windows) ]
590650 fn os_str_to_u16vec < ' tcx > ( os_str : & OsStr ) -> InterpResult < ' tcx , Vec < u16 > > {
591- Ok ( std :: os :: windows :: ffi :: OsStrExt :: encode_wide ( os_str ) . collect ( ) )
651+ Ok ( os_str . encode_wide ( ) . collect ( ) )
592652 }
593653 #[ cfg( not( windows) ) ]
594654 fn os_str_to_u16vec < ' tcx > ( os_str : & OsStr ) -> InterpResult < ' tcx , Vec < u16 > > {
0 commit comments