python-tabulate: improves coverage of fuzzer (#10156)

This PR:
- Adds helper functions to allow different inputs in to passed into
`tabulate`.
- Fuzzes `simple_separated_format`
This commit is contained in:
jesslatimer 2023-04-25 18:30:25 -07:00 committed by GitHub
parent c1e5dbfe3d
commit 963effbb97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 84 additions and 7 deletions

View File

@ -13,32 +13,109 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import os
import sys import sys
import json import json
import atheris import atheris
import tabulate import tabulate
def ConsumeListofLists(fdp):
list = []
num_lists = fdp.ConsumeIntInRange(1, 100)
for _ in range(num_lists):
list.append(fdp.ConsumeFloatListInRange(num_lists, 1, 1000))
return list
def ConsumeDictionary(fdp):
dictionary = {}
dict_size = fdp.ConsumeIntInRange(1, 100)
for _ in range(dict_size):
dictionary[fdp.ConsumeUnicodeNoSurrogates(
fdp.ConsumeIntInRange(0, 100))] = fdp.ConsumeUnicodeNoSurrogates(fdp.ConsumeIntInRange(0, 100))
return dictionary
def ConsumeNestedDictionary(fdp):
dictionary = {}
dict_size = fdp.ConsumeIntInRange(1, 100)
for _ in range(dict_size):
t_or_f = fdp.ConsumeBool()
if t_or_f is True:
dictionary[fdp.ConsumeUnicodeNoSurrogates(
fdp.ConsumeIntInRange(0, 100))] = ConsumeDictionary(fdp)
else:
dictionary[fdp.ConsumeUnicodeNoSurrogates(
fdp.ConsumeIntInRange(0, 100))] = fdp.ConsumeUnicodeNoSurrogates(
fdp.ConsumeIntInRange(0, 100))
return dictionary
def ConsumeDictionaryWithList(fdp):
dictionary = {}
dict_size = fdp.ConsumeIntInRange(1, 100)
for _ in range(dict_size):
dictionary[fdp.ConsumeUnicodeNoSurrogates(
fdp.ConsumeIntInRange(1, 100))] = fdp.ConsumeIntListInRange(
fdp.ConsumeIntInRange(1, 100), 1, 100)
return dictionary
def TestOneInput(data): def TestOneInput(data):
fdp = atheris.FuzzedDataProvider(data) fdp = atheris.FuzzedDataProvider(data)
tabulate_formats = list(tabulate._table_formats.keys()) table_format = fdp.PickValueInList(tabulate.tabulate_formats)
table_format = tabulate_formats[fdp.ConsumeIntInRange(0, len(tabulate_formats)-1)] col_align_num = fdp.PickValueInList(
["right", "center", "left", "decimal", None])
col_align_str = fdp.PickValueInList(
["right", "center", "left", None])
# Create random dictionary # Create random dictionary
try: try:
fuzzed_dict = json.loads(fdp.ConsumeString(sys.maxsize)) fuzzed_dict = json.loads(
fdp.ConsumeUnicodeNoSurrogates(fdp.ConsumeIntInRange(0, 100)))
except: except:
return return
if type(fuzzed_dict) is not dict: if type(fuzzed_dict) is not dict:
return return
# Test tabulate with various inputs
t1 = tabulate.tabulate( t1 = tabulate.tabulate(
fuzzed_dict, fuzzed_dict,
tablefmt=table_format tablefmt=table_format
) )
return t2 = tabulate.tabulate(
ConsumeDictionary(fdp),
tablefmt=table_format,
headers="keys"
)
t3 = tabulate.tabulate(
ConsumeListofLists(fdp),
tablefmt=table_format,
headers="firstrow"
)
t4 = tabulate.tabulate(
ConsumeNestedDictionary(fdp),
tablefmt=table_format
)
t5 = tabulate.tabulate(
ConsumeDictionaryWithList(fdp),
tablefmt=table_format
)
almost_all_args = tabulate.tabulate(
ConsumeListofLists(fdp),
tablefmt=table_format,
headers="firstrow",
showindex="always",
numalign=col_align_num,
stralign=col_align_str,
floatfmt=".4f"
)
# make and implement custom table formator
custom_separator = tabulate.simple_separated_format(
fdp.ConsumeUnicodeNoSurrogates(fdp.ConsumeIntInRange(1, 100)))
tabulate.tabulate(ConsumeDictionary(fdp), tablefmt=custom_separator)
def main(): def main():