Skip to content

Commit c0b8912

Browse files
committed
---
yaml --- r: 274925 b: refs/heads/stable c: 6ba5d9c h: refs/heads/master i: 274923: 5d03567
1 parent 3df0301 commit c0b8912

File tree

11 files changed

+150
-178
lines changed

11 files changed

+150
-178
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: e06d2ad9fcd5027bcaac5b08fc9aa39a49d0ecd3
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: c0221c8897db309a79990367476177b1230bb264
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 310ab5ea747110941f14d6aa8dc69cb794f1335d
32+
refs/heads/stable: 6ba5d9cfd5a76deae0adc1e28260d9821a94a3a7
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/etc/regex-match-tests.py

Lines changed: 0 additions & 109 deletions
This file was deleted.

branches/stable/src/libcore/ptr.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,7 @@ pub unsafe fn read<T>(src: *const T) -> T {
127127
tmp
128128
}
129129

130-
/// Variant of read_and_zero that writes the specific drop-flag byte
131-
/// (which may be more appropriate than zero).
130+
#[allow(missing_docs)]
132131
#[inline(always)]
133132
#[unstable(feature = "filling_drop",
134133
reason = "may play a larger role in std::ptr future extensions",

branches/stable/src/librustc_typeck/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3828,7 +3828,7 @@ impl<'tcx> Expectation<'tcx> {
38283828
/// for examples of where this comes up,.
38293829
fn rvalue_hint(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> {
38303830
match tcx.struct_tail(ty).sty {
3831-
ty::TySlice(_) | ty::TyTrait(..) => {
3831+
ty::TySlice(_) | ty::TyStr | ty::TyTrait(..) => {
38323832
ExpectRvalueLikeUnsized(ty)
38333833
}
38343834
_ => ExpectHasType(ty)

branches/stable/src/librustdoc/html/render.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
554554
ty: shortty(item),
555555
name: item.name.clone().unwrap(),
556556
path: fqp[..fqp.len() - 1].join("::"),
557-
desc: shorter(item.doc_value()),
557+
desc: Escape(&shorter(item.doc_value())).to_string(),
558558
parent: Some(did),
559559
search_type: get_index_search_type(&item, parent_basename),
560560
});
@@ -1065,7 +1065,7 @@ impl DocFolder for Cache {
10651065
ty: shortty(&item),
10661066
name: s.to_string(),
10671067
path: path.join("::").to_string(),
1068-
desc: shorter(item.doc_value()),
1068+
desc: Escape(&shorter(item.doc_value())).to_string(),
10691069
parent: parent,
10701070
search_type: get_index_search_type(&item, parent_basename),
10711071
});
@@ -1501,11 +1501,17 @@ impl<'a> Item<'a> {
15011501
true, |component| {
15021502
path.push(component.to_string());
15031503
});
1504-
Some(format!("{root}src/{krate}/{path}.html#{href}",
1505-
root = self.cx.root_path,
1506-
krate = self.cx.layout.krate,
1507-
path = path.join("/"),
1508-
href = href))
1504+
// If the span points into an external macro the
1505+
// source-file will be bogus, i.e `<foo macros>`
1506+
if Path::new(&self.item.source.filename).is_file() {
1507+
Some(format!("{root}src/{krate}/{path}.html#{href}",
1508+
root = self.cx.root_path,
1509+
krate = self.cx.layout.krate,
1510+
path = path.join("/"),
1511+
href = href))
1512+
} else {
1513+
None
1514+
}
15091515

15101516
// If this item is not part of the local crate, then things get a little
15111517
// trickier. We don't actually know the span of the external item, but

branches/stable/src/libstd/fs.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,6 +2151,26 @@ mod tests {
21512151
"foo");
21522152
}
21532153

2154+
#[test]
2155+
fn read_link() {
2156+
if cfg!(windows) {
2157+
// directory symlink
2158+
assert_eq!(check!(fs::read_link(r"C:\Users\All Users")).to_str().unwrap(),
2159+
r"C:\ProgramData");
2160+
// junction
2161+
assert_eq!(check!(fs::read_link(r"C:\Users\Default User")).to_str().unwrap(),
2162+
r"C:\Users\Default");
2163+
// junction with special permissions
2164+
assert_eq!(check!(fs::read_link(r"C:\Documents and Settings\")).to_str().unwrap(),
2165+
r"C:\Users");
2166+
}
2167+
let tmpdir = tmpdir();
2168+
let link = tmpdir.join("link");
2169+
if !got_symlink_permission(&tmpdir) { return };
2170+
check!(symlink_file(&"foo", &link));
2171+
assert_eq!(check!(fs::read_link(&link)).to_str().unwrap(), "foo");
2172+
}
2173+
21542174
#[test]
21552175
fn readlink_not_symlink() {
21562176
let tmpdir = tmpdir();

branches/stable/src/libstd/sys/windows/c.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
240240
pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
241241
pub const IO_REPARSE_TAG_SYMLINK: DWORD = 0xa000000c;
242242
pub const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003;
243+
pub const SYMLINK_FLAG_RELATIVE: DWORD = 0x00000001;
243244
pub const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
244245
pub const FSCTL_DELETE_REPARSE_POINT: DWORD = 0x900ac;
245246

@@ -533,6 +534,15 @@ pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
533534
pub PathBuffer: WCHAR,
534535
}
535536

537+
#[repr(C)]
538+
pub struct MOUNT_POINT_REPARSE_BUFFER {
539+
pub SubstituteNameOffset: c_ushort,
540+
pub SubstituteNameLength: c_ushort,
541+
pub PrintNameOffset: c_ushort,
542+
pub PrintNameLength: c_ushort,
543+
pub PathBuffer: WCHAR,
544+
}
545+
536546
pub type LPPROGRESS_ROUTINE = ::option::Option<unsafe extern "system" fn(
537547
TotalFileSize: LARGE_INTEGER,
538548
TotalBytesTransferred: LARGE_INTEGER,

branches/stable/src/libstd/sys/windows/fs.rs

Lines changed: 62 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,12 @@ impl DirEntry {
150150
nFileSizeHigh: self.data.nFileSizeHigh,
151151
nFileSizeLow: self.data.nFileSizeLow,
152152
},
153-
reparse_tag: self.data.dwReserved0,
153+
reparse_tag: if self.data.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
154+
// reserved unless this is a reparse point
155+
self.data.dwReserved0
156+
} else {
157+
0
158+
},
154159
})
155160
}
156161
}
@@ -240,15 +245,6 @@ impl OpenOptions {
240245
}
241246

