From 61d9e8699687342c2e32c32c8d4eb71760d5d290 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 26 Jun 2021 17:33:24 +0200 Subject: Use fork/exec instead of popen. Add Path class --- src/main.cpp | 78 ++++++++++++++++-------------------------------------------- 1 file changed, 20 insertions(+), 58 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 713514d..ecb0e99 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -80,9 +80,6 @@ using namespace std::chrono; // TODO: Add program command for generating compile_commands.json without compiling code, without using Ninja -// TODO: Make Process::exec safe to use. Currently you pass an argument and it's run as a command, but the string can be escaped to perform malicious acts. -// Process::exec should be modified to take a list of arguments to execute command with. - // TODO: Verify paths (test path, ignore dirs, include dirs, expose include dir, sibs test --file dir) are sub directory of the project // TODO: When creating a package with `sibs package` copy LICENSE files into archive. @@ -97,6 +94,8 @@ using namespace std::chrono; // TODO: If dependencies are using a version that is not within our dependency version range then ask the user if they still want to use the dependency (the closest matching dependency). // Currently if dependency version does not match, build will always fail with no option to ignore version mismatch. +// TODO: Check if ninja args are properly escaped. + #if OS_FAMILY == OS_FAMILY_POSIX #define fout std::cout #define ferr std::cerr @@ -314,7 +313,8 @@ struct MicrosoftBuildTool static MicrosoftBuildTool locateLatestMicrosoftBuildTool() { MicrosoftBuildTool result = { 0 }; - Result execResult = exec(TINYDIR_STRING("locate_windows_sdk x64")); + // TODO: x86 + Result execResult = exec({ TINYDIR_STRING("locate_windows_sdk"), TINYDIR_STRING("x64") }); if (execResult && execResult.unwrap().exitCode == 0) { auto &str = execResult.unwrap().execStdout; @@ -363,7 +363,7 @@ static void appendBuildToolToPathEnv() #endif } -static int buildProject(const FileString &projectPath, const FileString &projectConfFilePath, SibsConfig &sibsConfig, bool run, FileString run_args) +static int buildProject(const FileString &projectPath, const FileString &projectConfFilePath, SibsConfig &sibsConfig, bool run, const std::vector &run_args) { FileString buildPath; readSibsConfig(projectPath, projectConfFilePath, sibsConfig, buildPath); @@ -455,7 +455,11 @@ static int buildProject(const FileString &projectPath, const FileString &project FileString executableName = toFileString(sibsConfig.getPackageName()); if(isSamePlatformFamily(sibsConfig.platform, PLATFORM_WIN)) executableName += TINYDIR_STRING(".exe"); - auto exec_result = exec(buildPath + TINYDIR_STRING("/") + executableName + TINYDIR_STRING(" ") + run_args, true); + + std::vector args = { Path(buildPath).join(executableName).data }; + args.insert(args.end(), run_args.begin(), run_args.end()); + + auto exec_result = exec(args, true); if(!exec_result) { ferr << "Failed to execute" << (buildPath + TINYDIR_STRING("/") + executableName) << ", error: " << toFileString(exec_result.getErrMsg()) << endl; return 1; @@ -466,35 +470,6 @@ static int buildProject(const FileString &projectPath, const FileString &project return 0; } -#if OS_FAMILY == OS_FAMILY_WINDOWS -#define NATIVE_CHAR_PREFIX L -#else -#define NATIVE_CHAR_PREFIX -#endif - -static FileString replace_all(const _tinydir_char_t *str) { - FileString result = TINYDIR_STRING("'"); - while(*str != NATIVE_CHAR_PREFIX'\0') { - if(*str == NATIVE_CHAR_PREFIX'\'') - result += TINYDIR_STRING("\\'"); - else - result += *str; - ++str; - } - result += NATIVE_CHAR_PREFIX'\''; - return result; -} - -static FileString escape_args(const std::vector &args) { - FileString result; - for(const _tinydir_char_t *arg : args) { - if(!result.empty()) - result += NATIVE_CHAR_PREFIX' '; - result += replace_all(arg); - } - return result; -} - static Sanitize sanitize_string_to_type(const _tinydir_char_t *str) { if(strcmp(str, TINYDIR_STRING("address")) == 0) return Sanitize::ADDRESS; @@ -517,7 +492,7 @@ static int buildProject(int argc, const _tinydir_char_t **argv, bool run) Sanitize sanitize = Sanitize::NONE; FileString platformName; bool use_lto = false; - std::vector run_args; + std::vector run_args; for(int i = 0; i < argc; ++i) { @@ -652,7 +627,7 @@ static int buildProject(int argc, const _tinydir_char_t **argv, bool run) sibsConfig.platform = platform; sibsConfig.setSanitize(sanitize); sibsConfig.use_lto = use_lto; - return buildProject(projectPath, projectConfFilePath, sibsConfig, run, escape_args(run_args)); + return buildProject(projectPath, projectConfFilePath, sibsConfig, run, run_args); } static int testProject(int argc, const _tinydir_char_t **argv) @@ -797,7 +772,7 @@ static int testProject(int argc, const _tinydir_char_t **argv) sibsConfig.zigTestFiles = move(filesToTest); sibsConfig.zigTestAllFiles = testAllFiles; - return buildProject(projectPath, projectConfFilePath, sibsConfig, false, TINYDIR_STRING("")); + return buildProject(projectPath, projectConfFilePath, sibsConfig, false, {}); } // Returns nullptr if @charToFind is not found @@ -844,10 +819,7 @@ static void createProjectFile(const FileString &projectFilePath, const string &f // so there is no reason to do it (right now) static Result gitInitProject(const FileString &projectPath) { - FileString cmd = TINYDIR_STRING("git init \""); - cmd += projectPath; - cmd += TINYDIR_STRING("\""); - return exec(cmd.c_str()); + return exec({ TINYDIR_STRING("git"), TINYDIR_STRING("init"), TINYDIR_STRING("--"), projectPath }); } static bool gitIgnoreContainsSibs(const FileString &gitIgnoreFilePath) @@ -1236,7 +1208,7 @@ static int packageProject(int argc, const _tinydir_char_t **argv) sibsConfig.packaging = packagingType == PackagingType::STATIC; sibsConfig.bundling = (packagingType == PackagingType::BUNDLE) || (packagingType == PackagingType::BUNDLE_INSTALL); sibsConfig.use_lto = true; - int result = buildProject(projectPath, projectConfFilePath, sibsConfig, false, TINYDIR_STRING("")); + int result = buildProject(projectPath, projectConfFilePath, sibsConfig, false, {}); if(result != 0) return result; @@ -1244,8 +1216,8 @@ static int packageProject(int argc, const _tinydir_char_t **argv) { case PackagingType::STATIC: { - string packagePath = toUtf8(projectPath + TINYDIR_STRING("/sibs-build/") + toFileString(asString(sibsConfig.platform)) + TINYDIR_STRING("/package")); - printf("Project %s was successfully packaged and can be found at %s\n", sibsConfig.getPackageName().c_str(), packagePath.c_str()); + Path packagePath = Path(projectPath).join(TINYDIR_STRING("sibs-build")).join(toFileString(asString(sibsConfig.platform))).join(TINYDIR_STRING("package")); + printf("Project %s was successfully packaged and can be found at %s\n", sibsConfig.getPackageName().c_str(), packagePath.data.c_str()); break; } case PackagingType::BUNDLE: @@ -1262,21 +1234,11 @@ static int packageProject(int argc, const _tinydir_char_t **argv) break; } - FileString packagePath = projectPath + TINYDIR_STRING("/sibs-build/") + toFileString(asString(sibsConfig.platform)) + TINYDIR_STRING("/package"); - FileString executablePath = projectPath + TINYDIR_STRING("/sibs-build/") + toFileString(asString(sibsConfig.platform)) + TINYDIR_STRING("/release/")+ toFileString(sibsConfig.getPackageName()); + Path packagePath = Path(projectPath).join(TINYDIR_STRING("sibs-build")).join(toFileString(asString(sibsConfig.platform))).join(TINYDIR_STRING("package")); + Path executablePath = Path(projectPath).join(TINYDIR_STRING("sibs-build")).join(toFileString(asString(sibsConfig.platform))).join(TINYDIR_STRING("release")).join(toFileString(sibsConfig.getPackageName())); printf("Creating a package from project and dependencies...\n"); // args: executable_path program_version destination_path <--bundle|--bundle-install> - FileString cmd = TINYDIR_STRING("python3 \"") + - packageScriptPath + - TINYDIR_STRING("\" \"") + - executablePath + - TINYDIR_STRING("\" \"") + - toFileString(sibsConfig.version.toString()) + - TINYDIR_STRING("\" \"") + - packagePath + - TINYDIR_STRING("\" ") + - bundleType; - Result bundleResult = exec(cmd.c_str(), true); + Result bundleResult = exec({ TINYDIR_STRING("python3"), packageScriptPath, executablePath.data, toFileString(sibsConfig.version.toString()), packagePath.data, bundleType }, true); if(!bundleResult) { fprintf(stderr, "Error: failed to package project as a bundle, reason: %s\n", bundleResult.getErrMsg().c_str()); -- cgit v1.2.3