You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-commits@axis.apache.org by ro...@apache.org on 2026/01/25 04:14:04 UTC

(axis-axis2-c-core) 02/05: Fix unsigned integer type handling in code generator (AXIS2C-1492)

This is an automated email from the ASF dual-hosted git repository.

robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-c-core.git

commit 80ec82f0ce9a1a908f7defe8f7777977fb9d1b5f
Author: Robert Lazarski <ro...@gmail.com>
AuthorDate: Sat Jan 24 14:36:03 2026 -1000

    Fix unsigned integer type handling in code generator (AXIS2C-1492)
    
    The issue: xsd:unsignedInt values above 2147483647 (INT_MAX) were
    incorrectly truncated because the generated code used atoi() which
    returns signed int. Values like 3000000000 would overflow to negative
    numbers (-1294967296).
    
    The fix adds proper XSD integer type detection and C type mapping:
    
    Type detection helpers:
    - is_unsigned_integer_type(): Detects unsignedInt, unsignedLong,
      unsignedShort, unsignedByte, positiveInteger, nonNegativeInteger
    - is_64bit_integer_type(): Detects long, unsignedLong, integer types
    - is_integer_type(): Detects all integer types (for free function)
    
    C type mapping:
    - xsd:unsignedInt -> unsigned int
    - xsd:unsignedLong -> uint64_t
    - xsd:unsignedShort -> unsigned int
    - xsd:unsignedByte -> unsigned int
    - xsd:positiveInteger -> uint64_t
    - xsd:nonNegativeInteger -> uint64_t
    
    Conversion functions:
    - Unsigned 32-bit types: strtoul(text_value, NULL, 10)
    - Unsigned 64-bit types: strtoull(text_value, NULL, 10)
    - Signed types: atoi() for 32-bit, strtoll() for 64-bit
    
    Format specifiers:
    - Unsigned 32-bit: %u
    - Unsigned 64-bit: %llu
    - Signed 32-bit: %d
    - Signed 64-bit: %lld
    
    Also fixes the _free function to not call AXIS2_FREE on primitive
    integer types (they're stack values in the struct, not pointers).
    
    Co-Authored-By: Claude Opus 4.5 <no...@anthropic.com>
---
 tools/codegen/native/src/stub_generator.c          | 184 +++++++--
 tools/codegen/native/test/Makefile.am              |   1 +
 .../native/test/include/adb_test_framework.h       |  11 +
 tools/codegen/native/test/src/adb_test_framework.c |   1 +
 .../test/src/test_axis2c_1492_unsigned_int.c       | 429 +++++++++++++++++++++
 5 files changed, 604 insertions(+), 22 deletions(-)

diff --git a/tools/codegen/native/src/stub_generator.c b/tools/codegen/native/src/stub_generator.c
index ad34e107a..b5b693f14 100644
--- a/tools/codegen/native/src/stub_generator.c
+++ b/tools/codegen/native/src/stub_generator.c
@@ -148,6 +148,129 @@ wsdl2c_sanitize_c_identifier(const axutil_env_t *env, const axis2_char_t *wsdl_n
     return result;
 }
 
+/* AXIS2C-1492 FIX: XSD integer type detection and C type mapping
+ *
+ * XSD defines several integer types with different ranges:
+ * - Signed: byte, short, int, long, integer (arbitrary precision)
+ * - Unsigned: unsignedByte, unsignedShort, unsignedInt, unsignedLong,
+ *             positiveInteger, nonNegativeInteger
+ *
+ * This fix ensures proper C type mapping and conversion functions:
+ * - Unsigned types use unsigned int/uint64_t and strtoul()/strtoull()
+ * - Signed types use int/int64_t and atoi()/strtol()/strtoll()
+ */
+
+/* Check if XSD type is an unsigned integer type */
+axis2_bool_t
+is_unsigned_integer_type(const axis2_char_t *xsd_type)
+{
+    if (!xsd_type) {
+        return AXIS2_FALSE;
+    }
+    /* XSD unsigned integer types */
+    if (strstr(xsd_type, "unsignedInt") ||
+        strstr(xsd_type, "unsignedLong") ||
+        strstr(xsd_type, "unsignedShort") ||
+        strstr(xsd_type, "unsignedByte") ||
+        strstr(xsd_type, "positiveInteger") ||
+        strstr(xsd_type, "nonNegativeInteger")) {
+        return AXIS2_TRUE;
+    }
+    return AXIS2_FALSE;
+}
+
+/* Check if XSD type is a 64-bit integer type (long) */
+axis2_bool_t
+is_64bit_integer_type(const axis2_char_t *xsd_type)
+{
+    if (!xsd_type) {
+        return AXIS2_FALSE;
+    }
+    /* XSD long types (signed and unsigned) */
+    if (strstr(xsd_type, "Long") || strstr(xsd_type, "long") ||
+        strstr(xsd_type, "integer") || strstr(xsd_type, "Integer")) {
+        /* "integer" in XSD is arbitrary precision, map to 64-bit */
+        /* But exclude unsignedInt which contains "int" */
+        if (strstr(xsd_type, "unsignedInt") && !strstr(xsd_type, "unsignedInteg")) {
+            return AXIS2_FALSE;
+        }
+        return AXIS2_TRUE;
+    }
+    return AXIS2_FALSE;
+}
+
+/* Check if XSD type is any integer type (signed or unsigned) */
+axis2_bool_t
+is_integer_type(const axis2_char_t *xsd_type)
+{
+    if (!xsd_type) {
+        return AXIS2_FALSE;
+    }
+    if (strstr(xsd_type, "int") || strstr(xsd_type, "Int") ||
+        strstr(xsd_type, "long") || strstr(xsd_type, "Long") ||
+        strstr(xsd_type, "short") || strstr(xsd_type, "Short") ||
+        strstr(xsd_type, "byte") || strstr(xsd_type, "Byte") ||
+        strstr(xsd_type, "integer") || strstr(xsd_type, "Integer")) {
+        return AXIS2_TRUE;
+    }
+    return AXIS2_FALSE;
+}
+
+/* Get the C type string for an XSD integer type */
+const char*
+get_c_integer_type(const axis2_char_t *xsd_type)
+{
+    if (!xsd_type) {
+        return "int";
+    }
+
+    axis2_bool_t is_unsigned = is_unsigned_integer_type(xsd_type);
+    axis2_bool_t is_64bit = is_64bit_integer_type(xsd_type);
+
+    if (is_64bit) {
+        return is_unsigned ? "uint64_t" : "int64_t";
+    } else {
+        return is_unsigned ? "unsigned int" : "int";
+    }
+}
+
+/* Get the conversion function for deserializing an XSD integer type */
+const char*
+get_integer_deserialize_func(const axis2_char_t *xsd_type)
+{
+    if (!xsd_type) {
+        return "atoi";
+    }
+
+    axis2_bool_t is_unsigned = is_unsigned_integer_type(xsd_type);
+    axis2_bool_t is_64bit = is_64bit_integer_type(xsd_type);
+
+    if (is_64bit) {
+        return is_unsigned ? "strtoull(text_value, NULL, 10)" : "strtoll(text_value, NULL, 10)";
+    } else {
+        return is_unsigned ? "strtoul(text_value, NULL, 10)" : "atoi(text_value)";
+    }
+}
+
+/* Get the printf format specifier for an XSD integer type */
+const char*
+get_integer_format_specifier(const axis2_char_t *xsd_type)
+{
+    if (!xsd_type) {
+        return "%d";
+    }
+
+    axis2_bool_t is_unsigned = is_unsigned_integer_type(xsd_type);
+    axis2_bool_t is_64bit = is_64bit_integer_type(xsd_type);
+
+    if (is_64bit) {
+        /* Use PRIu64/PRId64 macros from inttypes.h, but for simplicity use %llu/%lld */
+        return is_unsigned ? "%llu" : "%lld";
+    } else {
+        return is_unsigned ? "%u" : "%d";
+    }
+}
+
 /* Forward declarations for internal functions */
 static axis2_status_t create_output_directory(const axis2_char_t *path, const axutil_env_t *env);
 static axis2_status_t generate_stub_header(wsdl2c_context_t *context, const axutil_env_t *env);
@@ -912,8 +1035,9 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                 }
                 /* Map XSD types to C types */
                 else if (elem->type) {
-                    if (strstr(elem->type, "int") || strstr(elem->type, "Integer")) {
-                        c_type = "int";
+                    /* AXIS2C-1492 FIX: Use helper function for proper integer type mapping */
+                    if (is_integer_type(elem->type)) {
+                        c_type = get_c_integer_type(elem->type);
                     } else if (strstr(elem->type, "boolean") || strstr(elem->type, "bool")) {
                         c_type = "axis2_bool_t";
                     } else if (strstr(elem->type, "double") || strstr(elem->type, "float")) {
@@ -1073,8 +1197,9 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                     c_type = "axiom_node_t*";
                 }
                 else if (elem->type) {
-                    if (strstr(elem->type, "int") || strstr(elem->type, "Integer")) {
-                        c_type = "int";
+                    /* AXIS2C-1492 FIX: Use helper function for proper integer type mapping */
+                    if (is_integer_type(elem->type)) {
+                        c_type = get_c_integer_type(elem->type);
                     } else if (strstr(elem->type, "boolean") || strstr(elem->type, "bool")) {
                         c_type = "axis2_bool_t";
                     } else if (strstr(elem->type, "double") || strstr(elem->type, "float")) {
@@ -1160,10 +1285,11 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                     fprintf(source_file, "        axutil_date_time_free(_this->%s, env);\n", elem_name);
                     fprintf(source_file, "    }\n");
                 } else if (elem->type &&
-                    (strstr(elem->type, "int") || strstr(elem->type, "Integer") ||
+                    (is_integer_type(elem->type) ||
                      strstr(elem->type, "boolean") || strstr(elem->type, "bool") ||
-                     strstr(elem->type, "double") || strstr(elem->type, "float"))) {
-                    /* Primitive types don't need freeing */
+                     strstr(elem->type, "double") || strstr(elem->type, "float") ||
+                     strstr(elem->type, "decimal"))) {
+                    /* Primitive types don't need freeing - AXIS2C-1492 */
                 } else if (!elem->is_typeless && !elem->is_any_type) {
                     /* String types need AXIS2_FREE */
                     fprintf(source_file, "    if (_this->%s) {\n", elem_name);
@@ -1199,8 +1325,9 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                     default_val = "NULL";
                 }
                 else if (elem->type) {
-                    if (strstr(elem->type, "int") || strstr(elem->type, "Integer")) {
-                        c_type = "int";
+                    /* AXIS2C-1492 FIX: Use helper function for proper integer type mapping */
+                    if (is_integer_type(elem->type)) {
+                        c_type = get_c_integer_type(elem->type);
                         default_val = "0";
                     } else if (strstr(elem->type, "boolean") || strstr(elem->type, "bool")) {
                         c_type = "axis2_bool_t";
@@ -1225,8 +1352,9 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                     /* AXIS2C-1182: Generate array accessor functions */
 
                     /* Check if this is a primitive type that needs boxing */
+                    /* AXIS2C-1492 FIX: Use helper function for integer type detection */
                     axis2_bool_t is_primitive = (elem->type &&
-                        (strstr(elem->type, "int") || strstr(elem->type, "Integer") ||
+                        (is_integer_type(elem->type) ||
                          strstr(elem->type, "boolean") || strstr(elem->type, "bool") ||
                          strstr(elem->type, "double") || strstr(elem->type, "float")));
 
@@ -1369,8 +1497,9 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                 if (is_array) {
                     /* AXIS2C-1182: Loop through array and serialize each item */
                     /* Check if this is a primitive type that needs unboxing */
+                    /* AXIS2C-1492 FIX: Use helper function for integer type detection */
                     axis2_bool_t is_primitive = (elem->type &&
-                        (strstr(elem->type, "int") || strstr(elem->type, "Integer") ||
+                        (is_integer_type(elem->type) ||
                          strstr(elem->type, "boolean") || strstr(elem->type, "bool") ||
                          strstr(elem->type, "double") || strstr(elem->type, "float")));
 
@@ -1380,13 +1509,16 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
 
                     if (is_primitive) {
                         /* Primitive types are boxed - need to unbox and convert to string */
-                        if (elem->type && (strstr(elem->type, "int") || strstr(elem->type, "Integer"))) {
-                            fprintf(source_file, "            int *_arr_item = (int*)axutil_array_list_get(_this->%s, env, _ser_i);\n", elem_name);
+                        /* AXIS2C-1492 FIX: Use proper integer type and format specifier */
+                        if (elem->type && is_integer_type(elem->type)) {
+                            const char *int_c_type = get_c_integer_type(elem->type);
+                            const char *int_fmt = get_integer_format_specifier(elem->type);
+                            fprintf(source_file, "            %s *_arr_item = (%s*)axutil_array_list_get(_this->%s, env, _ser_i);\n", int_c_type, int_c_type, elem_name);
                             fprintf(source_file, "            if (_arr_item) {\n");
                             fprintf(source_file, "                ns = axiom_namespace_create(env, \"\", NULL);\n");
                             fprintf(source_file, "                current_element = axiom_element_create(env, parent, \"%s\", ns, &current_node);\n", xml_name);
                             fprintf(source_file, "                if (current_element) {\n");
-                            fprintf(source_file, "                    sprintf(tmp_buf, \"%%d\", *_arr_item);\n");
+                            fprintf(source_file, "                    sprintf(tmp_buf, \"%s\", *_arr_item);\n", int_fmt);
                             fprintf(source_file, "                    axiom_element_set_text(current_element, env, tmp_buf, current_node);\n");
                             fprintf(source_file, "                }\n");
                             fprintf(source_file, "            }\n");
@@ -1448,8 +1580,10 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                         fprintf(source_file, "                AXIS2_FREE(env->allocator, text_value);\n");
                         fprintf(source_file, "                text_value = NULL;\n");
                         fprintf(source_file, "            }\n");
-                    } else if (elem->type && (strstr(elem->type, "int") || strstr(elem->type, "Integer"))) {
-                        fprintf(source_file, "            sprintf(tmp_buf, \"%%d\", _this->%s);\n", elem_name);
+                    /* AXIS2C-1492 FIX: Use proper format specifier for integer types */
+                    } else if (elem->type && is_integer_type(elem->type)) {
+                        const char *int_fmt = get_integer_format_specifier(elem->type);
+                        fprintf(source_file, "            sprintf(tmp_buf, \"%s\", _this->%s);\n", int_fmt, elem_name);
                         fprintf(source_file, "            axiom_element_set_text(current_element, env, tmp_buf, current_node);\n");
                     } else if (elem->type && (strstr(elem->type, "boolean") || strstr(elem->type, "bool"))) {
                         fprintf(source_file, "            axiom_element_set_text(current_element, env, _this->%s ? \"true\" : \"false\", current_node);\n", elem_name);
@@ -1518,8 +1652,9 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                 if (is_array) {
                     /* AXIS2C-1182: Collect array elements into axutil_array_list_t */
                     /* Check if this is a primitive type that needs boxing */
+                    /* AXIS2C-1492 FIX: Use helper function for integer type detection */
                     axis2_bool_t is_primitive = (elem->type &&
-                        (strstr(elem->type, "int") || strstr(elem->type, "Integer") ||
+                        (is_integer_type(elem->type) ||
                          strstr(elem->type, "boolean") || strstr(elem->type, "bool") ||
                          strstr(elem->type, "double") || strstr(elem->type, "float")));
 
@@ -1531,10 +1666,13 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
 
                     if (is_primitive) {
                         /* Box primitive types when deserializing */
-                        if (elem->type && (strstr(elem->type, "int") || strstr(elem->type, "Integer"))) {
-                            fprintf(source_file, "                            int *_boxed = AXIS2_MALLOC(env->allocator, sizeof(int));\n");
+                        /* AXIS2C-1492 FIX: Use proper integer type and conversion function */
+                        if (elem->type && is_integer_type(elem->type)) {
+                            const char *int_c_type = get_c_integer_type(elem->type);
+                            const char *int_deser_func = get_integer_deserialize_func(elem->type);
+                            fprintf(source_file, "                            %s *_boxed = AXIS2_MALLOC(env->allocator, sizeof(%s));\n", int_c_type, int_c_type);
                             fprintf(source_file, "                            if (_boxed) {\n");
-                            fprintf(source_file, "                                *_boxed = atoi(text_value);\n");
+                            fprintf(source_file, "                                *_boxed = %s;\n", int_deser_func);
                             fprintf(source_file, "                                axutil_array_list_add(obj->%s, env, _boxed);\n", elem_name);
                             fprintf(source_file, "                            }\n");
                         } else if (elem->type && (strstr(elem->type, "boolean") || strstr(elem->type, "bool"))) {
@@ -1573,9 +1711,11 @@ generate_adb_complex_types(wsdl2c_context_t *context, const axutil_env_t *env)
                     fprintf(source_file, "                            axutil_date_time_deserialize_date_time(obj->%s, env, text_value);\n", elem_name);
                     fprintf(source_file, "                        }\n");
                     fprintf(source_file, "                    }\n");
-                } else if (elem->type && (strstr(elem->type, "int") || strstr(elem->type, "Integer"))) {
+                /* AXIS2C-1492 FIX: Use proper integer conversion function */
+                } else if (elem->type && is_integer_type(elem->type)) {
+                    const char *int_deser_func = get_integer_deserialize_func(elem->type);
                     fprintf(source_file, "                    if (text_value) {\n");
-                    fprintf(source_file, "                        obj->%s = atoi(text_value);\n", elem_name);
+                    fprintf(source_file, "                        obj->%s = %s;\n", elem_name, int_deser_func);
                     fprintf(source_file, "                    }\n");
                 } else if (elem->type && (strstr(elem->type, "boolean") || strstr(elem->type, "bool"))) {
                     fprintf(source_file, "                    if (text_value) {\n");
diff --git a/tools/codegen/native/test/Makefile.am b/tools/codegen/native/test/Makefile.am
index 0ddc38902..96e96c54f 100644
--- a/tools/codegen/native/test/Makefile.am
+++ b/tools/codegen/native/test/Makefile.am
@@ -44,6 +44,7 @@ adb_test_runner_SOURCES = \
     src/test_axis2c_1613_error_on_null.c \
     src/test_axis2c_1182_array_add_function.c \
     src/test_axis2c_1506_ehealth_schema.c \
+    src/test_axis2c_1492_unsigned_int.c \
     src/axis2_stub_compat.c
 
 # Include directories
diff --git a/tools/codegen/native/test/include/adb_test_framework.h b/tools/codegen/native/test/include/adb_test_framework.h
index 11f33c660..b3521333c 100644
--- a/tools/codegen/native/test/include/adb_test_framework.h
+++ b/tools/codegen/native/test/include/adb_test_framework.h
@@ -416,6 +416,17 @@ extern int axis2c_1182_test_count;
 extern adb_test_case_t axis2c_1506_tests[];
 extern int axis2c_1506_test_count;
 
+/* AXIS2C-1492: Unsigned integer type handling
+ *
+ * Issue: xsd:unsignedInt values above INT_MAX are truncated because
+ * the generated code uses atoi() which returns signed int.
+ *
+ * Fix: Uses proper type mapping (unsigned int, uint64_t) and
+ * conversion functions (strtoul, strtoull) for unsigned types.
+ */
+extern adb_test_case_t axis2c_1492_tests[];
+extern int axis2c_1492_test_count;
+
 /* Global test statistics */
 extern adb_test_stats_t g_test_stats;
 
diff --git a/tools/codegen/native/test/src/adb_test_framework.c b/tools/codegen/native/test/src/adb_test_framework.c
index 9953d4056..4616e50e0 100644
--- a/tools/codegen/native/test/src/adb_test_framework.c
+++ b/tools/codegen/native/test/src/adb_test_framework.c
@@ -472,6 +472,7 @@ int main(int argc, char *argv[]) {
     adb_run_test_suite(axis2c_1613_tests, axis2c_1613_test_count);
     adb_run_test_suite(axis2c_1182_tests, axis2c_1182_test_count);
     adb_run_test_suite(axis2c_1506_tests, axis2c_1506_test_count);
+    adb_run_test_suite(axis2c_1492_tests, axis2c_1492_test_count);
 
     adb_test_cleanup();
 
diff --git a/tools/codegen/native/test/src/test_axis2c_1492_unsigned_int.c b/tools/codegen/native/test/src/test_axis2c_1492_unsigned_int.c
new file mode 100644
index 000000000..dd92d899e
--- /dev/null
+++ b/tools/codegen/native/test/src/test_axis2c_1492_unsigned_int.c
@@ -0,0 +1,429 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * test_axis2c_1492_unsigned_int.c
+ *
+ * AXIS2C-1492 Tests for Unsigned Integer Type Handling
+ *
+ * Issue: xsd:unsignedInt values above 2147483647 are truncated because
+ * the generated code uses atoi() which returns signed int, causing
+ * values above INT_MAX to overflow to negative numbers.
+ *
+ * Fix: The native generator now uses proper type mapping and conversion:
+ * - xsd:unsignedInt -> unsigned int with strtoul()
+ * - xsd:unsignedLong -> uint64_t with strtoull()
+ * - xsd:unsignedShort -> unsigned int with strtoul()
+ * - xsd:unsignedByte -> unsigned int with strtoul()
+ *
+ * This ensures values like 4294967295 (max unsigned int) are handled
+ * correctly without overflow.
+ */
+
+#include "adb_test_framework.h"
+#include <stdint.h>
+#include <limits.h>
+
+/* Simulate the helper functions from stub_generator.c for testing
+ * These use the exact same logic as the actual implementation.
+ */
+
+/* Check if XSD type is an unsigned integer type */
+static int
+test_is_unsigned_integer_type(const char *xsd_type)
+{
+    if (!xsd_type) {
+        return 0;
+    }
+    if (strstr(xsd_type, "unsignedInt") ||
+        strstr(xsd_type, "unsignedLong") ||
+        strstr(xsd_type, "unsignedShort") ||
+        strstr(xsd_type, "unsignedByte") ||
+        strstr(xsd_type, "positiveInteger") ||
+        strstr(xsd_type, "nonNegativeInteger")) {
+        return 1;
+    }
+    return 0;
+}
+
+/* Check if XSD type is a 64-bit integer type (long) */
+static int
+test_is_64bit_integer_type(const char *xsd_type)
+{
+    if (!xsd_type) {
+        return 0;
+    }
+    if (strstr(xsd_type, "Long") || strstr(xsd_type, "long") ||
+        strstr(xsd_type, "integer") || strstr(xsd_type, "Integer")) {
+        /* "integer" in XSD is arbitrary precision, map to 64-bit */
+        /* But exclude unsignedInt which contains "int" */
+        if (strstr(xsd_type, "unsignedInt") && !strstr(xsd_type, "unsignedInteg")) {
+            return 0;
+        }
+        return 1;
+    }
+    return 0;
+}
+
+/* Check if XSD type is any integer type (signed or unsigned) */
+static int
+test_is_integer_type(const char *xsd_type)
+{
+    if (!xsd_type) {
+        return 0;
+    }
+    if (strstr(xsd_type, "int") || strstr(xsd_type, "Int") ||
+        strstr(xsd_type, "long") || strstr(xsd_type, "Long") ||
+        strstr(xsd_type, "short") || strstr(xsd_type, "Short") ||
+        strstr(xsd_type, "byte") || strstr(xsd_type, "Byte") ||
+        strstr(xsd_type, "integer") || strstr(xsd_type, "Integer")) {
+        return 1;
+    }
+    return 0;
+}
+
+/* Get the C type string for an XSD integer type */
+static const char*
+test_get_c_integer_type(const char *xsd_type)
+{
+    if (!xsd_type) {
+        return "int";
+    }
+
+    int is_unsigned = test_is_unsigned_integer_type(xsd_type);
+    int is_64bit = test_is_64bit_integer_type(xsd_type);
+
+    if (is_64bit) {
+        return is_unsigned ? "uint64_t" : "int64_t";
+    } else {
+        return is_unsigned ? "unsigned int" : "int";
+    }
+}
+
+/* Get the conversion function for deserializing an XSD integer type */
+static const char*
+test_get_deserialize_func(const char *xsd_type)
+{
+    if (!xsd_type) {
+        return "atoi";
+    }
+
+    int is_unsigned = test_is_unsigned_integer_type(xsd_type);
+    int is_64bit = test_is_64bit_integer_type(xsd_type);
+
+    if (is_64bit) {
+        return is_unsigned ? "strtoull" : "strtoll";
+    } else {
+        return is_unsigned ? "strtoul" : "atoi";
+    }
+}
+
+/* Get the printf format specifier for an XSD integer type */
+static const char*
+test_get_format_specifier(const char *xsd_type)
+{
+    if (!xsd_type) {
+        return "%d";
+    }
+
+    int is_unsigned = test_is_unsigned_integer_type(xsd_type);
+    int is_64bit = test_is_64bit_integer_type(xsd_type);
+
+    if (is_64bit) {
+        return is_unsigned ? "%llu" : "%lld";
+    } else {
+        return is_unsigned ? "%u" : "%d";
+    }
+}
+
+/* Test unsigned type detection */
+adb_test_result_t test_axis2c_1492_unsigned_type_detection(void) {
+    printf("Testing AXIS2C-1492: Unsigned type detection...\n");
+
+    struct {
+        const char *type;
+        int expected;
+    } tests[] = {
+        /* Unsigned types - should return true */
+        {"unsignedInt", 1},
+        {"xsd:unsignedInt", 1},
+        {"unsignedLong", 1},
+        {"unsignedShort", 1},
+        {"unsignedByte", 1},
+        {"positiveInteger", 1},
+        {"nonNegativeInteger", 1},
+        /* Signed types should return false */
+        {"int", 0},
+        {"xsd:int", 0},
+        {"long", 0},
+        {"short", 0},
+        {"byte", 0},
+        {"integer", 0},
+        {"negativeInteger", 0},
+    };
+
+    int count = sizeof(tests) / sizeof(tests[0]);
+    int i;
+    for (i = 0; i < count; i++) {
+        int result = test_is_unsigned_integer_type(tests[i].type);
+        printf("  is_unsigned_integer_type(\"%s\") = %s (expected %s)\n",
+               tests[i].type,
+               result ? "true" : "false",
+               tests[i].expected ? "true" : "false");
+        ADB_ASSERT_TRUE(result == tests[i].expected,
+                       "Unsigned type detection should match expected");
+    }
+
+    printf("  Unsigned type detection: PASS\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test C type mapping */
+adb_test_result_t test_axis2c_1492_c_type_mapping(void) {
+    printf("Testing AXIS2C-1492: C type mapping...\n");
+
+    struct {
+        const char *xsd_type;
+        const char *expected_c_type;
+    } tests[] = {
+        /* Signed 32-bit */
+        {"int", "int"},
+        {"short", "int"},
+        {"byte", "int"},
+        /* Unsigned 32-bit - the AXIS2C-1492 fix */
+        {"unsignedInt", "unsigned int"},
+        {"unsignedShort", "unsigned int"},
+        {"unsignedByte", "unsigned int"},
+        /* Signed 64-bit */
+        {"long", "int64_t"},
+        {"integer", "int64_t"},
+        {"negativeInteger", "int64_t"},
+        /* Unsigned 64-bit */
+        {"unsignedLong", "uint64_t"},
+        {"positiveInteger", "uint64_t"},
+        {"nonNegativeInteger", "uint64_t"},
+    };
+
+    int count = sizeof(tests) / sizeof(tests[0]);
+    int i;
+    for (i = 0; i < count; i++) {
+        const char *result = test_get_c_integer_type(tests[i].xsd_type);
+        printf("  get_c_integer_type(\"%s\") = \"%s\" (expected \"%s\")\n",
+               tests[i].xsd_type, result, tests[i].expected_c_type);
+        ADB_ASSERT_TRUE(strcmp(result, tests[i].expected_c_type) == 0,
+                       "C type mapping should match expected");
+    }
+
+    printf("  C type mapping: PASS\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test conversion function selection */
+adb_test_result_t test_axis2c_1492_conversion_functions(void) {
+    printf("Testing AXIS2C-1492: Conversion function selection...\n");
+
+    struct {
+        const char *xsd_type;
+        const char *expected_func;
+    } tests[] = {
+        /* Signed 32-bit uses atoi */
+        {"int", "atoi"},
+        {"short", "atoi"},
+        {"byte", "atoi"},
+        /* Unsigned 32-bit uses strtoul - the AXIS2C-1492 fix */
+        {"unsignedInt", "strtoul"},
+        {"unsignedShort", "strtoul"},
+        {"unsignedByte", "strtoul"},
+        /* Signed 64-bit uses strtoll */
+        {"long", "strtoll"},
+        {"integer", "strtoll"},
+        /* Unsigned 64-bit uses strtoull */
+        {"unsignedLong", "strtoull"},
+        {"positiveInteger", "strtoull"},
+    };
+
+    int count = sizeof(tests) / sizeof(tests[0]);
+    int i;
+    for (i = 0; i < count; i++) {
+        const char *result = test_get_deserialize_func(tests[i].xsd_type);
+        printf("  get_deserialize_func(\"%s\") = \"%s\" (expected \"%s\")\n",
+               tests[i].xsd_type, result, tests[i].expected_func);
+        ADB_ASSERT_TRUE(strcmp(result, tests[i].expected_func) == 0,
+                       "Conversion function should match expected");
+    }
+
+    printf("  Conversion function selection: PASS\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test format specifier selection */
+adb_test_result_t test_axis2c_1492_format_specifiers(void) {
+    printf("Testing AXIS2C-1492: Format specifier selection...\n");
+
+    struct {
+        const char *xsd_type;
+        const char *expected_format;
+    } tests[] = {
+        /* Signed 32-bit uses %d */
+        {"int", "%d"},
+        {"short", "%d"},
+        {"byte", "%d"},
+        /* Unsigned 32-bit uses %u - the AXIS2C-1492 fix */
+        {"unsignedInt", "%u"},
+        {"unsignedShort", "%u"},
+        {"unsignedByte", "%u"},
+        /* Signed 64-bit uses %lld */
+        {"long", "%lld"},
+        {"integer", "%lld"},
+        /* Unsigned 64-bit uses %llu */
+        {"unsignedLong", "%llu"},
+        {"positiveInteger", "%llu"},
+    };
+
+    int count = sizeof(tests) / sizeof(tests[0]);
+    int i;
+    for (i = 0; i < count; i++) {
+        const char *result = test_get_format_specifier(tests[i].xsd_type);
+        printf("  get_format_specifier(\"%s\") = \"%s\" (expected \"%s\")\n",
+               tests[i].xsd_type, result, tests[i].expected_format);
+        ADB_ASSERT_TRUE(strcmp(result, tests[i].expected_format) == 0,
+                       "Format specifier should match expected");
+    }
+
+    printf("  Format specifier selection: PASS\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test the actual bug: large unsigned values */
+adb_test_result_t test_axis2c_1492_large_unsigned_values(void) {
+    printf("Testing AXIS2C-1492: Large unsigned value handling...\n");
+
+    /* Test value that would overflow if using atoi */
+    const char *text_value = "3000000000";  /* Greater than INT_MAX (2147483647) */
+
+    /* Old buggy approach: atoi() returns signed int, causes overflow */
+    int buggy_result = atoi(text_value);
+    printf("  Old buggy atoi(\"%s\") = %d (WRONG - overflow to negative)\n",
+           text_value, buggy_result);
+    ADB_ASSERT_TRUE(buggy_result < 0, "atoi should overflow to negative for large values");
+
+    /* New fixed approach: strtoul() returns unsigned, no overflow */
+    unsigned int fixed_result = strtoul(text_value, NULL, 10);
+    printf("  New fixed strtoul(\"%s\") = %u (CORRECT)\n",
+           text_value, fixed_result);
+    ADB_ASSERT_TRUE(fixed_result == 3000000000U, "strtoul should handle large unsigned values");
+
+    /* Test maximum unsigned int value */
+    const char *max_uint = "4294967295";
+    unsigned int max_result = strtoul(max_uint, NULL, 10);
+    printf("  strtoul(\"%s\") = %u (max unsigned int)\n", max_uint, max_result);
+    ADB_ASSERT_TRUE(max_result == UINT_MAX, "strtoul should handle max unsigned int");
+
+    /* Test maximum uint64_t value */
+    const char *max_uint64 = "18446744073709551615";
+    uint64_t max64_result = strtoull(max_uint64, NULL, 10);
+    printf("  strtoull(\"%s\") = %llu (max uint64_t)\n",
+           max_uint64, (unsigned long long)max64_result);
+    ADB_ASSERT_TRUE(max64_result == UINT64_MAX, "strtoull should handle max uint64_t");
+
+    printf("  Large unsigned value handling: PASS\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test integer type detection (for free function primitive check) */
+adb_test_result_t test_axis2c_1492_integer_type_detection(void) {
+    printf("Testing AXIS2C-1492: Integer type detection (for free function)...\n");
+
+    struct {
+        const char *type;
+        int expected;
+    } tests[] = {
+        /* All integer types should be detected */
+        {"int", 1},
+        {"xsd:int", 1},
+        {"unsignedInt", 1},
+        {"long", 1},
+        {"unsignedLong", 1},
+        {"short", 1},
+        {"unsignedShort", 1},
+        {"byte", 1},
+        {"unsignedByte", 1},
+        {"integer", 1},
+        {"positiveInteger", 1},
+        {"negativeInteger", 1},
+        {"nonNegativeInteger", 1},
+        {"nonPositiveInteger", 1},
+        /* Non-integer types should NOT be detected */
+        {"string", 0},
+        {"dateTime", 0},
+        {"base64Binary", 0},
+        {"boolean", 0},
+        {"double", 0},
+        {"float", 0},
+    };
+
+    int count = sizeof(tests) / sizeof(tests[0]);
+    int i;
+    for (i = 0; i < count; i++) {
+        int result = test_is_integer_type(tests[i].type);
+        printf("  is_integer_type(\"%s\") = %s (expected %s)\n",
+               tests[i].type,
+               result ? "true" : "false",
+               tests[i].expected ? "true" : "false");
+        ADB_ASSERT_TRUE(result == tests[i].expected,
+                       "Integer type detection should match expected");
+    }
+
+    printf("  Integer type detection: PASS\n");
+    return ADB_TEST_SUCCESS;
+}
+
+/* Test case array for AXIS2C-1492 tests */
+adb_test_case_t axis2c_1492_tests[] = {
+    {
+        "test_axis2c_1492_unsigned_type_detection",
+        "Test XSD unsigned type detection",
+        test_axis2c_1492_unsigned_type_detection
+    },
+    {
+        "test_axis2c_1492_c_type_mapping",
+        "Test XSD to C type mapping",
+        test_axis2c_1492_c_type_mapping
+    },
+    {
+        "test_axis2c_1492_conversion_functions",
+        "Test string-to-integer conversion function selection",
+        test_axis2c_1492_conversion_functions
+    },
+    {
+        "test_axis2c_1492_format_specifiers",
+        "Test printf format specifier selection",
+        test_axis2c_1492_format_specifiers
+    },
+    {
+        "test_axis2c_1492_large_unsigned_values",
+        "Test large unsigned value handling (the actual bug)",
+        test_axis2c_1492_large_unsigned_values
+    },
+    {
+        "test_axis2c_1492_integer_type_detection",
+        "Test integer type detection (for free function primitive check)",
+        test_axis2c_1492_integer_type_detection
+    }
+};
+
+int axis2c_1492_test_count = sizeof(axis2c_1492_tests) / sizeof(axis2c_1492_tests[0]);