diff options
author | Sendil Kumar <sendilkumarn@live.com> | 2019-08-22 13:17:02 +0200 |
---|---|---|
committer | Sendil Kumar <sendilkumarn@live.com> | 2019-08-22 13:17:02 +0200 |
commit | ea102096803dd12acf5fc592fb5c581e9b9ff51d (patch) | |
tree | dba4e53b9ea454efc8fd4d4ee4b85e7ff9516c0b | |
parent | 414cc86c0af09fd44454b93b6dc738316b16c43c (diff) | |
download | nix-ea102096803dd12acf5fc592fb5c581e9b9ff51d.zip |
fix readlink/readlinkat to return too long only when it is long
-rw-r--r-- | src/fcntl.rs | 4 | ||||
-rw-r--r-- | test/test_fcntl.rs | 19 |
2 files changed, 18 insertions, 5 deletions
diff --git a/src/fcntl.rs b/src/fcntl.rs index be6ee0f7..f590e361 100644 --- a/src/fcntl.rs +++ b/src/fcntl.rs @@ -181,7 +181,9 @@ fn wrap_readlink_result(buffer: &mut[u8], res: ssize_t) -> Result<&OsStr> { match Errno::result(res) { Err(err) => Err(err), Ok(len) => { - if (len as usize) >= buffer.len() { + if len < 0 { + Err(Error::Sys(Errno::EINVAL)) + } else if (len as usize) > buffer.len() { Err(Error::Sys(Errno::ENAMETOOLONG)) } else { Ok(OsStr::from_bytes(&buffer[..(len as usize)])) diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs index 6b2bbd67..c8773219 100644 --- a/test/test_fcntl.rs +++ b/test/test_fcntl.rs @@ -56,12 +56,23 @@ fn test_readlink() { let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); + let expected_dir = src.to_str().unwrap(); + // When the size of the buffer is bigger than the expected directory length let mut buf = vec![0; src.to_str().unwrap().len() + 1]; - assert_eq!(readlink(&dst, &mut buf).unwrap().to_str().unwrap(), - src.to_str().unwrap()); - assert_eq!(readlinkat(dirfd, "b", &mut buf).unwrap().to_str().unwrap(), - src.to_str().unwrap()); + assert_eq!(readlink(&dst, &mut buf).unwrap().to_str().unwrap(), expected_dir); + assert_eq!(readlinkat(dirfd, "b", &mut buf).unwrap().to_str().unwrap(), expected_dir); + + // When the size of the buffer is equal to the expected directory length + let mut exact_buf = vec![0; src.to_str().unwrap().len()]; + assert_eq!(readlink(&dst, &mut exact_buf).unwrap().to_str().unwrap(), expected_dir); + assert_eq!(readlinkat(dirfd, "b", &mut exact_buf).unwrap().to_str().unwrap(), expected_dir); + + // When the size of the buffer is smaller than the expected directory length + let mut small_buf = vec![0;0]; + assert_eq!(readlink(&dst, &mut small_buf).unwrap().to_str().unwrap(), ""); + assert_eq!(readlinkat(dirfd, "b", &mut small_buf).unwrap().to_str().unwrap(), ""); + } #[cfg(any(target_os = "linux", target_os = "android"))] |