Skip to content
Merged
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
1 change: 1 addition & 0 deletions inc/limits.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

/* Limits */
#define MAX_ARGLN 512 // Max command line argument length
#define MAX_COMPONENT_SCAN_HASHES 1000 // Max number of url hashes accepted by -C
#define MAX_PATH 1024
#define MAX_HASHES_READ 65535
#define MAX_FILE_SIZE (1024 * 1024 * 4)
Expand Down
1 change: 1 addition & 0 deletions inc/match_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,5 +147,6 @@ void component_list_destroy(component_list_t *list);
bool component_list_add_binary(component_list_t *list, component_data_t *new_comp, bool (*val)(component_data_t *a, component_data_t *b), bool remove_a);
bool match_list_eval(match_list_t *list, match_data_t * in, bool (*eval)(match_data_t *fpa, match_data_t *fpb));
void match_list_tolerance_set(float in);
float match_list_tolerance_get(void);

#endif
76 changes: 76 additions & 0 deletions inc/purl_scan.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* inc/purl_scan.h
*
* SCANOSS Inventory Scanner
*
* Copyright (C) 2018-2024 SCANOSS.COM
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.

* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.

* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef __PURL_SCAN_H
#define __PURL_SCAN_H

/**
* @brief Resolve the purls and url hashes related to a file MD5.
*
* Looks up the given file MD5 in the KB (url and file tables) and prints, in
* JSON, the unique purls associated with that file along with every url hash
* (url_id) where the file was seen and the best (lowest) KB rank found for
* each purl.
*
* @param file_md5_hex file MD5 in hex (32 chars)
* @return EXIT_SUCCESS on success, EXIT_FAILURE on invalid input
*/
int purl_scan(char *file_md5_hex);

/**
* @brief Report the details of a single component identified by its url hash.
*
* Looks up the url record for the given url_hash (url_id) in the KB and
* prints the component details in JSON, reusing the same rendering used in
* regular scan reports (print_json_component).
*
* @param url_hash_hex url hash in hex (32 chars)
* @return EXIT_SUCCESS on success, EXIT_FAILURE on invalid input
*/
int component_scan(char *url_hash_hex);

/**
* @brief Run a snippet-only scan whose WFP input comes from stdin.
*
* Reads a WFP block (same format used by `-w` scans) from stdin, runs the
* snippet selection pipeline (no full-file lookup, no component resolution)
* and prints a JSON report listing the file_md5 candidates grouped by snippet
* region, together with their input/oss line ranges. Candidate cohort size is
* controlled by the tolerance set via -T (match_list_tolerance_set).
*
* @return EXIT_SUCCESS on success, EXIT_FAILURE on invalid/empty input
*/
int snippet_scan_stdin(void);

/**
* @brief Run a snippet-only scan whose WFP input is passed as a string.
*
* Same behavior as snippet_scan_stdin() but reads the WFP block from the
* provided in-memory buffer. Used by `-S "<wfp>"` so callers (e.g. FlexAPI)
* can pass the WFP directly as an argv value instead of piping it via stdin.
*
* @param wfp NUL-terminated buffer holding the WFP block
* @return EXIT_SUCCESS on success, EXIT_FAILURE on invalid/empty input
*/
int snippet_scan_string(const char *wfp);

#endif
1 change: 1 addition & 0 deletions inc/report.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ void json_open();
void json_close(void);
void kb_version_get(void);
bool print_json_component(component_data_t * component);
void print_purl_array(component_data_t * component);
#endif
5 changes: 5 additions & 0 deletions src/help.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ Configuration:\n\
-a, --attribution FILE Show attribution notices for the provided SBOM.json file.\n\
-c, --component HINT Add a component HINT to guide scan results.\n\
-k, --key KEY Show contents of the specified KEY file from MZ sources archive.\n\
-P, --purl MD5 Return the purls and versions related to the given file MD5 (JSON).\n\
-C, --url-hash MD5 Return the details of the component identified by the given url hash (JSON).\n\
-S, --snippet-scan WFP Snippet-only scan: take a single-file WFP block as argument and return JSON with candidate\n\
file_md5s and their line ranges, filtered by the tolerance set via -T (precede -S with -T\n\
to apply). Use -S - to read the WFP from stdin instead of passing it as argument.\n\
-l, --license LICENSE Display OSADL metadata for the given SPDX license ID.\n\
-L, --full-license Enable full license report.\n\
-F, --flags FLAGS Set engine scanning flags (see below).\n\
Expand Down
32 changes: 21 additions & 11 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "parse.h"
#include "report.h"
#include "scan.h"
#include "purl_scan.h"
#include "scanoss.h"
#include "util.h"
#include "component.h"
Expand Down Expand Up @@ -278,8 +279,11 @@ static struct option long_options[] = {
{"sbom", required_argument, 0, 's'},
{"blacklist", required_argument, 0, 'b'},
{"force-snippet", required_argument, 0, 256}, /* Long option only, no short form */
{"snippet-scan", required_argument, 0, 'S'},
{"component", required_argument, 0, 'c'},
{"key", required_argument, 0, 'k'},
{"purl", required_argument, 0, 'P'},
{"url-hash", required_argument, 0, 'C'},
{"attribution", required_argument, 0, 'a'},
{"flags", required_argument, 0, 'F'},
{"license", required_argument, 0, 'l'},
Expand Down Expand Up @@ -334,18 +338,8 @@ int main(int argc, char **argv)
bool invalid_argument = false;
char * ldb_db_name = NULL;

while ((option = getopt_long(argc, argv, ":r:T:s:b:c:k:a:F:l:n:M:N:wtLvhdqH", long_options, &option_index)) != -1)
while ((option = getopt_long(argc, argv, ":r:T:s:b:c:k:a:F:l:n:M:N:P:C:S:wtLvhdqH", long_options, &option_index)) != -1)
{
/* Check valid alpha is entered */
if (optarg)
{
if ((strlen(optarg) > MAX_ARGLN))
{
invalid_argument = true;
break;
}
}

switch (option)
{
case 's':
Expand All @@ -371,6 +365,16 @@ int main(int argc, char **argv)
exit(EXIT_SUCCESS);
break;

case 'P':
initialize_ldb_tables(ldb_db_name);
exit(purl_scan(optarg));
break;

case 'C':
initialize_ldb_tables(ldb_db_name);
exit(component_scan(optarg));
break;

case 'a':
if (declared_components)
{
Expand Down Expand Up @@ -414,6 +418,12 @@ int main(int argc, char **argv)
case 256: /* --force-snippet (long option only) */
force_snippet_scan = true;
break;
case 'S':
initialize_ldb_tables(ldb_db_name);
if (optarg && optarg[0] == '-' && optarg[1] == '\0')
exit(snippet_scan_stdin());
exit(snippet_scan_string(optarg));
break;
case 't':
initialize_ldb_tables(ldb_db_name);
scan_benchmark();
Expand Down
7 changes: 6 additions & 1 deletion src/match_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,16 @@ void match_list_tolerance_set(float in)
{
if (in > 99)
in = 99;

match_list_tolerance = 100.0-in;
scanlog("setting match list tolerance to %.1f\n", match_list_tolerance);
}

float match_list_tolerance_get(void)
{
return 100.0 - match_list_tolerance;
}

bool tolerance_eval(int a, int b)
{
int relative_error = (abs(a - b) * 100) / ((a + b) / 2);
Expand Down
Loading
Loading