{"record":{"id":"00822550c9b83576","repo":"apache/seatunnel","slug":"byte-overflow","errorCode":null,"errorMessage":"byte overflow","messagePattern":"byte overflow","errorType":"exception","errorClass":"ArithmeticException","httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/utils/ObjectUtils.java","lineNumber":34,"sourceCode":" */\n\npackage org.apache.seatunnel.connectors.seatunnel.jdbc.utils;\n\nimport java.math.BigDecimal;\nimport java.math.BigInteger;\n\npublic class ObjectUtils {\n    /**\n     * Returns a number {@code Object} whose value is {@code (number + augend)}, Note: This method\n     * will throw {@link ArithmeticException} if number overflows.\n     */\n    public static Object plus(Object number, int augend) throws ArithmeticException {\n        if (number instanceof Byte) {\n            // Byte and Short are promoted to int before addition; check their own ranges\n            // before narrowing the result back to the original type.\n            int result = Math.addExact((Byte) number, augend);\n            if (result < Byte.MIN_VALUE || result > Byte.MAX_VALUE) {\n                throw new ArithmeticException(\"byte overflow\");\n            }\n            return (byte) result;\n        } else if (number instanceof Short) {\n            int result = Math.addExact((Short) number, augend);\n            if (result < Short.MIN_VALUE || result > Short.MAX_VALUE) {\n                throw new ArithmeticException(\"short overflow\");\n            }\n            return (short) result;\n        } else if (number instanceof Integer) {\n            return Math.addExact((Integer) number, augend);\n        } else if (number instanceof Long) {\n            return Math.addExact((Long) number, augend);\n        } else if (number instanceof Float) {\n            return ((Float) number) + augend;\n        } else if (number instanceof Double) {\n            return ((Double) number) + augend;\n        } else if (number instanceof BigInteger) {\n            return ((BigInteger) number).add(BigInteger.valueOf(augend));","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/utils/ObjectUtils.java#L16-L52","documentation":"ObjectUtils.plus adds an int to a numeric value while preserving the original type (Byte, Short, Integer, Long...). For Byte (and Short) it promotes to int, adds, and throws ArithmeticException('byte overflow') if the result no longer fits the original type's range ([-128, 127] for byte). This protects against silent narrowing truncation.","triggerScenarios":"Calling ObjectUtils.plus with a Byte value whose sum with augend leaves byte range — e.g. plus((byte)100, 100) or incrementing a byte-typed counter repeatedly until it exceeds 127.","commonSituations":"Cursor/offset arithmetic on a column value stored as TINYINT that keeps incrementing past 127; batch position tracking initialized from a byte-typed DB value; algorithmic loops using plus on small-typed accumulators.","solutions":["Use a wider accumulator type (int/long) before incrementing, or start from a widened value","Cap the increment so the result stays in range, or wrap-around explicitly if wrap is intended","Catch ArithmeticException at the call site and switch to a wider type for the remainder of the computation"],"exampleFix":"// before\nObject pos = ObjectUtils.plus(cursor, batchSize); // cursor is Byte -> may overflow\n// after\nlong pos = ((Number) cursor).longValue() + batchSize; // widen before adding","handlingStrategy":"type-guard","validationCode":"if (number instanceof Byte || number instanceof Short) {\n  long projected = number.longValue() + (long) augend;\n  long max = number instanceof Byte ? Byte.MAX_VALUE : Short.MAX_VALUE;\n  if (projected > max) throw new IllegalStateException(\"Widen accumulator before incrementing\");\n}","typeGuard":"boolean canPlusWithoutOverflow(Number n, int augend) {\n  long r = n.longValue() + augend;\n  return n instanceof Byte ? (r >= Byte.MIN_VALUE && r <= Byte.MAX_VALUE)\n       : n instanceof Short ? (r >= Short.MIN_VALUE && r <= Short.MAX_VALUE)\n       : n instanceof Integer ? (r >= Integer.MIN_VALUE && r <= Integer.MAX_VALUE)\n       : true;\n}","tryCatchPattern":"try {\n  Object result = ObjectUtils.plus(number, augend);\n} catch (ArithmeticException e) {\n  // widen: long v = ((Number) number).longValue() + augend;\n}","preventionTips":["Use int/long accumulators for counters expected to grow","Never persist incrementing values in TINYINT columns","Range-check before narrowing results back to smaller types"],"tags":["jdbc","arithmetic","overflow"],"backgroundTag":"value-out-of-range","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}