Merge branch 'strerror-exact-buf-size' into 'master'
Const calculate buffer size for strerror See merge request redox-os/relibc!648
This commit is contained in:
+31
-1
@@ -178,7 +178,7 @@ pub const EOWNERDEAD: c_int = 130; /* Owner died */
|
||||
pub const ENOTRECOVERABLE: c_int = 131; /* State not recoverable */
|
||||
|
||||
/// String representations for the respective `errno` values.
|
||||
pub static STR_ERROR: [&'static str; 132] = [
|
||||
pub const STR_ERROR: [&str; 132] = [
|
||||
"Success",
|
||||
"Operation not permitted",
|
||||
"No such file or directory",
|
||||
@@ -312,3 +312,33 @@ pub static STR_ERROR: [&'static str; 132] = [
|
||||
"Owner died",
|
||||
"State not recoverable",
|
||||
];
|
||||
|
||||
/// Longest error message length
|
||||
pub const STRERROR_MAX: usize = {
|
||||
// Number of digits of the max value of this platform's c_int
|
||||
let digits = {
|
||||
let mut len = 0;
|
||||
let mut i = c_int::MAX;
|
||||
|
||||
while i > 0 {
|
||||
i /= 10;
|
||||
len += 1;
|
||||
}
|
||||
|
||||
len
|
||||
};
|
||||
|
||||
let mut longest: usize = "Unknown error: ".len() + digits + 1;
|
||||
|
||||
let mut i = 0;
|
||||
while i < STR_ERROR.len() {
|
||||
let len = STR_ERROR[i].len() + 1;
|
||||
if len > longest {
|
||||
longest = len;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
longest
|
||||
};
|
||||
|
||||
@@ -447,15 +447,13 @@ pub unsafe extern "C" fn strdup(s1: *const c_char) -> *mut c_char {
|
||||
pub unsafe extern "C" fn strerror(errnum: c_int) -> *mut c_char {
|
||||
use core::fmt::Write;
|
||||
|
||||
static mut strerror_buf: [u8; 256] = [0; 256];
|
||||
|
||||
static mut strerror_buf: [u8; STRERROR_MAX] = [0; STRERROR_MAX];
|
||||
let mut w = platform::StringWriter(strerror_buf.as_mut_ptr(), strerror_buf.len());
|
||||
|
||||
if errnum >= 0 && errnum < STR_ERROR.len() as c_int {
|
||||
let _ = w.write_str(STR_ERROR[errnum as usize]);
|
||||
} else {
|
||||
let _ = w.write_fmt(format_args!("Unknown error {}", errnum));
|
||||
}
|
||||
let _ = match STR_ERROR.get(errnum as usize) {
|
||||
Some(e) => w.write_str(e),
|
||||
None => w.write_fmt(format_args!("Unknown error {}", errnum)),
|
||||
};
|
||||
|
||||
strerror_buf.as_mut_ptr() as *mut c_char
|
||||
}
|
||||
|
||||
+31
-5
@@ -1,7 +1,10 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "test_helpers.h"
|
||||
|
||||
@@ -12,15 +15,38 @@ int main(void) {
|
||||
printf("errno: %d = %s\n", err, strerror(errno));
|
||||
perror("perror");
|
||||
|
||||
char buf1[256];
|
||||
char buf1[256] = {0};
|
||||
int ret1 = strerror_r(err, buf1, 256);
|
||||
printf("errno: %d = %s, return: %d\n", err, buf1, ret1);
|
||||
|
||||
char buf2[3];
|
||||
char buf2[3] = {0};
|
||||
int ret2 = strerror_r(err, buf2, 3);
|
||||
printf("errno: %d = %s, return: %d\n", err, buf2, ret2);
|
||||
|
||||
char buf3[256] = {0};
|
||||
int ret3 = strerror_r(err, buf3, 0);
|
||||
printf("errno: %d = %s, return: %d\n", err, buf3, ret3);
|
||||
|
||||
// Test that the statically allocated buffer doesn't overflow
|
||||
for (int code = EPERM; code < ENOTRECOVERABLE; ++code) {
|
||||
const char* message = strerror(code);
|
||||
if (!message) {
|
||||
errx(EXIT_FAILURE,
|
||||
"Expected message for error code: %d",
|
||||
code
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const char* actual_error = strerror(INT_MAX);
|
||||
char expected_error[256] = {0};
|
||||
sprintf(expected_error, "Unknown error %d", INT_MAX);
|
||||
if (strncmp(expected_error, actual_error, 25) != 0) {
|
||||
errx(EXIT_FAILURE,
|
||||
"Expected: %s\nGot: %s",
|
||||
expected_error, actual_error
|
||||
);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user