Remove possibility of setFilter and clearFilter shadowing in derived devices.
          #2005
        
          
      
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Summary
The PR focuses on streamlining the logic for setting device filters, and removing possibility of errors. It overhauls the
IFilterableDeviceto utilize a Template Method Pattern, instead of direct pure virtual methods. The cause for the change is the problematic shadowing of methods when a derived class declares a override a virtual method. It fixes one such issue that was left unmitigated inPcapNGtype devices hidingsetFilter(GeneralFilter).Override methods and shadowing
The problem
The shadowing issue becomes relevant when a base class declares two or more overloads of a
virtualmethod. If a derived class overrides only one of the overloads, the C++ language spec hides all other overloads from the derived class's scope by default.For example:
Such issues are hard to spot due to their subtlety.
Such was the case in
PcapNGFileReaderDeviceandPcapNGFileWriterDevicewhich only declaredsetFilter(std::string), making the interfacesetFilter(GenericFilter const&)unavailable through the types.Solutions
There are three possible ways to fix this issue:
using Base::foo;declaration.Proposed solution
Previously, most of the devices utilized option 2, but that is brittle as it requires developer knowledge of the issue and scrutinous review as observed due to existing issues with PcapNG-type reader devices.
This PR refactors the code to utilize option 3 as an alternative. This was selected due to the overload
setFilter(GeneralFilter)cleanly delegating the majority of the work tosetFilter(std::string).The solution follows a Template Method Pattern by introducing a protected hook method
doUpdateFilter(std::string)and keeping the public API non-virtual.The change allows all calls from
setFilterandclearFilterto be delegated to the device hook, while keeping the public API unchanged. The following change has the following benefits:overrideoverloads, as they are no longervirtual. It is still possible to shadow a method by adding another overload in a derived class, but that situation is a lot more rare.overridenfor a specific device.Behaviour changes
clearFilternow mirrorssetFilterand requires the device to be in an open state due to reusing the same filter hook. This differs from the previous implementation whereclearFiltercould possibly succeed depending on the device's implementation of the method.