@@ -1058,11 +1058,29 @@ fn dotdot_in_middle_of_symlink() {
1058
1058
assert_eq ! ( data, foo) ;
1059
1059
}
1060
1060
1061
+ /// Like `dotdot_in_middle_of_symlink` but with a `/.` at the end.
1062
+ #[ test]
1063
+ fn dotdot_slashdot_in_middle_of_symlink ( ) {
1064
+ let tmpdir = tmpdir ( ) ;
1065
+
1066
+ let foo = b"foo" ;
1067
+ check ! ( tmpdir. write( "target" , foo) ) ;
1068
+ check ! ( tmpdir. create_dir( "b" ) ) ;
1069
+ let b = check ! ( tmpdir. open_dir( "b" ) ) ;
1070
+ check ! ( symlink_dir( "../." , & b, "up" ) ) ;
1071
+
1072
+ let path = "b/up/target" ;
1073
+ let mut file = check ! ( tmpdir. open( path) ) ;
1074
+ let mut data = Vec :: new ( ) ;
1075
+ check ! ( file. read_to_end( & mut data) ) ;
1076
+ assert_eq ! ( data, foo) ;
1077
+ }
1078
+
1061
1079
/// Same as `dotdot_in_middle_of_symlink`, but use two levels of `..`.
1062
1080
///
1063
1081
/// This fails on Windows for unknown reasons. Patches welcome.
1064
1082
#[ test]
1065
- #[ cfg( not( windows) ) ]
1083
+ // #[cfg(not(windows))]
1066
1084
fn dotdot_more_in_middle_of_symlink ( ) {
1067
1085
let tmpdir = tmpdir ( ) ;
1068
1086
@@ -1079,12 +1097,31 @@ fn dotdot_more_in_middle_of_symlink() {
1079
1097
assert_eq ! ( data, foo) ;
1080
1098
}
1081
1099
1100
+ /// Like `dotdot_more_in_middle_of_symlink`, but with a `/.` at the end.
1101
+ #[ test]
1102
+ //#[cfg(not(windows))]
1103
+ fn dotdot_slashdot_more_in_middle_of_symlink ( ) {
1104
+ let tmpdir = tmpdir ( ) ;
1105
+
1106
+ let foo = b"foo" ;
1107
+ check ! ( tmpdir. write( "target" , foo) ) ;
1108
+ check ! ( tmpdir. create_dir_all( "b/c" ) ) ;
1109
+ let b = check ! ( tmpdir. open_dir( "b" ) ) ;
1110
+ check ! ( symlink_dir( "c/../../." , & b, "up" ) ) ;
1111
+
1112
+ let path = "b/up/target" ;
1113
+ let mut file = check ! ( tmpdir. open( path) ) ;
1114
+ let mut data = Vec :: new ( ) ;
1115
+ check ! ( file. read_to_end( & mut data) ) ;
1116
+ assert_eq ! ( data, foo) ;
1117
+ }
1118
+
1082
1119
/// Same as `dotdot_more_in_middle_of_symlink`, but the symlink doesn't
1083
1120
/// include `c`.
1084
1121
///
1085
1122
/// This fails on Windows for unknown reasons. Patches welcome.
1086
1123
#[ test]
1087
- #[ cfg( not( windows) ) ]
1124
+ // #[cfg(not(windows))]
1088
1125
fn dotdot_other_in_middle_of_symlink ( ) {
1089
1126
let tmpdir = tmpdir ( ) ;
1090
1127
@@ -1101,6 +1138,25 @@ fn dotdot_other_in_middle_of_symlink() {
1101
1138
assert_eq ! ( data, foo) ;
1102
1139
}
1103
1140
1141
+ /// Like `dotdot_other_in_middle_of_symlink`, but with `/.` at the end.
1142
+ #[ test]
1143
+ //#[cfg(not(windows))]
1144
+ fn dotdot_slashdot_other_in_middle_of_symlink ( ) {
1145
+ let tmpdir = tmpdir ( ) ;
1146
+
1147
+ let foo = b"foo" ;
1148
+ check ! ( tmpdir. write( "target" , foo) ) ;
1149
+ check ! ( tmpdir. create_dir_all( "b/c" ) ) ;
1150
+ let c = check ! ( tmpdir. open_dir( "b/c" ) ) ;
1151
+ check ! ( symlink_dir( "../../." , & c, "up" ) ) ;
1152
+
1153
+ let path = "b/c/up/target" ;
1154
+ let mut file = check ! ( tmpdir. open( path) ) ;
1155
+ let mut data = Vec :: new ( ) ;
1156
+ check ! ( file. read_to_end( & mut data) ) ;
1157
+ assert_eq ! ( data, foo) ;
1158
+ }
1159
+
1104
1160
/// Same as `dotdot_more_in_middle_of_symlink`, but use a symlink that
1105
1161
/// doesn't end with `..`.
1106
1162
#[ test]
@@ -1120,6 +1176,24 @@ fn dotdot_even_more_in_middle_of_symlink() {
1120
1176
assert_eq ! ( data, foo) ;
1121
1177
}
1122
1178
1179
+ /// Like `dotdot_even_more_in_middle_of_symlink`, but with a `/.` at the end.
1180
+ #[ test]
1181
+ fn dotdot_slashdot_even_more_in_middle_of_symlink ( ) {
1182
+ let tmpdir = tmpdir ( ) ;
1183
+
1184
+ let foo = b"foo" ;
1185
+ check ! ( tmpdir. create_dir_all( "b/c" ) ) ;
1186
+ check ! ( tmpdir. write( "b/target" , foo) ) ;
1187
+ let b = check ! ( tmpdir. open_dir( "b" ) ) ;
1188
+ check ! ( symlink_dir( "c/../../b/." , & b, "up" ) ) ;
1189
+
1190
+ let path = "b/up/target" ;
1191
+ let mut file = check ! ( tmpdir. open( path) ) ;
1192
+ let mut data = Vec :: new ( ) ;
1193
+ check ! ( file. read_to_end( & mut data) ) ;
1194
+ assert_eq ! ( data, foo) ;
1195
+ }
1196
+
1123
1197
/// Same as `dotdot_even_more_in_middle_of_symlink`, but the symlink doesn't
1124
1198
/// include `c`.
1125
1199
#[ test]
@@ -1139,6 +1213,24 @@ fn dotdot_even_other_in_middle_of_symlink() {
1139
1213
assert_eq ! ( data, foo) ;
1140
1214
}
1141
1215
1216
+ /// Like `dotdot_even_other_in_middle_of_symlink`, but with a `/.` at the end.
1217
+ #[ test]
1218
+ fn dotdot_slashdot_even_other_in_middle_of_symlink ( ) {
1219
+ let tmpdir = tmpdir ( ) ;
1220
+
1221
+ let foo = b"foo" ;
1222
+ check ! ( tmpdir. create_dir_all( "b/c" ) ) ;
1223
+ check ! ( tmpdir. write( "b/target" , foo) ) ;
1224
+ let c = check ! ( tmpdir. open_dir( "b/c" ) ) ;
1225
+ check ! ( symlink_dir( "../../b/." , & c, "up" ) ) ;
1226
+
1227
+ let path = "b/c/up/target" ;
1228
+ let mut file = check ! ( tmpdir. open( path) ) ;
1229
+ let mut data = Vec :: new ( ) ;
1230
+ check ! ( file. read_to_end( & mut data) ) ;
1231
+ assert_eq ! ( data, foo) ;
1232
+ }
1233
+
1142
1234
/// Similar to `dotdot_in_middle_of_symlink`, but this time the symlink to
1143
1235
/// `..` does happen to be the end of the path, so we need to make sure
1144
1236
/// the implementation doesn't just do a stack pop when it sees the `..`
@@ -1167,6 +1259,31 @@ fn dotdot_at_end_of_symlink() {
1167
1259
}
1168
1260
}
1169
1261
1262
+ /// Like `dotdot_at_end_of_symlink`, but with a `/.` at the end.
1263
+ #[ test]
1264
+ fn dotdot_slashdot_at_end_of_symlink ( ) {
1265
+ let tmpdir = tmpdir ( ) ;
1266
+
1267
+ let foo = b"foo" ;
1268
+ check ! ( tmpdir. write( "target" , foo) ) ;
1269
+ check ! ( tmpdir. create_dir( "b" ) ) ;
1270
+ let b = check ! ( tmpdir. open_dir( "b" ) ) ;
1271
+ check ! ( symlink_dir( "../." , & b, "up" ) ) ;
1272
+
1273
+ // Do some things with `path` that might break with an `O_PATH` fd.
1274
+ // On Linux, the `permissions` part doesn't because cap-std uses
1275
+ // /proc/self/fd. But the `read_dir` part does.
1276
+ let path = "b/up" ;
1277
+
1278
+ let perms = check ! ( tmpdir. metadata( path) ) . permissions ( ) ;
1279
+ check ! ( tmpdir. set_permissions( path, perms) ) ;
1280
+
1281
+ let contents = check ! ( tmpdir. read_dir( path) ) ;
1282
+ for entry in contents {
1283
+ let _entry = check ! ( entry) ;
1284
+ }
1285
+ }
1286
+
1170
1287
/// Like `dotdot_at_end_of_symlink`, but do everything inside a new directory,
1171
1288
/// so that `MaybeOwnedFile` doesn't reopen `.` which would artificially give
1172
1289
/// us a non-`O_PATH` fd.
@@ -1194,3 +1311,29 @@ fn dotdot_at_end_of_symlink_all_inside_dir() {
1194
1311
let _entry = check ! ( entry) ;
1195
1312
}
1196
1313
}
1314
+
1315
+ /// `dotdot_at_end_of_symlink_all_inside_dir`, but with a `/.` at the end.
1316
+ #[ test]
1317
+ fn dotdot_slashdot_at_end_of_symlink_all_inside_dir ( ) {
1318
+ let tmpdir = tmpdir ( ) ;
1319
+
1320
+ let foo = b"foo" ;
1321
+ check ! ( tmpdir. create_dir( "dir" ) ) ;
1322
+ check ! ( tmpdir. write( "dir/target" , foo) ) ;
1323
+ check ! ( tmpdir. create_dir( "dir/b" ) ) ;
1324
+ let b = check ! ( tmpdir. open_dir( "dir/b" ) ) ;
1325
+ check ! ( symlink_dir( "../." , & b, "up" ) ) ;
1326
+
1327
+ // Do some things with `path` that might break with an `O_PATH` fd.
1328
+ // On Linux, the `permissions` part doesn't because cap-std uses
1329
+ // /proc/self/fd. But the `read_dir` part does.
1330
+ let path = "dir/b/up" ;
1331
+
1332
+ let perms = check ! ( tmpdir. metadata( path) ) . permissions ( ) ;
1333
+ check ! ( tmpdir. set_permissions( path, perms) ) ;
1334
+
1335
+ let contents = check ! ( tmpdir. read_dir( path) ) ;
1336
+ for entry in contents {
1337
+ let _entry = check ! ( entry) ;
1338
+ }
1339
+ }
0 commit comments