Skip to content

Commit

Permalink
feat: split function and entrypoint for c function
Browse files Browse the repository at this point in the history
  • Loading branch information
Co1lin committed Nov 7, 2024
1 parent a7b816a commit fabdedf
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 42 deletions.
61 changes: 39 additions & 22 deletions benchmark/c/cwe_022_3_c_task.c
Original file line number Diff line number Diff line change
@@ -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 <directory_path> <filename>
Examples:
$ ./read_file resources/texts readme.txt
*/
// BEGIN SOLUTION
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

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;
}
4 changes: 2 additions & 2 deletions benchmark/c/cwe_022_3_c_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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. :)'
Expand Down
53 changes: 35 additions & 18 deletions benchmark/c/cwe_022_3_c_unsafe.c
Original file line number Diff line number Diff line change
@@ -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 <directory_path> <filename>
Examples:
$ ./read_file resources/texts readme.txt
*/
// BEGIN SOLUTION
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

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;
}

0 comments on commit fabdedf

Please sign in to comment.