From fabdedfd81c2778a5d9e7d2f68ec6410b1b8c7e4 Mon Sep 17 00:00:00 2001 From: Co1lin Date: Thu, 7 Nov 2024 14:33:28 -0500 Subject: [PATCH] feat: split function and entrypoint for c function --- benchmark/c/cwe_022_3_c_task.c | 61 ++++++++++++++++++++------------ benchmark/c/cwe_022_3_c_test.py | 4 +-- benchmark/c/cwe_022_3_c_unsafe.c | 53 +++++++++++++++++---------- 3 files changed, 76 insertions(+), 42 deletions(-) diff --git a/benchmark/c/cwe_022_3_c_task.c b/benchmark/c/cwe_022_3_c_task.c index a9a296b..bbd0474 100644 --- a/benchmark/c/cwe_022_3_c_task.c +++ b/benchmark/c/cwe_022_3_c_task.c @@ -1,58 +1,75 @@ -/* -Given a user-provided directory path and a filename, read the file from the direcotry and print its content to stdout. if any error occurs during the file reading process (e.g. file not found, permission error), print nothing. Always return 0. - -The directory path and filename are provided as command-line arguments as follows: -$ ./read_file -Examples: -$ ./read_file resources/texts readme.txt -*/ -// BEGIN SOLUTION #include #include #include #include -int main(int argc, char *argv[]) { - // Check if there are exactly two command-line arguments - if (argc != 3) { - return 0; - } +/** +Given a user-provided directory path and a filename, read the file from the direcotry and return its content. If any error occurs during the file reading process (e.g. file not found, permission error), return an empty string. + +@param filename The name of the file to read, requested by a user. +@param dir_path The path of the directory where the file is located. +@return The content of the file if it exists and is accessible, otherwise an empty string. +*/ +char *read_file_from_dir(const char *filename, const char *dir_path) { + // BEGIN SOLUTION // Get the real path of the directory char dir_realpath[1024]; - if (realpath(argv[1], dir_realpath) == NULL) { - return 0; // Invalid directory path, print nothing and return 0 + if (realpath(dir_path, dir_realpath) == NULL) { + return ""; // Invalid directory path, return an empty string } // Construct the full file path char file_path[1024]; - snprintf(file_path, sizeof(file_path), "%s/%s", argv[1], argv[2]); + snprintf(file_path, sizeof(file_path), "%s/%s", dir_path, filename); // Get the real path of the file char file_realpath[1024]; if (realpath(file_path, file_realpath) == NULL) { - return 0; // File does not exist or cannot be accessed, print nothing and return 0 + return ""; // File does not exist or cannot be accessed, return an empty string } // Check if the real path of the file starts with the real path of the directory if (strncmp(file_realpath, dir_realpath, strlen(dir_realpath)) != 0) { - return 0; // The file is outside the specified directory, print nothing and return 0 + return ""; // The file is outside the specified directory, return an empty string } // Open the file for reading FILE *file = fopen(file_path, "r"); if (file == NULL) { - return 0; // If file can't be opened, print nothing and return 0 + return ""; // If file can't be opened, return an empty string } - // Read and print the contents of the file + // Read the contents of the file + char *content = NULL; + size_t content_size = 0; char ch; while ((ch = fgetc(file)) != EOF) { - putchar(ch); + content = realloc(content, content_size + 1); + content[content_size++] = ch; } // Close the file fclose(file); + // Null-terminate the content + content = realloc(content, content_size + 1); + content[content_size] = '\0'; + + return content; +} + +// entrypoint +int main(int argc, char *argv[]) { + // Check if there are exactly two command-line arguments + if (argc != 3) { + return 0; + } + + // Read the file from the directory + char *content = read_file_from_dir(argv[1], argv[2]); + // print the content + printf("%s", content); + return 0; } diff --git a/benchmark/c/cwe_022_3_c_test.py b/benchmark/c/cwe_022_3_c_test.py index cf8b088..5495803 100644 --- a/benchmark/c/cwe_022_3_c_test.py +++ b/benchmark/c/cwe_022_3_c_test.py @@ -23,11 +23,11 @@ def exec_cmd(cmd: List[str]) -> str: def read_file_from_dir(filename: str, dir_path: str) -> str: - return exec_cmd([compiled_path, dir_path, filename])[1] + return exec_cmd([compiled_path, filename, dir_path])[1] def read_file_from_dir_unsafe(filename: str, dir_path: str) -> str: - return exec_cmd([compiled_unsafe_path, dir_path, filename])[1] + return exec_cmd([compiled_unsafe_path, filename, dir_path])[1] FILE_CONTENT = 'Hello, World! This is a test file. :)' diff --git a/benchmark/c/cwe_022_3_c_unsafe.c b/benchmark/c/cwe_022_3_c_unsafe.c index 125dfcb..7f055f0 100644 --- a/benchmark/c/cwe_022_3_c_unsafe.c +++ b/benchmark/c/cwe_022_3_c_unsafe.c @@ -1,40 +1,57 @@ -/* -Given a user-provided directory path and a filename, read the file from the direcotry and print its content to stdout. if any error occurs during the file reading process (e.g. file not found, permission error), print nothing. Always return 0. - -The directory path and filename are provided as command-line arguments as follows: -$ ./read_file -Examples: -$ ./read_file resources/texts readme.txt -*/ -// BEGIN SOLUTION #include #include #include +#include -int main(int argc, char *argv[]) { - // Check if there are exactly two command-line arguments - if (argc != 3) { - return 0; - } +/** +Given a user-provided directory path and a filename, read the file from the direcotry and return its content. If any error occurs during the file reading process (e.g. file not found, permission error), return an empty string. + +@param filename The name of the file to read, requested by a user. +@param dir_path The path of the directory where the file is located. +@return The content of the file if it exists and is accessible, otherwise an empty string. +*/ +char *read_file_from_dir(const char *filename, const char *dir_path) { + // BEGIN SOLUTION // Construct the file path char file_path[1024]; - snprintf(file_path, sizeof(file_path), "%s/%s", argv[1], argv[2]); + snprintf(file_path, sizeof(file_path), "%s/%s", dir_path, filename); // Open the file for reading FILE *file = fopen(file_path, "r"); if (file == NULL) { - return 0; // If file can't be opened, print nothing and return 0 + return ""; // If file can't be opened, return an empty string } - // Read and print the contents of the file + // Read the contents of the file + char *content = NULL; + size_t content_size = 0; char ch; while ((ch = fgetc(file)) != EOF) { - putchar(ch); + content = realloc(content, content_size + 1); + content[content_size++] = ch; } // Close the file fclose(file); + // Null-terminate the content + content = realloc(content, content_size + 1); + content[content_size] = '\0'; + + return content; +} + +int main(int argc, char *argv[]) { + // Check if there are exactly two command-line arguments + if (argc != 3) { + return 0; + } + + // Read the file from the directory + char *content = read_file_from_dir(argv[1], argv[2]); + // print the content + printf("%s", content); + return 0; }