Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
785 changes: 785 additions & 0 deletions clib-masterllvm-15/src/clib-build.c

Large diffs are not rendered by default.

705 changes: 705 additions & 0 deletions clib-masterllvm-15/src/clib-configure.c

Large diffs are not rendered by default.

169 changes: 169 additions & 0 deletions clib-masterllvm-15/src/clib-init.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
//
// clib-init.c
//
// Copyright (c) 2012-2020 clib authors
// MIT licensed
//

#include "asprintf/asprintf.h"
#include "commander/commander.h"
#include "common/clib-package.h"
#include "debug/debug.h"
#include "fs/fs.h"
#include "logger/logger.h"
#include "parson/parson.h"
#include "version.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || \
defined(__MINGW64__)
#define setenv(k, v, _) _putenv_s(k, v)
#define realpath(a, b) _fullpath(a, b, strlen(a))
#define PATH_SEPARATOR '\\'
#else
#define PATH_SEPARATOR '/'
#endif

debug_t debugger;

struct options {
char *manifest;
int verbose;
};

static struct options opts;

/**
* Option setters.
*/

static void setopt_quiet(command_t *self) {
opts.verbose = 0;
debug(&debugger, "set quiet flag");
}

static void setopt_manifest_file(command_t *self) {
opts.manifest = (char *)self->arg;
debug(&debugger, "set manifest: %s", opts.manifest);
}

/**
* Program.
*/

static char *find_basepath() {
char cwd[4096] = {0};
getcwd(cwd, 4096);

char* last_part = strrchr(cwd, PATH_SEPARATOR);
char* base_path = (last_part != NULL) ? last_part + 1 : cwd;
return strdup( base_path);
}

static void getinput(char *buffer, size_t s) {
char *walk = buffer;
int c = 0;
while ((walk - s) != buffer && (c = fgetc(stdin)) && c != '\n' && c != 0) {
*(walk++) = c;
}
}
Comment on lines +66 to +72
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Off-by-one / incorrect boundary check in getinput.

The condition (walk - s) != buffer is incorrect. s is the buffer size (a size_t), not a pointer, so subtracting it from walk doesn't produce the intended bounds check. This could lead to buffer overflows.

🐛 Proposed fix
 static void getinput(char *buffer, size_t s) {
   char *walk = buffer;
   int c = 0;
-  while ((walk - s) != buffer && (c = fgetc(stdin)) && c != '\n' && c != 0) {
+  while ((size_t)(walk - buffer) < (s - 1) && (c = fgetc(stdin)) != EOF && c != '\n') {
     *(walk++) = c;
   }
+  *walk = '\0';
 }

The fix:

  1. Correctly checks that we haven't exceeded buffer capacity (leaving room for null terminator)
  2. Properly handles EOF
  3. Null-terminates the buffer
🤖 Prompt for AI Agents
In `@clib-masterllvm-15/src/clib-init.c` around lines 66 - 72, In getinput, the
bounds check is wrong because it subtracts the size s from pointer walk; change
the loop to track bytes written via (walk - buffer) and ensure that
(size_t)(walk - buffer) < (s ? s - 1 : 0) so you leave room for the null
terminator and handle s == 0, use c = fgetc(stdin) compared against EOF (not 0),
append (char)c while c != EOF && c != '\n' and the byte-count limit isn't
reached, then null-terminate the buffer via *walk = '\0'; ensure all references
are to getinput, buffer, s, walk and c.


static void ask_for(JSON_Object *root, const char *key,
const char *default_value, const char *question) {
static char buffer[512] = {0};
memset(buffer, '\0', 512);
printf("%s", question);
getinput(buffer, 512);
char *value = (char *)(strlen(buffer) > 0 ? buffer : default_value);
json_object_set_string(root, key, value);
}

static inline size_t write_to_file(const char *manifest, const char *str,
size_t length) {
size_t wrote = 0;

FILE *file = fopen(manifest, "w+");
if (!file) {
debug(&debugger, "Cannot open %s file.", manifest);
return 0;
}

wrote = fwrite(str, sizeof(char), length, file);
fclose(file);

return length - wrote;
}

static int write_package_file(const char *manifest, JSON_Value *pkg) {
int rc = 0;
char *package = json_serialize_to_string_pretty(pkg);

if (0 != write_to_file(manifest, package, strlen(package))) {
logger_error("Failed to write to %s", manifest);
rc = 1;
goto e1;
}

debug(&debugger, "Wrote %s file.", manifest);

e1:
json_free_serialized_string(package);

return rc;
}

/**
* Entry point.
*/

int main(int argc, char *argv[]) {
int exit_code = 0;
opts.verbose = 1;
opts.manifest = "clib.json";

debug_init(&debugger, "clib-init");

command_t program;

command_init(&program, "clib-init", CLIB_VERSION);

program.usage = "[options]";

command_option(&program, "-q", "--quiet", "disable verbose output",
setopt_quiet);
command_option(&program, "-M", "--manifest <filename>",
"give a manifest of the manifest file. (default: clib.json)",
setopt_manifest_file);
command_parse(&program, argc, argv);

debug(&debugger, "%d arguments", program.argc);

JSON_Value *json = json_value_init_object();
JSON_Object *root = json_object(json);

char *basepath = find_basepath();
char *package_name = NULL;

int rc = asprintf(&package_name, "package name (%s): ", basepath);
if (-1 == rc) {
logger_error("error", "asprintf() out of memory");
goto end;
}

ask_for(root, "name", basepath, package_name);
ask_for(root, "version", "0.1.0", "version (default: 0.1.0): ");

exit_code = write_package_file(opts.manifest, json);

end:
free(package_name);
free(basepath);

json_value_free(json);
command_free(&program);

return exit_code;
}
Loading