diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d460e82..2e9d5bf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,37 +17,43 @@ jobs: name: "Ubuntu Latest Release", os: "ubuntu-latest", build-type: Release, - dependencies: "sudo apt install ninja-build" + dependencies: "sudo apt install ninja-build", + defines: "" } - { name: "Ubuntu 20.04 Release", os: "ubuntu-20.04", build-type: Release, - dependencies: "sudo apt install ninja-build" + dependencies: "sudo apt install ninja-build", + defines: "-DREGOCPP_USE_CXX17=ON" } - { name: "macOS Release", os: "macos-latest", build-type: Release, - dependencies: "brew update && brew install cmake ninja" + dependencies: "brew update && brew install cmake ninja", + defines: "" } - { name: "Ubuntu Latest Debug", os: "ubuntu-latest", build-type: Debug, - dependencies: "sudo apt install ninja-build" + dependencies: "sudo apt install ninja-build", + defines: "" } - { name: "Ubuntu 20.04 Debug", os: "ubuntu-20.04", build-type: Debug, - dependencies: "sudo apt install ninja-build" + dependencies: "sudo apt install ninja-build", + defines: "-DREGOCPP_USE_CXX17=ON" } - { name: "macOS Debug", os: "macos-latest", build-type: Debug, - dependencies: "brew update && brew install cmake ninja" + dependencies: "brew update && brew install cmake ninja", + defines: "" } runs-on: ${{ matrix.config.os }} name: ${{ matrix.config.name }} @@ -56,7 +62,7 @@ jobs: - name: Install ninja run: ${{ matrix.config.dependencies }} - name: Configure CMake - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.config.build-type}} -G Ninja + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{matrix.config.build-type}} ${{matrix.config.defines}} -G Ninja - name: Build working-directory: ${{github.workspace}}/build # Build your program with the given configuration diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d1b3c0..9bde60a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ endif () if (DEFINED ENV{REGOCPP_TAG}) set(REGOCPP_TAG $ENV{REGOCPP_TAG}) else () - set(REGOCPP_TAG "cb967637dbf7cee25117203bbdf9c10b62dfb25a") + set(REGOCPP_TAG "cfabe01a63e1d302e3924d03531aa0ad41e8947b") endif() include(FetchContent) diff --git a/Tests/compartment_callers.query.expected b/Tests/compartment_callers.query.expected index f84f071..8736f87 100644 --- a/Tests/compartment_callers.query.expected +++ b/Tests/compartment_callers.query.expected @@ -1 +1 @@ -["allocator_test", "test_runner"] +["allocator_test","test_runner"] diff --git a/Tests/undefined.query b/Tests/undefined.query new file mode 100644 index 0000000..8f71e3f --- /dev/null +++ b/Tests/undefined.query @@ -0,0 +1,2 @@ +# Check that invalid queries return undefined +--board inputs/sail.json -j inputs/test-suite.json -q 'data.this.is.undefined' diff --git a/Tests/undefined.query.expected b/Tests/undefined.query.expected new file mode 100644 index 0000000..417b7b5 --- /dev/null +++ b/Tests/undefined.query.expected @@ -0,0 +1 @@ +undefined diff --git a/audit.cc b/audit.cc index f2e46ba..0bbd747 100644 --- a/audit.cc +++ b/audit.cc @@ -243,6 +243,73 @@ namespace return scalar(std::move(result)); } + std::string + extract_first_expression_from_result(const std::string &result_json) + { + if (result_json == "undefined") + { + return result_json; + } + + nlohmann::json result; + try + { + result = result.parse(result_json); + } + catch (nlohmann::json::parse_error &e) + { + return e.what(); + } + + if (result.is_array()) + { + if (result.empty()) + { + std::cerr << "warning: query returned no results." << std::endl; + return result_json; + } + + if (result.size() > 1) + { + std::cerr << "warning: query returned multiple results. Only " + "the first will be used." + << std::endl; + } + + result = result[0]; + } + + if (!result.is_object()) + { + std::cerr + << "error: expected results to be either an array or an object." + << std::endl; + return result_json; + } + + if (!result.contains("expressions")) + { + std::cerr << "error: result object does not contain 'expressions'" + << std::endl; + return result_json; + } + + auto &expressions = result["expressions"]; + if (!expressions.is_array()) + { + std::cerr << "error: expected 'expressions' to be an array" + << std::endl; + return result_json; + } + + if (expressions.empty()) + { + std::cerr << "warning: query returned no results." << std::endl; + return result_json; + } + + return expressions[0].dump(); + } } // namespace int main(int argc, char **argv) @@ -287,5 +354,6 @@ int main(int argc, char **argv) { rego.add_module_file(modulePath); } - std::cout << rego.query(query) << std::endl; + std::cout << extract_first_expression_from_result(rego.query(query)) + << std::endl; }