@@ -4263,8 +4263,7 @@ fn test_ls_context_long() {
4263
4263
let line: Vec < _ > = result. stdout_str ( ) . split ( ' ' ) . collect ( ) ;
4264
4264
assert ! ( line[ 0 ] . ends_with( '.' ) ) ;
4265
4265
assert ! ( line[ 4 ] . starts_with( "unconfined_u" ) ) ;
4266
- let s: Vec < _ > = line[ 4 ] . split ( ':' ) . collect ( ) ;
4267
- assert ! ( s. len( ) == 4 ) ;
4266
+ validate_selinux_context ( line[ 4 ] ) ;
4268
4267
}
4269
4268
}
4270
4269
@@ -4298,6 +4297,100 @@ fn test_ls_context_format() {
4298
4297
}
4299
4298
}
4300
4299
4300
+ /// Helper function to validate `SELinux` context format
4301
+ /// Returns the context parts if valid, panics with descriptive message if invalid
4302
+ #[ cfg( feature = "feat_selinux" ) ]
4303
+ fn validate_selinux_context ( context : & str ) -> Vec < & str > {
4304
+ assert ! (
4305
+ context. contains( ':' ) ,
4306
+ "Expected SELinux context format (user:role:type:level), got: {}" ,
4307
+ context
4308
+ ) ;
4309
+
4310
+ let context_parts: Vec < & str > = context. split ( ':' ) . collect ( ) ;
4311
+ assert_eq ! (
4312
+ context_parts. len( ) ,
4313
+ 4 ,
4314
+ "SELinux context should have 4 components separated by colons, got: {}" ,
4315
+ context
4316
+ ) ;
4317
+
4318
+ context_parts
4319
+ }
4320
+
4321
+ #[ test]
4322
+ #[ cfg( feature = "feat_selinux" ) ]
4323
+ fn test_ls_selinux_context_indicator ( ) {
4324
+ if !uucore:: selinux:: is_selinux_enabled ( ) {
4325
+ println ! ( "test skipped: Kernel has no support for SElinux context" ) ;
4326
+ return ;
4327
+ }
4328
+
4329
+ let scene = TestScenario :: new ( util_name ! ( ) ) ;
4330
+ let at = & scene. fixtures ;
4331
+
4332
+ at. touch ( "file" ) ;
4333
+ at. symlink_file ( "file" , "link" ) ;
4334
+
4335
+ // Test that ls -l shows "." indicator for files with SELinux contexts
4336
+ for file in [ "file" , "link" ] {
4337
+ let result = scene. ucmd ( ) . args ( & [ "-l" , file] ) . succeeds ( ) ;
4338
+ let output = result. stdout_str ( ) ;
4339
+
4340
+ // The 11th character should be "." indicating SELinux context
4341
+ // -rw-rw-r--. (permissions + context indicator)
4342
+ let lines: Vec < & str > = output. lines ( ) . collect ( ) ;
4343
+ assert ! ( !lines. is_empty( ) , "Output should contain at least one line" ) ;
4344
+
4345
+ let first_line = lines[ 0 ] ;
4346
+ let chars: Vec < char > = first_line. chars ( ) . collect ( ) ;
4347
+ assert ! (
4348
+ chars. len( ) >= 11 ,
4349
+ "Line should be at least 11 characters long"
4350
+ ) ;
4351
+
4352
+ // The 11th character (0-indexed position 10) should be "." for SELinux context
4353
+ assert_eq ! (
4354
+ chars[ 10 ] , '.' ,
4355
+ "Expected '.' indicator for SELinux context in position 11, got '{}' in line: {}" ,
4356
+ chars[ 10 ] , first_line
4357
+ ) ;
4358
+ }
4359
+ }
4360
+
4361
+ #[ test]
4362
+ #[ cfg( feature = "feat_selinux" ) ]
4363
+ fn test_ls_selinux_context_format ( ) {
4364
+ if !uucore:: selinux:: is_selinux_enabled ( ) {
4365
+ println ! ( "test skipped: Kernel has no support for SElinux context" ) ;
4366
+ return ;
4367
+ }
4368
+
4369
+ let scene = TestScenario :: new ( util_name ! ( ) ) ;
4370
+ let at = & scene. fixtures ;
4371
+
4372
+ at. touch ( "file" ) ;
4373
+ at. symlink_file ( "file" , "link" ) ;
4374
+
4375
+ // Test that ls -lnZ properly shows the context
4376
+ for file in [ "file" , "link" ] {
4377
+ let result = scene. ucmd ( ) . args ( & [ "-lnZ" , file] ) . succeeds ( ) ;
4378
+ let output = result. stdout_str ( ) ;
4379
+
4380
+ let lines: Vec < & str > = output. lines ( ) . collect ( ) ;
4381
+ assert ! ( !lines. is_empty( ) , "Output should contain at least one line" ) ;
4382
+
4383
+ let first_line = lines[ 0 ] ;
4384
+ let parts: Vec < & str > = first_line. split_whitespace ( ) . collect ( ) ;
4385
+ assert ! ( parts. len( ) >= 6 , "Line should have at least 6 fields" ) ;
4386
+
4387
+ // The 5th field (0-indexed position 4) should contain the SELinux context
4388
+ // Format: permissions links owner group context size date time name
4389
+ let context = parts[ 4 ] ;
4390
+ validate_selinux_context ( context) ;
4391
+ }
4392
+ }
4393
+
4301
4394
#[ test]
4302
4395
#[ allow( non_snake_case) ]
4303
4396
fn test_ls_a_A ( ) {
0 commit comments