trailofbits.rs.panic-in-function-returning-result.panic-in-function-returning-result

profile photo of trailofbitstrailofbits
Author
unknown
Download Count*

expect or unwrap called in function returning a Result

Run Locally

Run in CI

Defintion

rules:
  - id: panic-in-function-returning-result
    message: "`expect` or `unwrap` called in function returning a `Result`"
    languages:
      - rust
    severity: WARNING
    metadata:
      category: security
      cwe: "CWE-755: Improper Handling of Exceptional Conditions"
      subcategory:
        - audit
      confidence: HIGH
      likelihood: MEDIUM
      impact: LOW
      technology:
        - --no-technology--
      description: Calling `unwrap` or `expect` in a function returning a `Result`
      references:
        - https://doc.rust-lang.org/std/result/
      license: AGPL-3.0 license
      vulnerability_class:
        - Other
    patterns:
      - pattern-either:
          - pattern: $EXPR.unwrap()
          - pattern: $EXPR.expect(...)
      - pattern-either:
          - pattern-inside: |
              fn $FUNC(...) -> Result<$T1, $T2> {
                  ...
              }
          - pattern-inside: |
              fn $FUNC(...) -> Result<$T> {
                  ...
              }
          - patterns:
              - pattern-inside: |
                  fn $FUNC(...) -> $RETTYPE {
                      ...
                  }
              - pattern-either:
                  - pattern-inside: |
                      type $RETTYPE = Result<$T>;
                      ...
                      fn $FUNC(...) -> $RETTYPE {
                          ...
                      }
                  - pattern-inside: |
                      type $RETTYPE = Result<$T1, $T2>;
                      ...
                      fn $FUNC(...) -> $RETTYPE {
                          ...
                      }

Examples

panic-in-function-returning-result.rs

use std::io;
use std::fs::File;
use std::io::Read;
use std::convert::TryInto;

fn main() {
    println!("Enter a file name: ");
    let mut input = String::new();

    io::stdin().read_line(&mut input)
        .expect("error: unable to read user input");

    let _ = match get_file_content(&input.trim()) {
        Ok(c)  =>     println!("{}", c),
        Err(e) => panic!("Unable to parse file. {}", e),
    };

    match get_file_content_2(&input.trim()){
        Ok(_) => println!("Success"),
        Err(e) => panic!("{}", e)
    }

    get_file_content_3(&input).unwrap();
    get_file_content_4(&input).unwrap();
}

fn get_file_content(path:&str) -> Result<String, std::io::Error> {
    // ruleid: panic-in-function-returning-result
    let mut f = File::open(path).unwrap();
    let mut s = String::new();
    // ruleid: panic-in-function-returning-result
    f.read_to_string(&mut s).expect("oh");
    return Ok(s)
}

fn get_file_content_2(path:&str) -> io::Result<()> {    
    // ruleid: panic-in-function-returning-result
    let mut f = File::open(path).expect("uh");
    let mut s = String::new();
    // ruleid: panic-in-function-returning-result
    f.read_to_string(&mut s).unwrap();
    println!("{}", s);
    return Ok(())
}


type CustomResult = Result<f64, String>;

thread_local!(static GLOB: [i32; 10] = {
    // ok: panic-in-function-returning-result
    (0..10).collect::<Vec<i32>>().try_into().unwrap()
});

fn get_file_content_3(path:&str) -> CustomResult {    
    // ruleid: panic-in-function-returning-result
    let mut f = File::open(path).unwrap();
    let mut s = String::new();
    // ruleid: panic-in-function-returning-result
    f.read_to_string(&mut s).unwrap();
    println!("{}", s);
    return Ok(1.)
}


fn get_file_content_4(path:&str) -> io::Result<()> {    
    // ok: panic-in-function-returning-result
    let mut f = File::open(path)?;
    let mut s = String::new();
    // ok: panic-in-function-returning-result
    f.read_to_string(&mut s)?;
    println!("{}", s);
    return Ok(())
}