Revision2: Corrected: RFR 8059557 (XL): Validate JVM Command-Line Flag Arguments
Kim Barrett
kim.barrett at oracle.com
Wed Jun 3 21:50:39 UTC 2015
On Jun 3, 2015, at 5:29 PM, Derek White <derek.white at oracle.com> wrote:
>
>> - Shouldn't the default implementations for CommandLineFlagConstraint::apply_XXX() return failure, not success?
>> I looked at it from the point of view of the more likely scenario, which is assume success, unless a fault detected.
>>
>> If we did do this, though, then instead of:
>>
>> Flag::Error MinHeapFreeRatioConstraintFunc(bool verbose, uintx* value) {
>> if ((CommandLineFlags::finishedInitializing()) && (*value > MaxHeapFreeRatio)) {
>> if (verbose == true) {
>> jio_fprintf(defaultStream::error_stream(),
>> "MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or "
>> "equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n",
>> *value, MaxHeapFreeRatio);
>> }
>> return Flag::VIOLATES_CONSTRAINT;
>> } else {
>> return Flag::SUCCESS;
>> }
>> }
>>
>> we’d have:
>>
>> Flag::Error MinHeapFreeRatioConstraintFunc(bool verbose, uintx* value) {
>> Flag::Error error = Flag::VIOLATES_CONSTRAINT;
>> if ((CommandLineFlags::finishedInitializing()) && (*value > MaxHeapFreeRatio)) {
>> if (verbose == true) {
>> jio_fprintf(defaultStream::error_stream(),
>> "MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or "
>> "equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n",
>> *value, MaxHeapFreeRatio);
>> }
>> } else {
>> error = Flag::SUCCESS;
>> }
>> return error;
>> }
>>
>> which is not as nice, in my opinion.
> I'm not sure we're talking about the same thing.
>
> Looking at commandLineFlagConstraintList.hpp:
>
> 55 virtual Flag::Error apply_bool(bool* value, bool verbose = true) { return Flag::SUCCESS; };
>
> I had the question "What happens if someone calls a version of the apply function (apply_FOO) that doesn't match the type of the constraint?"
>
> For example, look at CommandLineFlagConstraint::apply_bool(). What if the flag is really an "int", and it has a constraint? So the constraint is of type CommandLineFlagConstraint_intx. If apply_bool() is ever called on a CommandLineFlagConstraint_intx it will return Flag::SUCCESS. This is wrong - it violates the implicit constraint that the type of the value matches the type of the flag.
>
> It looks like the callers ensure that constraint's type matches the value's type, so the default apply_bool() is never called. I'm not sure why you'd have to re-write MinHeapFreeRatioConstraint() (as describe above) no matter what the default value of apply_bool() is.
>
> But if some later code forgets to match the types correctly, I think we're better off calling shouldNotReachHere() in the default methods.
>
> I think Kim had a similar question about default check_FOO() methods in commandLineFlagRangeList.hpp.
>
> 47 virtual Flag::Error check_intx(intx value, bool verbose = true) { return Flag::SUCCESS; }
> 48 virtual Flag::Error check_uintx(uintx value, bool verbose = true) { return Flag::SUCCESS; }
> 49 virtual Flag::Error check_uint64_t(uint64_t value, bool verbose = true) { return Flag::SUCCESS; }
> 50 virtual Flag::Error check_size_t(size_t value, bool verbose = true) { return Flag::SUCCESS; }
> 51 virtual Flag::Error check_double(double value, bool verbose = true) { return Flag::SUCCESS; }
>
> Thanks for reading this far!
>
> - Derek
>
> Notes:
>
> apply_bool() is called in two places.
>
> 1) apply_constraint_and_check_range_bool()
> - Do the callers do a type check?
> - Yes. On type mismatch:
> - CommandLineFlags::boolAtPut(const char* name, size_t
> len, bool* value, Flag::Flags origin) returns Flag::WRONG_FORMAT.
> - CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType
> flag, bool value, Flag::Flags origin) will fail a "guarantee". Not
> sure if that's best idea.
>
> 2) CommandLineFlags::check_all_ranges_and_constraints()
> - Caller basically does a type case, so apply_bool() is
> never called with wrong type flag.
>
> 55 virtual Flag::Error apply_bool(bool* value, bool verbose = true) { return Flag::SUCCESS; };
> 56 virtual Flag::Error apply_intx(intx* value, bool verbose = true) { return Flag::SUCCESS; };
> 57 virtual Flag::Error apply_uintx(uintx* value, bool verbose = true) { return Flag::SUCCESS; };
> 58 virtual Flag::Error apply_uint64_t(uint64_t* value, bool verbose = true) { return Flag::SUCCESS; };
> 59 virtual Flag::Error apply_size_t(size_t* value, bool verbose = true) { return Flag::SUCCESS; };
> 60 virtual Flag::Error apply_double(double* value, bool verbose = true) { return Flag::SUCCESS;
>
> These are never called (because the callers ensure that constraint's type matches the "value" type), so it shouldn't matter if they return Flag::SUCCESS or Flag::INVALID_FLAG.
Yes, this is what I was talking about, and I agree with Derek, except I would go further an make these default implementations be ShouldNotReachHere(), because we shouldn’t be reaching there...
More information about the hotspot-dev
mailing list