1818#include <math.h>
1919#include "xshared.h"
2020
21- static void ensure_heap_opts (struct xtables_globals * globals )
22- {
23- struct option * orig ;
24- size_t count ;
25- struct option * copy ;
26-
27- if (globals == NULL )
28- return ;
29-
30- if (globals -> opts == NULL )
31- globals -> opts = globals -> orig_opts ;
32-
33- orig = globals -> orig_opts ;
34- if (orig == NULL || globals -> opts != orig )
35- return ;
36-
37- for (count = 0 ; orig [count ].name != NULL ; ++ count )
38- ;
39- copy = malloc (sizeof (* copy ) * (count + 1 ));
40- if (copy == NULL )
41- xtables_error (RESOURCE_PROBLEM , "malloc" );
42- memcpy (copy , orig , sizeof (* copy ) * (count + 1 ));
43- globals -> opts = copy ;
44- if (xt_params == globals )
45- xt_params -> opts = copy ;
46- }
47-
4821/*
4922 * Print out any special helps. A user might like to be able to add a --help
5023 * to the commandline, and see expected results. So we call help for all
@@ -184,17 +157,26 @@ int command_default(struct iptables_command_state *cs,
184157 m -> m -> u .user .revision = m -> revision ;
185158 xs_init_match (m );
186159
187- ensure_heap_opts (gl );
188- if (m -> x6_options != NULL )
189- gl -> opts = xtables_options_xfrm (gl -> orig_opts ,
190- gl -> opts ,
160+ {
161+ struct option * existing ;
162+ struct option * old ;
163+
164+ existing = gl -> opts ;
165+ if (existing == NULL )
166+ existing = gl -> orig_opts ;
167+ old = (existing == gl -> orig_opts ) ? NULL : existing ;
168+
169+ if (m -> x6_options != NULL )
170+ gl -> opts = xtables_options_xfrm (gl -> orig_opts ,
171+ old ,
191172 m -> x6_options ,
192173 & m -> option_offset );
193- else
194- gl -> opts = xtables_merge_options (gl -> orig_opts ,
195- gl -> opts ,
196- m -> extra_opts ,
197- & m -> option_offset );
174+ else
175+ gl -> opts = xtables_merge_options (gl -> orig_opts ,
176+ old ,
177+ m -> extra_opts ,
178+ & m -> option_offset );
179+ }
198180 if (gl -> opts == NULL )
199181 xtables_error (OTHER_PROBLEM , "can't alloc memory!" );
200182 optind -- ;
@@ -567,14 +549,20 @@ void print_ifaces(const char *iniface, const char *outiface, uint8_t invflags,
567549
568550void command_match (struct iptables_command_state * cs )
569551{
570- ensure_heap_opts (xt_params );
571- struct option * opts = xt_params -> opts ;
552+ struct option * existing ;
553+ struct option * old ;
554+ struct option * opts ;
572555 struct xtables_match * m ;
573556 size_t size ;
574557
558+ existing = xt_params -> opts ;
559+ if (existing == NULL )
560+ existing = xt_params -> orig_opts ;
561+ opts = existing ;
562+
575563 if (cs -> invert )
576564 xtables_error (PARAMETER_PROBLEM ,
577- "unexpected ! flag before --match" );
565+ "unexpected ! flag before --match" );
578566
579567 m = xtables_find_match (optarg , XTF_LOAD_MUST_SUCCEED , & cs -> matches );
580568 size = XT_ALIGN (sizeof (struct xt_entry_match )) + m -> size ;
@@ -592,13 +580,16 @@ void command_match(struct iptables_command_state *cs)
592580 xs_init_match (m );
593581 if (m == m -> next )
594582 return ;
595- /* Merge options for non-cloned matches */
583+
584+ old = (existing == xt_params -> orig_opts ) ? NULL : existing ;
596585 if (m -> x6_options != NULL ) {
597- opts = xtables_options_xfrm (xt_params -> orig_opts , opts ,
598- m -> x6_options , & m -> option_offset );
586+ opts = xtables_options_xfrm (xt_params -> orig_opts , old ,
587+ m -> x6_options , & m -> option_offset );
599588 } else if (m -> extra_opts != NULL ) {
600- opts = xtables_merge_options (xt_params -> orig_opts , opts ,
601- m -> extra_opts , & m -> option_offset );
589+ opts = xtables_merge_options (xt_params -> orig_opts , old ,
590+ m -> extra_opts , & m -> option_offset );
591+ } else {
592+ return ;
602593 }
603594 if (opts == NULL )
604595 xtables_error (OTHER_PROBLEM , "can't alloc memory!" );
@@ -627,10 +618,16 @@ const char *xt_parse_target(const char *targetname)
627618
628619void command_jump (struct iptables_command_state * cs )
629620{
630- ensure_heap_opts (xt_params );
631- struct option * opts = xt_params -> opts ;
621+ struct option * existing ;
622+ struct option * old ;
623+ struct option * opts ;
632624 size_t size ;
633625
626+ existing = xt_params -> opts ;
627+ if (existing == NULL )
628+ existing = xt_params -> orig_opts ;
629+ opts = existing ;
630+
634631 cs -> jumpto = xt_parse_target (optarg );
635632 /* TRY_LOAD (may be chain name) */
636633 cs -> target = xtables_find_target (cs -> jumpto , XTF_TRY_LOAD );
@@ -655,14 +652,17 @@ void command_jump(struct iptables_command_state *cs)
655652 cs -> target -> t -> u .user .revision = cs -> target -> revision ;
656653 xs_init_target (cs -> target );
657654
655+ old = (existing == xt_params -> orig_opts ) ? NULL : existing ;
658656 if (cs -> target -> x6_options != NULL )
659- opts = xtables_options_xfrm (xt_params -> orig_opts , opts ,
660- cs -> target -> x6_options ,
661- & cs -> target -> option_offset );
657+ opts = xtables_options_xfrm (xt_params -> orig_opts , old ,
658+ cs -> target -> x6_options ,
659+ & cs -> target -> option_offset );
660+ else if (cs -> target -> extra_opts != NULL )
661+ opts = xtables_merge_options (xt_params -> orig_opts , old ,
662+ cs -> target -> extra_opts ,
663+ & cs -> target -> option_offset );
662664 else
663- opts = xtables_merge_options (xt_params -> orig_opts , opts ,
664- cs -> target -> extra_opts ,
665- & cs -> target -> option_offset );
665+ return ;
666666 if (opts == NULL )
667667 xtables_error (OTHER_PROBLEM , "can't alloc memory!" );
668668 xt_params -> opts = opts ;
0 commit comments