242247
impl File {
243-
fn open_reparse_point(path: &Path, write: bool) -> io::Result<File> {
244-
let mut opts = OpenOptions::new();
245-
opts.read(!write);
246-
opts.write(write);
247-
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT |
248-
c::FILE_FLAG_BACKUP_SEMANTICS);
249-
File::open(path, &opts)
250-
}
251-
252248
pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
253249
let path = try!(to_u16s(path));
254250
let handle = unsafe {
@@ -371,19 +367,34 @@ impl File {
371367
fn readlink(&self) -> io::Result<PathBuf> {
372368
let mut space = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
373369
let (_bytes, buf) = try!(self.reparse_point(&mut space));
374-
if buf.ReparseTag != c::IO_REPARSE_TAG_SYMLINK {
375-
return Err(io::Error::new(io::ErrorKind::Other, "not a symlink"))
376-
}
377-
378370
unsafe {
379-
let info: *const c::SYMBOLIC_LINK_REPARSE_BUFFER =
380-
&buf.rest as *const _ as *const _;
381-
let path_buffer = &(*info).PathBuffer as *const _ as *const u16;
382-
let subst_off = (*info).SubstituteNameOffset / 2;
371+
let (path_buffer, subst_off, subst_len, relative) = match buf.ReparseTag {
372+
c::IO_REPARSE_TAG_SYMLINK => {
373+
let info: *const c::SYMBOLIC_LINK_REPARSE_BUFFER =
374+
&buf.rest as *const _ as *const _;
375+
(&(*info).PathBuffer as *const _ as *const u16,
376+
(*info).SubstituteNameOffset / 2,
377+
(*info).SubstituteNameLength / 2,
378+
(*info).Flags & c::SYMLINK_FLAG_RELATIVE != 0)
379+
},
380+
c::IO_REPARSE_TAG_MOUNT_POINT => {
381+
let info: *const c::MOUNT_POINT_REPARSE_BUFFER =
382+
&buf.rest as *const _ as *const _;
383+
(&(*info).PathBuffer as *const _ as *const u16,
384+
(*info).SubstituteNameOffset / 2,
385+
(*info).SubstituteNameLength / 2,
386+
false)
387+
},
388+
_ => return Err(io::Error::new(io::ErrorKind::Other,
389+
"Unsupported reparse point type"))
390+
};
383391
let subst_ptr = path_buffer.offset(subst_off as isize);
384-
let subst_len = (*info).SubstituteNameLength / 2;
385-
let subst = slice::from_raw_parts(subst_ptr, subst_len as usize);
386-
392+
let mut subst = slice::from_raw_parts(subst_ptr, subst_len as usize);
393+
// Absolute paths start with an NT internal namespace prefix `\??\`
394+
// We should not let it leak through.
395+
if !relative && subst.starts_with(&[92u16, 63u16, 63u16, 92u16]) {
396+
subst = &subst[4..];
397+
}
387398
Ok(PathBuf::from(OsString::from_wide(subst)))
388399
}
389400
}
@@ -577,8 +588,15 @@ fn remove_dir_all_recursive(path: &Path) -> io::Result<()> {
577588
rmdir(path)
578589
}
579590

580-
pub fn readlink(p: &Path) -> io::Result<PathBuf> {
581-
let file = try!(File::open_reparse_point(p, false));
591+
pub fn readlink(path: &Path) -> io::Result<PathBuf> {
592+
// Open the link with no access mode, instead of generic read.
593+
// By default FILE_LIST_DIRECTORY is denied for the junction "C:\Documents and Settings", so
594+
// this is needed for a common case.
595+
let mut opts = OpenOptions::new();
596+
opts.access_mode(0);
597+
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT |
598+
c::FILE_FLAG_BACKUP_SEMANTICS);
599+
let file = try!(File::open(&path, &opts));
582600
file.readlink()
583601
}
584602

@@ -605,42 +623,23 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
605623
Ok(())
606624
}
607625

608-
pub fn stat(p: &Path) -> io::Result<FileAttr> {
609-
let attr = try!(lstat(p));
610-
611-
// If this is a reparse point, then we need to reopen the file to get the
612-
// actual destination. We also pass the FILE_FLAG_BACKUP_SEMANTICS flag to
613-
// ensure that we can open directories (this path may be a directory
614-
// junction). Once the file is opened we ask the opened handle what its
615-
// metadata information is.
616-
if attr.is_reparse_point() {
617-
let mut opts = OpenOptions::new();
618-
// No read or write permissions are necessary
619-
opts.access_mode(0);
620-
// This flag is so we can open directories too
621-
opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS);
622-
let file = try!(File::open(p, &opts));
623-
file.file_attr()
624-
} else {
625-
Ok(attr)
626-
}
626+
pub fn stat(path: &Path) -> io::Result<FileAttr> {
627+
let mut opts = OpenOptions::new();
628+
// No read or write permissions are necessary
629+
opts.access_mode(0);
630+
// This flag is so we can open directories too
631+
opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS);
632+
let file = try!(File::open(path, &opts));
633+
file.file_attr()
627634
}
628635

