Merge pull request #4630 from BrzVlad/feature-valloc-limit
[mono-project.git] / mono / utils / parse.c
blobaf1377d7012b7e0da4377e0a08e8d563b1a1dd6c
1 /**
2 * \file
3 * Parsing for GC options.
5 * Copyright (C) 2015 Xamarin Inc
7 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
8 */
10 #include <config.h>
11 #include <glib.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <ctype.h>
15 #include <stdlib.h>
17 #include "parse.h"
19 /**
20 * mono_gc_parse_environment_string_extract_number:
21 * \param str points to the first digit of the number
22 * \param out pointer to the variable that will receive the value
23 * Tries to extract a number from the passed string, taking in to account m, k
24 * and g suffixes
25 * \returns TRUE if passing was successful
27 gboolean
28 mono_gc_parse_environment_string_extract_number (const char *str, size_t *out)
30 char *endptr;
31 int len = strlen (str), shift = 0;
32 size_t val;
33 gboolean is_suffix = FALSE;
34 char suffix;
36 if (!len)
37 return FALSE;
39 suffix = str [len - 1];
41 switch (suffix) {
42 case 'g':
43 case 'G':
44 shift += 10;
45 case 'm':
46 case 'M':
47 shift += 10;
48 case 'k':
49 case 'K':
50 shift += 10;
51 is_suffix = TRUE;
52 break;
53 default:
54 if (!isdigit (suffix))
55 return FALSE;
56 break;
59 errno = 0;
60 val = strtol (str, &endptr, 10);
62 if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
63 || (errno != 0 && val == 0) || (endptr == str))
64 return FALSE;
66 if (is_suffix) {
67 size_t unshifted;
69 if (*(endptr + 1)) /* Invalid string. */
70 return FALSE;
72 unshifted = (size_t)val;
73 val <<= shift;
74 if (((size_t)val >> shift) != unshifted) /* value too large */
75 return FALSE;
78 *out = val;
79 return TRUE;