From fff50cb4926218eb8f5c79b0292251d55e4ef649 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Wed, 20 May 2026 13:09:37 +0200 Subject: [PATCH] signed bit to unsigned to avoid overflow after 3B --- .../com/epam/parso/impl/SasFileParser.java | 50 ++++++++++++++----- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/epam/parso/impl/SasFileParser.java b/src/main/java/com/epam/parso/impl/SasFileParser.java index c146317..9ea9dd3 100644 --- a/src/main/java/com/epam/parso/impl/SasFileParser.java +++ b/src/main/java/com/epam/parso/impl/SasFileParser.java @@ -168,7 +168,7 @@ public final class SasFileParser { /** * The index of the current byte when reading the file. */ - private int currentFilePosition; + private long currentFilePosition; /** * The index of the current column when reading the file. */ @@ -176,7 +176,7 @@ public final class SasFileParser { /** * The index of the current row when reading the file. */ - private int currentRowInFileIndex; + private long currentRowInFileIndex; /** * The index of the current row when reading the page. */ @@ -324,10 +324,14 @@ private void processSasFileHeader(String builderEncoding) throws IOException { if (sasFileStream != null) { try { - int bytesLeft = sasFileProperties.getHeaderLength() - currentFilePosition; - long actuallySkipped = 0; + long bytesLeft = (long) sasFileProperties.getHeaderLength() - currentFilePosition; + long actuallySkipped = 0L; while (actuallySkipped < bytesLeft) { - actuallySkipped += sasFileStream.skip(bytesLeft - actuallySkipped); + long skipped = sasFileStream.skip(bytesLeft - actuallySkipped); + if (skipped <= 0) { + break; // avoid infinite loop if skip returns 0 + } + actuallySkipped += skipped; } currentFilePosition = 0; } catch (IOException e) { @@ -507,6 +511,7 @@ Object[] readNext(List columnNames) throws IOException { if (currentRowInFileIndex++ >= sasFileProperties.getRowCount() || eof) { return null; } + currentRowInFileIndex++; int bitOffset = sasFileProperties.isU64() ? PAGE_BIT_OFFSET_X64 : PAGE_BIT_OFFSET_X86; switch (currentPageType) { case PAGE_META_TYPE_1: @@ -759,7 +764,7 @@ private List getBytesFromFile(Long[] offset, Integer[] length) throws IO } catch (EOFException e) { eof = true; } - currentFilePosition = (int) (long) offset[i] + length[i]; + currentFilePosition = offset[i] + length[i]; vars.add(temp); } } else { @@ -782,13 +787,24 @@ private List getBytesFromFile(Long[] offset, Integer[] length) throws IO * for convenience. */ private long correctLongProcess(ByteBuffer byteBuffer) { - if (sasFileProperties.isU64()) { - return byteBuffer.getLong(); - } else { - return byteBuffer.getInt(); + if (sasFileProperties.isU64()) { + return byteBuffer.getLong(); + } else { + return byteBuffer.getInt(); // signed } } + /** + * Reads a 32-bit unsigned integer from the provided {@link ByteBuffer} and returns it as a {@code long}. + *

+ * SAS stores some counters (e.g., rowCount) as 32-bit values that should be interpreted as unsigned. + * + * @param byteBuffer buffer positioned at the start of the 4-byte unsigned int + * @return unsigned 32-bit value widened to long (0..4294967295) + */ + private long readUnsignedInt(ByteBuffer byteBuffer) { + return ((long) byteBuffer.getInt()) & 0xFFFFFFFFL; + } /** * The function to convert an array of bytes with any order of bytes into {@link ByteBuffer}. * {@link ByteBuffer} has the order of bytes defined in the file located at the @@ -1207,13 +1223,21 @@ public void processSubheader(long subheaderOffset, long subheaderLength) throws if (sasFileProperties.getRowLength() == 0) { sasFileProperties.setRowLength(bytesToLong(vars.get(0))); } + // if (sasFileProperties.getRowCount() == 0) { + // sasFileProperties.setRowCount(bytesToLong(vars.get(1))); + // } if (sasFileProperties.getRowCount() == 0) { - sasFileProperties.setRowCount(bytesToLong(vars.get(1))); + ByteBuffer bb = byteArrayToByteBuffer(vars.get(1)); + long rc = sasFileProperties.isU64() ? bb.getLong() : readUnsignedInt(bb); + sasFileProperties.setRowCount(rc); } if (sasFileProperties.getMixPageRowCount() == 0) { - sasFileProperties.setMixPageRowCount(bytesToLong(vars.get(2))); + ByteBuffer bb = byteArrayToByteBuffer(vars.get(2)); + long mrc = sasFileProperties.isU64() + ? bb.getLong() + : readUnsignedInt(bb); + sasFileProperties.setMixPageRowCount(mrc); } - fileLabelOffset = bytesToShort(vars.get(3)); fileLabelLength = bytesToShort(vars.get(4)); }