@@ -25,7 +25,11 @@ const INCLUDE_LIMIT: u8 = 128;
25
25
26
26
/// Export some necessary symbols from modules
27
27
pub use ast:: TextEnum ;
28
- pub struct Error ( pub Option < basic_parser:: Position > , pub String ) ;
28
+ pub struct Error {
29
+ pub source : Option < PathBuf > ,
30
+ pub location : Option < basic_parser:: Position > ,
31
+ pub message : String ,
32
+ }
29
33
30
34
#[ derive( Default ) ]
31
35
pub struct Sudoers {
@@ -587,12 +591,19 @@ fn analyze(
587
591
}
588
592
589
593
impl Sudoers {
590
- fn include ( & mut self , path : & Path , diagnostics : & mut Vec < Error > , count : & mut u8 ) {
594
+ fn include (
595
+ & mut self ,
596
+ parent : & Path ,
597
+ path : & Path ,
598
+ diagnostics : & mut Vec < Error > ,
599
+ count : & mut u8 ,
600
+ ) {
591
601
if * count >= INCLUDE_LIMIT {
592
- diagnostics. push ( Error (
593
- None ,
594
- format ! ( "include file limit reached opening '{}'" , path. display( ) ) ,
595
- ) )
602
+ diagnostics. push ( Error {
603
+ source : Some ( parent. to_owned ( ) ) ,
604
+ location : None ,
605
+ message : format ! ( "include file limit reached opening '{}'" , path. display( ) ) ,
606
+ } )
596
607
// FIXME: this will cause an error in `visudo` if we open a non-privileged sudoers file
597
608
// that includes another non-privileged sudoer files.
598
609
} else {
@@ -609,7 +620,11 @@ fn analyze(
609
620
e. to_string ( )
610
621
} ;
611
622
612
- diagnostics. push ( Error ( None , message) )
623
+ diagnostics. push ( Error {
624
+ source : Some ( parent. to_owned ( ) ) ,
625
+ location : None ,
626
+ message,
627
+ } )
613
628
}
614
629
}
615
630
}
@@ -641,25 +656,28 @@ fn analyze(
641
656
}
642
657
643
658
Sudo :: Include ( path) => self . include (
659
+ cur_path,
644
660
& resolve_relative ( cur_path, path) ,
645
661
diagnostics,
646
662
safety_count,
647
663
) ,
648
664
649
665
Sudo :: IncludeDir ( path) => {
650
666
if path. contains ( "%h" ) {
651
- diagnostics. push ( Error (
652
- None ,
653
- format ! ( "cannot open sudoers file {path}: percent escape %h in includedir is unsupported" ) ) ) ;
667
+ diagnostics. push ( Error {
668
+ source : Some ( cur_path. to_owned ( ) ) ,
669
+ location : None ,
670
+ message : format ! ( "cannot open sudoers file {path}: percent escape %h in includedir is unsupported" ) } ) ;
654
671
continue ;
655
672
}
656
673
657
674
let path = resolve_relative ( cur_path, path) ;
658
675
let Ok ( files) = std:: fs:: read_dir ( & path) else {
659
- diagnostics. push ( Error (
660
- None ,
661
- format ! ( "cannot open sudoers file {}" , path. display( ) ) ,
662
- ) ) ;
676
+ diagnostics. push ( Error {
677
+ source : Some ( cur_path. to_owned ( ) ) ,
678
+ location : None ,
679
+ message : format ! ( "cannot open sudoers file {}" , path. display( ) ) ,
680
+ } ) ;
663
681
continue ;
664
682
} ;
665
683
let mut safe_files = files
@@ -675,14 +693,16 @@ fn analyze(
675
693
. collect :: < Vec < _ > > ( ) ;
676
694
safe_files. sort ( ) ;
677
695
for file in safe_files {
678
- self . include ( file. as_ref ( ) , diagnostics, safety_count)
696
+ self . include ( cur_path , file. as_ref ( ) , diagnostics, safety_count)
679
697
}
680
698
}
681
699
} ,
682
700
683
- Err ( basic_parser:: Status :: Fatal ( pos, error) ) => {
684
- diagnostics. push ( Error ( Some ( pos) , error) )
685
- }
701
+ Err ( basic_parser:: Status :: Fatal ( pos, message) ) => diagnostics. push ( Error {
702
+ source : Some ( cur_path. to_owned ( ) ) ,
703
+ location : Some ( pos) ,
704
+ message,
705
+ } ) ,
686
706
Err ( _) => panic ! ( "internal parser error" ) ,
687
707
}
688
708
}
@@ -756,7 +776,11 @@ fn sanitize_alias_table<T>(table: &Vec<Def<T>>, diagnostics: &mut Vec<Error>) ->
756
776
757
777
impl < T > Visitor < ' _ , T > {
758
778
fn complain ( & mut self , text : String ) {
759
- self . diagnostics . push ( Error ( None , text) )
779
+ self . diagnostics . push ( Error {
780
+ source : None ,
781
+ location : None ,
782
+ message : text,
783
+ } )
760
784
}
761
785
762
786
fn visit ( & mut self , pos : usize ) {
0 commit comments