diff options
author | midipix <writeonce@midipix.org> | 2025-06-03 10:11:24 +0000 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2025-06-03 15:16:50 +0000 |
commit | 663098e8be251c89181cc56503d7fb7ab2e8c1c5 (patch) | |
tree | c167f020c69ed1210829b9002d60195c566e6065 /src | |
parent | c5c7073a522fc96ec5c0270de6d5e48154d5cd62 (diff) | |
download | perk-663098e8be251c89181cc56503d7fb7ab2e8c1c5.tar.bz2 perk-663098e8be251c89181cc56503d7fb7ab2e8c1c5.tar.xz |
pe_cmd_ar(): added command-line semantic verification.
Diffstat (limited to 'src')
-rw-r--r-- | src/cmds/pe_cmd_ar.c | 78 | ||||
-rw-r--r-- | src/internal/perk_ar_impl.h | 12 | ||||
-rw-r--r-- | src/output/pe_output_error.c | 8 |
3 files changed, 93 insertions, 5 deletions
diff --git a/src/cmds/pe_cmd_ar.c b/src/cmds/pe_cmd_ar.c index e578ca0..4b4f284 100644 --- a/src/cmds/pe_cmd_ar.c +++ b/src/cmds/pe_cmd_ar.c @@ -6,6 +6,76 @@ #include <perk/perk.h> #include "perk_driver_impl.h" +#include "perk_errinfo_impl.h" +#include "perk_ar_impl.h" + +static int pe_cmd_ar_verify_cmdline( + const struct pe_driver_ctx * dctx, + uint64_t flags, + const char * posname, + const char * arname, + const char ** units) +{ + uint64_t action; + uint64_t poscmd; + uint64_t vercmd; + + action = (flags & AR_ACTION_MASK); + poscmd = (flags & AR_POSNAME_MASK); + vercmd = (flags & PERK_DRIVER_VERSION); + + if (vercmd && !posname && !arname && !units) + return 0; + + switch (action) { + case 0: + return PERK_CUSTOM_ERROR(dctx, + PERK_ERR_AR_MISSING_ACTION); + + case PERK_DRIVER_AR_LIST_MEMBERS: + case PERK_DRIVER_AR_DELETE_MEMBERS: + case PERK_DRIVER_AR_APPEND_MEMBERS: + case PERK_DRIVER_AR_EXTRACT_MEMBERS: + case PERK_DRIVER_AR_PRINT_ARCHIVE: + if (poscmd || posname) + return PERK_CUSTOM_ERROR(dctx, + PERK_ERR_AR_INVALID_ANCHORS); + + break; + + case AR_UPDATE_MASK: + case PERK_DRIVER_AR_REPLACE_MEMBERS: + case PERK_DRIVER_AR_MOVE_MEMBERS: + switch (poscmd) { + case 0: + if (posname) + return PERK_CUSTOM_ERROR(dctx, + PERK_ERR_AR_MISSING_ANCHOR); + break; + + case PERK_DRIVER_AR_POSITION_AFTER: + case PERK_DRIVER_AR_POSITION_BEFORE: + if (!posname) + return PERK_CUSTOM_ERROR(dctx, + PERK_ERR_AR_NULL_POSNAME); + break; + + default: + return PERK_CUSTOM_ERROR(dctx, + PERK_ERR_AR_MULTIPLE_ANCHORS); + } + + default: + return PERK_CUSTOM_ERROR(dctx, + PERK_ERR_AR_MULTIPLE_ACTIONS); + } + + if (!arname) + return PERK_CUSTOM_ERROR(dctx, + PERK_ERR_AR_NULL_ARNAME); + + return 0; +} int pe_cmd_ar( const struct pe_driver_ctx * dctx, @@ -14,10 +84,8 @@ int pe_cmd_ar( const char * arname, const char ** units) { - (void)dctx; - (void)flags; - (void)posname; - (void)arname; - (void)units; + if (pe_cmd_ar_verify_cmdline(dctx,flags,posname,arname,units) < 0) + return PERK_NESTED_ERROR(dctx); + return 0; } diff --git a/src/internal/perk_ar_impl.h b/src/internal/perk_ar_impl.h index aa44396..b7c2fbc 100644 --- a/src/internal/perk_ar_impl.h +++ b/src/internal/perk_ar_impl.h @@ -24,6 +24,18 @@ #define AR_POSNAME_MASK (PERK_DRIVER_AR_POSITION_AFTER \ |PERK_DRIVER_AR_POSITION_BEFORE) +#define AR_UPDATE_MASK (PERK_DRIVER_AR_UPDATE_MEMBERS \ + |PERK_DRIVER_AR_REPLACE_MEMBERS) + +#define AR_ACTION_MASK (PERK_DRIVER_AR_LIST_MEMBERS \ + |PERK_DRIVER_AR_MOVE_MEMBERS \ + |PERK_DRIVER_AR_UPDATE_MEMBERS \ + |PERK_DRIVER_AR_DELETE_MEMBERS \ + |PERK_DRIVER_AR_APPEND_MEMBERS \ + |PERK_DRIVER_AR_REPLACE_MEMBERS \ + |PERK_DRIVER_AR_EXTRACT_MEMBERS \ + |PERK_DRIVER_AR_PRINT_ARCHIVE) + extern const struct argv_option pe_ar_options[]; struct ar_armaps_impl { diff --git a/src/output/pe_output_error.c b/src/output/pe_output_error.c index 1d818d1..9635d13 100644 --- a/src/output/pe_output_error.c +++ b/src/output/pe_output_error.c @@ -38,6 +38,14 @@ static const char * const pe_error_strings[PERK_ERR_CAP] = { [PERK_ERR_AR_NON_PE_MEMBERS] = "format of current archive member is not PE/COFF", [PERK_ERR_AR_MIXED_PE_MEMBERS] = "archive mixes objects of different architectures", [PERK_ERR_AR_NESTED_ARCHIVE] = "nested archives are currently not supported", + + [PERK_ERR_AR_MISSING_ACTION] = "missing action, which should be exactly one of [dqmrxpt]", + [PERK_ERR_AR_MULTIPLE_ACTIONS] = "exactly one action permitted, multiple actions specified", + [PERK_ERR_AR_MULTIPLE_ANCHORS] = "multiple anchors: may specify _before_ or _after_, but not both", + [PERK_ERR_AR_INVALID_ANCHORS] = "mismatched arguments: anchors are incompatible with the selected action", + [PERK_ERR_AR_MISSING_ANCHOR] = "missing anchor: <posname> provided, but no anchor specified", + [PERK_ERR_AR_NULL_POSNAME] = "null <posname> argument with [-a], [-b], or [-i]", + [PERK_ERR_AR_NULL_ARNAME] = "null <arname> argument", }; static const char * pe_output_error_header(const struct pe_error_info * erri) |