Details
-
Bug
-
Status: Open
-
Normal
-
Resolution: Unresolved
-
None
-
Normal
Description
The SizeTieredCompactionStrategyOptions_validateOptions method has the following code:
public static Map<String, String> validateOptions(Map<String, String> options, Map<String, String> uncheckedOptions) throws ConfigurationException { String optionValue = options.get(MIN_SSTABLE_SIZE_KEY); try { long minSSTableSize = optionValue == null ? DEFAULT_MIN_SSTABLE_SIZE : Long.parseLong(optionValue); if (minSSTableSize < 0) { throw new ConfigurationException(String.format("%s must be non negative: %d", MIN_SSTABLE_SIZE_KEY, minSSTableSize)); } } catch (NumberFormatException e) { throw new ConfigurationException(String.format("%s is not a parsable int (base10) for %s", optionValue, MIN_SSTABLE_SIZE_KEY), e); } ... }
Here, the optionValue can be too long and cause overflow. CASSANDRA-8406 fixed a similar bug. The buggy code is:
public static Map<String, String> validateOptions(Map<String, String> options, Map<String, String> uncheckedOptions) throws ConfigurationException { String optionValue = options.get(TIMESTAMP_RESOLUTION_KEY); try { if (optionValue != null) TimeUnit.valueOf(optionValue); } catch (IllegalArgumentException e) { throw new ConfigurationException(String.format("timestamp_resolution %s is not valid", optionValue)); } optionValue = options.get(MAX_SSTABLE_AGE_KEY); try { long maxSStableAge = optionValue == null ? DEFAULT_MAX_SSTABLE_AGE_DAYS : Long.parseLong(optionValue); if (maxSStableAge < 0) { throw new ConfigurationException(String.format("%s must be non-negative: %d", MAX_SSTABLE_AGE_KEY, maxSStableAge)); } } catch (NumberFormatException e) { throw new ConfigurationException(String.format("%s is not a parsable int (base10) for %s", optionValue, MAX_SSTABLE_AGE_KEY), e); } ... }
The fixed code uses Double to parse the input:
public static Map<String, String> validateOptions(Map<String, String> options, Map<String, String> uncheckedOptions) throws ConfigurationException { String optionValue = options.get(TIMESTAMP_RESOLUTION_KEY); try { if (optionValue != null) TimeUnit.valueOf(optionValue); } catch (IllegalArgumentException e) { throw new ConfigurationException(String.format("timestamp_resolution %s is not valid", optionValue)); } optionValue = options.get(MAX_SSTABLE_AGE_KEY); try { double maxSStableAge = optionValue == null ? DEFAULT_MAX_SSTABLE_AGE_DAYS : Double.parseDouble(optionValue); if (maxSStableAge < 0) { throw new ConfigurationException(String.format("%s must be non-negative: %.2f", MAX_SSTABLE_AGE_KEY, maxSStableAge)); } } catch (NumberFormatException e) { throw new ConfigurationException(String.format("%s is not a parsable int (base10) for %s", optionValue, MAX_SSTABLE_AGE_KEY), e); } ... }