629-
pub fn lstat(p: &Path) -> io::Result<FileAttr> {
630-
let u16s = try!(to_u16s(p));
631-
unsafe {
632-
let mut attr: FileAttr = mem::zeroed();
633-
try!(cvt(c::GetFileAttributesExW(u16s.as_ptr(),
634-
c::GetFileExInfoStandard,
635-
&mut attr.data as *mut _ as *mut _)));
636-
if attr.is_reparse_point() {
637-
attr.reparse_tag = File::open_reparse_point(p, false).and_then(|f| {
638-
let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
639-
f.reparse_point(&mut b).map(|(_, b)| b.ReparseTag)
640-
}).unwrap_or(0);
641-
}
642-
Ok(attr)
643-
}
636+
pub fn lstat(path: &Path) -> io::Result<FileAttr> {
637+
let mut opts = OpenOptions::new();
638+
// No read or write permissions are necessary
639+
opts.access_mode(0);
640+
opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS | c::FILE_FLAG_OPEN_REPARSE_POINT);
641+
let file = try!(File::open(path, &opts));
642+
file.file_attr()
644643
}
645644

646645
pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
@@ -709,7 +708,12 @@ pub fn symlink_junction<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::R
709708
fn symlink_junction_inner(target: &Path, junction: &Path) -> io::Result<()> {
710709
let d = DirBuilder::new();
711710
try!(d.mkdir(&junction));
712-
let f = try!(File::open_reparse_point(junction, true));
711+
712+
let mut opts = OpenOptions::new();
713+
opts.write(true);
714+
opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT |
715+
c::FILE_FLAG_BACKUP_SEMANTICS);
716+
let f = try!(File::open(junction, &opts));
713717
let h = f.handle().raw();
714718

715719
unsafe {

0 commit comments

Comments
 (0)