<p>Friendly Automation <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/11358">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Benjamin Keith Ford: Looks good to me, but someone else must approve
  Joshua Colp: Looks good to me, approved
  Friendly Automation: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">conversions.c: Add conversions for largest max sized integer<br><br>Added a conversion for umax (largest maximum sized integer allowed). Adjusted<br>the other current conversion functions (uint and ulong) to be derivatives of<br>the umax conversion since they are simply subsets of umax.<br><br>Also made the negative check move the pointer on spaces since strtoumax does it<br>anyways.<br><br>Change-Id: I56c2ef2629d49b524c8df58af12951c181f81f08<br>---<br>M include/asterisk/conversions.h<br>M main/conversions.c<br>M tests/test_conversions.c<br>3 files changed, 95 insertions(+), 14 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/conversions.h b/include/asterisk/conversions.h</span><br><span>index 2997760..55906e6 100644</span><br><span>--- a/include/asterisk/conversions.h</span><br><span>+++ b/include/asterisk/conversions.h</span><br><span>@@ -23,6 +23,8 @@</span><br><span> #ifndef _ASTERISK_CONVERSIONS_H</span><br><span> #define _ASTERISK_CONVERSIONS_H</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*!</span><br><span>  * \brief Convert the given string to an unsigned integer</span><br><span>  *</span><br><span>@@ -59,4 +61,22 @@</span><br><span>  */</span><br><span> int ast_str_to_ulong(const char *str, unsigned long *res);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Convert the given string to an unsigned max size integer</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This function will return failure for the following reasons:</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ *   The given string to convert is NULL</span><br><span style="color: hsl(120, 100%, 40%);">+ *   The given string to convert is empty.</span><br><span style="color: hsl(120, 100%, 40%);">+ *   The given string to convert is negative (starts with a '-')</span><br><span style="color: hsl(120, 100%, 40%);">+ *   The given string to convert contains non numeric values</span><br><span style="color: hsl(120, 100%, 40%);">+ *   Once converted the number is out of range (greater than UINTMAX_MAX)</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param str The string to convert</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param res [out] The converted value</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns -1 if it fails to convert, 0 on success</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_str_to_umax(const char *str, uintmax_t *res);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif /* _ASTERISK_CONVERSIONS_H */</span><br><span>diff --git a/main/conversions.c b/main/conversions.c</span><br><span>index e73e1a2..2fd3146 100644</span><br><span>--- a/main/conversions.c</span><br><span>+++ b/main/conversions.c</span><br><span>@@ -26,22 +26,26 @@</span><br><span> #include <ctype.h></span><br><span> #include <errno.h></span><br><span> #include <limits.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <inttypes.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span> </span><br><span> #include "asterisk/conversions.h"</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int str_is_negative(const char *str)</span><br><span style="color: hsl(120, 100%, 40%);">+static int str_is_negative(const char **str)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Ignore any preceding white space */</span><br><span style="color: hsl(0, 100%, 40%);">-  while (isspace(*str) && *++str);</span><br><span style="color: hsl(0, 100%, 40%);">-        return *str == '-';</span><br><span style="color: hsl(120, 100%, 40%);">+   /*</span><br><span style="color: hsl(120, 100%, 40%);">+     * Ignore any preceding white space. It's okay to move the pointer here</span><br><span style="color: hsl(120, 100%, 40%);">+    * since the converting function would do the same, i.e. skip white space.</span><br><span style="color: hsl(120, 100%, 40%);">+     */</span><br><span style="color: hsl(120, 100%, 40%);">+   while (isspace(**str)) ++*str;</span><br><span style="color: hsl(120, 100%, 40%);">+        return **str == '-';</span><br><span> }</span><br><span> </span><br><span> int ast_str_to_uint(const char *str, unsigned int *res)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-   unsigned long val;</span><br><span style="color: hsl(120, 100%, 40%);">+    uintmax_t val;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if (ast_str_to_ulong(str, &val) || val > UINT_MAX) {</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ast_str_to_umax(str, &val) || val > UINT_MAX) {</span><br><span>           return -1;</span><br><span>   }</span><br><span> </span><br><span>@@ -51,15 +55,27 @@</span><br><span> </span><br><span> int ast_str_to_ulong(const char *str, unsigned long *res)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       char *end;</span><br><span style="color: hsl(0, 100%, 40%);">-      unsigned long val;</span><br><span style="color: hsl(120, 100%, 40%);">+    uintmax_t val;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-      if (!str || str_is_negative(str)) {</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ast_str_to_umax(str, &val) || val > ULONG_MAX) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   *res = val;</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_str_to_umax(const char *str, uintmax_t *res)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       char *end;</span><br><span style="color: hsl(120, 100%, 40%);">+    uintmax_t val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!str || str_is_negative(&str)) {</span><br><span>             return -1;</span><br><span>   }</span><br><span> </span><br><span>        errno = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-      val = strtoul(str, &end, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+      val = strtoumax(str, &end, 0);</span><br><span> </span><br><span>       /*</span><br><span>    * If str equals end then no digits were found. If end is not pointing to</span><br><span>@@ -67,11 +83,10 @@</span><br><span>       * converted, but some characters that could not, which we'll consider</span><br><span>    * invalid.</span><br><span>   */</span><br><span style="color: hsl(0, 100%, 40%);">-     if ((str == end || *end != '\0' || (errno == ERANGE && val == ULONG_MAX))) {</span><br><span style="color: hsl(120, 100%, 40%);">+  if ((str == end || *end != '\0' || (errno == ERANGE && val == UINTMAX_MAX))) {</span><br><span>               return -1;</span><br><span>   }</span><br><span> </span><br><span>        *res = val;</span><br><span>  return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> }</span><br><span>diff --git a/tests/test_conversions.c b/tests/test_conversions.c</span><br><span>index 689aba9..1a765b4 100644</span><br><span>--- a/tests/test_conversions.c</span><br><span>+++ b/tests/test_conversions.c</span><br><span>@@ -62,6 +62,7 @@</span><br><span>      }</span><br><span> </span><br><span>        ast_test_validate(test, ast_str_to_uint(NULL, &val));</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_test_validate(test, ast_str_to_uint("\0", &val));</span><br><span>  ast_test_validate(test, ast_str_to_uint(invalid, &val));</span><br><span>         ast_test_validate(test, ast_str_to_uint(invalid_partial, &val));</span><br><span>         ast_test_validate(test, ast_str_to_uint(negative, &val));</span><br><span>@@ -103,6 +104,7 @@</span><br><span>  }</span><br><span> </span><br><span>        ast_test_validate(test, ast_str_to_ulong(NULL, &val));</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_test_validate(test, ast_str_to_ulong("\0", &val));</span><br><span>         ast_test_validate(test, ast_str_to_ulong(invalid, &val));</span><br><span>        ast_test_validate(test, ast_str_to_ulong(invalid_partial, &val));</span><br><span>        ast_test_validate(test, ast_str_to_ulong(negative, &val));</span><br><span>@@ -119,10 +121,53 @@</span><br><span>       return AST_TEST_PASS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+AST_TEST_DEFINE(str_to_umax)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *invalid = "abc";</span><br><span style="color: hsl(120, 100%, 40%);">+        const char *invalid_partial = "7abc";</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *negative = "-7";</span><br><span style="color: hsl(120, 100%, 40%);">+        const char *negative_spaces = "  -7";</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *out_of_range = "99999999999999999999999999999999999999999999999999";</span><br><span style="color: hsl(120, 100%, 40%);">+    const char *spaces = "  ";</span><br><span style="color: hsl(120, 100%, 40%);">+  const char *valid = "7";</span><br><span style="color: hsl(120, 100%, 40%);">+    const char *valid_spaces = "  7";</span><br><span style="color: hsl(120, 100%, 40%);">+   uintmax_t val;</span><br><span style="color: hsl(120, 100%, 40%);">+        char str[64];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case TEST_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+               info->name = __func__;</span><br><span style="color: hsl(120, 100%, 40%);">+             info->category = CATEGORY;</span><br><span style="color: hsl(120, 100%, 40%);">+         info->summary = "convert a string to an unsigned max size integer";</span><br><span style="color: hsl(120, 100%, 40%);">+              info->description = info->summary;</span><br><span style="color: hsl(120, 100%, 40%);">+              return AST_TEST_NOT_RUN;</span><br><span style="color: hsl(120, 100%, 40%);">+      case TEST_EXECUTE:</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_validate(test, ast_str_to_umax(NULL, &val));</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_test_validate(test, ast_str_to_umax("\0", &val));</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_validate(test, ast_str_to_umax(invalid, &val));</span><br><span style="color: hsl(120, 100%, 40%);">+  ast_test_validate(test, ast_str_to_umax(invalid_partial, &val));</span><br><span style="color: hsl(120, 100%, 40%);">+  ast_test_validate(test, ast_str_to_umax(negative, &val));</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_test_validate(test, ast_str_to_umax(negative_spaces, &val));</span><br><span style="color: hsl(120, 100%, 40%);">+  ast_test_validate(test, ast_str_to_umax(out_of_range, &val));</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_test_validate(test, ast_str_to_umax(spaces, &val));</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_validate(test, !ast_str_to_umax(valid, &val));</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_validate(test, !ast_str_to_umax(valid_spaces, &val));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  ast_test_validate(test, snprintf(str, sizeof(str), "%lu", UINTMAX_MAX) > 0);</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_test_validate(test, !ast_str_to_umax(str, &val));</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_test_validate(test, val == UINTMAX_MAX);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return AST_TEST_PASS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int load_module(void)</span><br><span> {</span><br><span>      AST_TEST_REGISTER(str_to_uint);</span><br><span>      AST_TEST_REGISTER(str_to_ulong);</span><br><span style="color: hsl(120, 100%, 40%);">+      AST_TEST_REGISTER(str_to_umax);</span><br><span>      return AST_MODULE_LOAD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -130,7 +175,8 @@</span><br><span> {</span><br><span>  AST_TEST_UNREGISTER(str_to_uint);</span><br><span>    AST_TEST_UNREGISTER(str_to_ulong);</span><br><span style="color: hsl(120, 100%, 40%);">+    AST_TEST_UNREGISTER(str_to_umax);</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "URI test module");</span><br><span style="color: hsl(120, 100%, 40%);">+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Conversions test module");</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/11358">change 11358</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/11358"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I56c2ef2629d49b524c8df58af12951c181f81f08 </div>
<div style="display:none"> Gerrit-Change-Number: 11358 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Benjamin Keith Ford <bford@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>