[Git][debian-gis-team/lerc][upstream] New upstream version 4.1.1+ds
Antonio Valentino (@antonio.valentino)
gitlab at salsa.debian.org
Sat Jul 4 21:08:08 BST 2026
Antonio Valentino pushed to branch upstream at Debian GIS Project / lerc
Commits:
4cc04dcd by Antonio Valentino at 2026-07-04T19:53:28+00:00
New upstream version 4.1.1+ds
- - - - -
19 changed files:
- .github/workflows/build_wheels.yml
- CHANGELOG.md
- CMakeLists.txt
- HOWTO-RELEASE.md
- OtherLanguages/Python/lerc/__init__.py
- + OtherLanguages/Python/pyproject.toml
- OtherLanguages/Python/setup.py
- README.md
- src/LercLib/BitMask.cpp
- src/LercLib/BitMask.h
- src/LercLib/Lerc.cpp
- src/LercLib/Lerc.h
- src/LercLib/Lerc1Decode/CntZImage.cpp
- src/LercLib/Lerc1Decode/CntZImage.h
- src/LercLib/Lerc2.cpp
- src/LercLib/Lerc2.h
- src/LercLib/fpl_EsriHuffman.cpp
- src/LercLib/include/Lerc_c_api.h
- src/LercTest/main.cpp
Changes:
=====================================
.github/workflows/build_wheels.yml
=====================================
@@ -7,18 +7,14 @@ on:
- 'OtherLanguages/Python/**'
- 'src/**'
- '.github/workflows/build_wheels.yml'
-
tags:
- 'v*'
-
pull_request:
paths:
- 'OtherLanguages/Python/**'
- '.github/workflows/build_wheels.yml'
-
workflow_dispatch:
-
jobs:
build_wheels:
name: Build on ${{ matrix.os }}
@@ -61,7 +57,7 @@ jobs:
run: |
python -m pip install --upgrade pip setuptools wheel build
cd OtherLanguages/Python
- python -m build
+ python -m build --wheel
- name: Upload Artifacts
uses: actions/upload-artifact at v4
=====================================
CHANGELOG.md
=====================================
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased][unreleased]
+## [4.1.1](https://github.com/Esri/lerc/releases/tag/v4.1.1) - 2026-07-02
+
+### Fixed
+
+* Fixed two security issues and some minor bugs.
+
## [4.1.0](https://github.com/Esri/lerc/releases/tag/v4.1.0) - 2026-03-09
### Fixed
=====================================
CMakeLists.txt
=====================================
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.12)
project(Lerc
DESCRIPTION "Limited Error Raster Compression"
HOMEPAGE_URL "https://github.com/Esri/lerc"
- VERSION 4.1.0) # Keep in sync with Lerc_c_api.h
+ VERSION 4.1.1) # Keep in sync with Lerc_c_api.h
include(GNUInstallDirs)
=====================================
HOWTO-RELEASE.md
=====================================
@@ -4,12 +4,12 @@ Update version numbers in src/LercLib/include/Lerc_c_api.h and CMakeLists.txt
### npm release
-- Config build environment. For 4.0 release: Node.js v16 LTS, npm 8.11
+- Config build environment. For 4.1.2 release: Node.js v24.11.1 LTS, npm 11.6.2
- Update the following files in OtherLanguages/js
- Run npm version xxx to update version numbers in package.json
- Update CHANGELOG.md
- - Update copyright year in Gruntfile.js, README.md and README.hbs
- - If applicable, update usage in README.md and README.hbs
+ - Update copyright year in Gruntfile.js, README.md
+ - If applicable, update usage in README.md
- Build and publish to npm
```
=====================================
OtherLanguages/Python/lerc/__init__.py
=====================================
@@ -1,3 +1,3 @@
-__version__ = "4.1"
+__version__ = "4.1.1"
from ._lerc import *
=====================================
OtherLanguages/Python/pyproject.toml
=====================================
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools", "wheel"]
+build-backend = "setuptools.build_meta"
=====================================
OtherLanguages/Python/setup.py
=====================================
@@ -26,8 +26,7 @@ try:
except Exception:
long_description = "Limited Error Raster Compression"
-# Using MANIFEST.in doesn't respect relative paths above the package root.
-# Instead, inspect the location and copy in the binaries if newer.
+# Stage binaries from repo root into package root
BINARY_TYPES = ["*.dll", "*.lib", "*.so*", "*.dylib"]
PLATFORMS = ["Linux", "MacOS", "windows"]
for platform in PLATFORMS:
@@ -41,7 +40,7 @@ for platform in PLATFORMS:
setuptools.setup(
name="pylerc",
- version="4.1",
+ version="4.1.1",
author="esri",
author_email="python at esri.com",
description="Limited Error Raster Compression",
@@ -56,6 +55,7 @@ setuptools.setup(
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"License :: OSI Approved :: Apache Software License",
],
package_data={"lerc": BINARY_TYPES},
=====================================
README.md
=====================================
@@ -123,7 +123,7 @@ The codecs Lerc2 and Lerc1 have been in use for years, bugs in those low level m
## Licensing
-Copyright 2015-2022 Esri
+Copyright 2015-2026 Esri
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
=====================================
src/LercLib/BitMask.cpp
=====================================
@@ -102,7 +102,7 @@ int BitMask::CountValidBits() const
const Byte numBitsHB[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
const Byte* ptr = m_pBits;
int sum = 0;
- int i = Size();
+ size_t i = Size();
while (i--)
{
sum += numBitsHB[*ptr & 15] + numBitsHB[*ptr >> 4];
=====================================
src/LercLib/BitMask.h
=====================================
@@ -25,6 +25,7 @@ Contributors: Thomas Maurer
#define BITMASK_H
#include "Defines.h"
+#include <cstddef>
NAMESPACE_LERC_START
@@ -59,7 +60,7 @@ public:
int GetWidth() const { return m_nCols; }
int GetHeight() const { return m_nRows; }
- int Size() const { return (m_nCols * m_nRows + 7) >> 3; }
+ size_t Size() const { return ((size_t)m_nCols * m_nRows + 7) >> 3; }
const Byte* Bits() const { return m_pBits; }
Byte* Bits() { return m_pBits; }
static Byte Bit(int k) { return (1 << 7) >> (k & 7); }
=====================================
src/LercLib/Lerc.cpp
=====================================
@@ -188,7 +188,7 @@ ErrCode Lerc::GetLercInfo(const Byte* pLercBlob, unsigned int numBytesBlob, stru
lercInfo.zMax = -FLT_MAX;
CntZImage cntZImg;
- if (numBytesHeaderBand0 <= numBytesBlob && cntZImg.read(&pByte, 1e12, true)) // read just the header
+ if (numBytesHeaderBand0 <= numBytesBlob && cntZImg.read(&pByte, pLercBlob + numBytesBlob, 1e12, true)) // read just the header
{
size_t nBytesRead = pByte - pLercBlob;
size_t nBytesNeeded = 10 + 4 * sizeof(int) + 1 * sizeof(double);
@@ -205,7 +205,7 @@ ErrCode Lerc::GetLercInfo(const Byte* pLercBlob, unsigned int numBytesBlob, stru
double maxZErrorInFile(0);
memcpy(&maxZErrorInFile, ptr, sizeof(double));
- if (height > 20000 || width > 20000) // guard against bogus numbers; size limitation for old Lerc1
+ if (height < 0 || width < 0 || height > 40000 || width > 40000) // guard against bogus numbers; size limitation for old Lerc1
return ErrCode::Failed;
lercInfo.nDepth = 1;
@@ -219,7 +219,7 @@ ErrCode Lerc::GetLercInfo(const Byte* pLercBlob, unsigned int numBytesBlob, stru
while (lercInfo.blobSize + numBytesHeaderBand1 < numBytesBlob) // means there could be another band
{
- if (!cntZImg.read(&pByte, 1e12, false, onlyZPart))
+ if (!cntZImg.read(&pByte, pLercBlob + numBytesBlob, 1e12, false, onlyZPart))
return (lercInfo.nBands > 0) ? ErrCode::Ok : ErrCode::Failed; // no other band, we are done
onlyZPart = true;
@@ -479,11 +479,11 @@ ErrCode Lerc::DecodeTempl(T* pData, const Byte* pLercBlob, unsigned int numBytes
for (int iBand = 0; iBand < nBands; iBand++)
{
unsigned int numBytesHeader = iBand == 0 ? numBytesHeaderBand0 : numBytesHeaderBand1;
- if ((size_t)(pByte - pLercBlob) + numBytesHeader > numBytesBlob)
+ if ((size_t)(pByte1 - pLercBlob) + numBytesHeader > numBytesBlob)
return ErrCode::BufferTooSmall;
bool onlyZPart = iBand > 0;
- if (!zImg.read(&pByte1, 1e12, false, onlyZPart))
+ if (!zImg.read(&pByte1, pLercBlob + numBytesBlob, 1e12, false, onlyZPart))
return ErrCode::Failed;
if (zImg.getWidth() != nCols || zImg.getHeight() != nRows)
@@ -675,14 +675,18 @@ ErrCode Lerc::EncodeInternal(const T* pData, int version, int nDepth, int nCols,
bool bNeedNoData = false; // can only turn true for nDepth > 1, and mix of valid and invalid values at the same pixel (special case)
errCode = ErrCode::Ok;
+ double minVal(+1), maxVal(-1);
+ lerc2.ClearMinMax();
+
if (bIsFltOrDbl) // if flt type, filter out NaN and / or noData values and update the mask if possible
{
errCode = FilterNoDataAndNaN(dataBuffer, maskBuffer, nDepth, nCols, nRows, maxZErrL, bPassNoDataValue, noDataL,
- bModifiedMask, bNeedNoData, bIsFltDblAllInt);
+ bModifiedMask, bNeedNoData, bIsFltDblAllInt, minVal, maxVal);
}
else if (bPassNoDataValue) // if int type (no NaN), and no noData value specified, nothing to do
{
- errCode = FilterNoData(dataBuffer, maskBuffer, nDepth, nCols, nRows, maxZErrL, bPassNoDataValue, noDataL, bModifiedMask, bNeedNoData);
+ errCode = FilterNoData(dataBuffer, maskBuffer, nDepth, nCols, nRows, maxZErrL, bPassNoDataValue, noDataL,
+ bModifiedMask, bNeedNoData, minVal, maxVal);
}
if (errCode != ErrCode::Ok)
@@ -723,6 +727,10 @@ ErrCode Lerc::EncodeInternal(const T* pData, int version, int nDepth, int nCols,
|| !lerc2.SetIsAllInt(bIsFltDblAllInt))
return ErrCode::Failed;
+ if (nDepth == 1 && (maxVal >= minVal)
+ && !lerc2.SetMinMax(nDepth, minVal, maxVal))
+ return ErrCode::Failed;
+
unsigned int nBytes = lerc2.ComputeNumBytesNeededToWrite(arrL, maxZErrL, bEncMsk);
if (nBytes <= 0)
return ErrCode::Failed;
@@ -1210,7 +1218,8 @@ bool Lerc::GetTypeRange(const T, std::pair<double, double>& range)
template<class T>
ErrCode Lerc::FilterNoData(std::vector<T>& dataBuffer, std::vector<Byte>& maskBuffer, int nDepth, int nCols, int nRows,
- double& maxZError, bool bPassNoDataValue, double& noDataValue, bool& bModifiedMask, bool& bNeedNoData)
+ double& maxZError, bool bPassNoDataValue, double& noDataValue, bool& bModifiedMask, bool& bNeedNoData,
+ double& minValA, double& maxValA)
{
if (nDepth <= 0 || nCols <= 0 || nRows <= 0 || maxZError < 0)
return ErrCode::WrongParam;
@@ -1252,10 +1261,13 @@ ErrCode Lerc::FilterNoData(std::vector<T>& dataBuffer, std::vector<Byte>& maskBu
if (z == origNoData)
cntInvalid++;
- else if (z < minVal)
- minVal = z;
- else if (z > maxVal)
- maxVal = z;
+ else
+ {
+ if (z < minVal)
+ minVal = z;
+ if (z > maxVal)
+ maxVal = z;
+ }
}
if (cntInvalid == nDepth)
@@ -1271,6 +1283,16 @@ ErrCode Lerc::FilterNoData(std::vector<T>& dataBuffer, std::vector<Byte>& maskBu
double maxZErrL = (std::max)(0.5, floor(maxZError)); // same mapping for int types as in Lerc2.cpp
double dist = floor(maxZErrL);
+ if (minVal == DBL_MAX && maxVal == -DBL_MAX) // if the tile has no valid data
+ {
+ minValA = maxValA = 0;
+ maxZError = 0.5;
+ return ErrCode::Ok;
+ }
+
+ minValA = minVal;
+ maxValA = maxVal;
+
// check the orig noData value is far enough away from the valid range
if ((origNoData >= minVal - dist) && (origNoData <= maxVal + dist))
{
@@ -1333,7 +1355,8 @@ ErrCode Lerc::FilterNoData(std::vector<T>& dataBuffer, std::vector<Byte>& maskBu
template<class T>
ErrCode Lerc::FilterNoDataAndNaN(std::vector<T>& dataBuffer, std::vector<Byte>& maskBuffer, int nDepth, int nCols, int nRows,
- double& maxZError, bool bPassNoDataValue, double& noDataValue, bool& bModifiedMask, bool& bNeedNoData, bool& bIsFltDblAllInt)
+ double& maxZError, bool bPassNoDataValue, double& noDataValue, bool& bModifiedMask, bool& bNeedNoData, bool& bIsFltDblAllInt,
+ double& minValA, double& maxValA)
{
if (nDepth <= 0 || nCols <= 0 || nRows <= 0 || maxZError < 0)
return ErrCode::WrongParam;
@@ -1371,7 +1394,6 @@ ErrCode Lerc::FilterNoDataAndNaN(std::vector<T>& dataBuffer, std::vector<Byte>&
double minVal = DBL_MAX;
double maxVal = -DBL_MAX;
- int cntValidPixels = 0;
// check for NaN or noData in valid pixels
for (int k = 0, i = 0; i < nRows; i++)
@@ -1381,7 +1403,6 @@ ErrCode Lerc::FilterNoDataAndNaN(std::vector<T>& dataBuffer, std::vector<Byte>&
for (int n = 0, j = 0; j < nCols; j++, k++, n += nDepth)
if (maskBuffer[k])
{
- cntValidPixels++;
int cntInvalidValues = 0;
for (int m = 0; m < nDepth; m++)
@@ -1406,7 +1427,7 @@ ErrCode Lerc::FilterNoDataAndNaN(std::vector<T>& dataBuffer, std::vector<Byte>&
{
if (zVal < minVal)
minVal = zVal;
- else if (zVal > maxVal)
+ if (zVal > maxVal)
maxVal = zVal;
if (bAllInt && !IsInt(zVal))
@@ -1424,10 +1445,16 @@ ErrCode Lerc::FilterNoDataAndNaN(std::vector<T>& dataBuffer, std::vector<Byte>&
}
}
- bNeedNoData = bHasNoDataValuesLeft;
+ if (minVal == DBL_MAX && maxVal == -DBL_MAX) // if the tile has no valid data
+ {
+ minValA = maxValA = 0;
+ maxZError = 0;
+ return ErrCode::Ok;
+ }
- if (cntValidPixels == 0)
- bAllInt = false;
+ minValA = minVal;
+ maxValA = maxVal;
+ bNeedNoData = bHasNoDataValuesLeft;
if (bHasNaN && nDepth > 1 && bHasNoDataValuesLeft && !bPassNoDataValue)
{
=====================================
src/LercLib/Lerc.h
=====================================
@@ -272,11 +272,13 @@ NAMESPACE_LERC_START
template<class T>
static ErrCode FilterNoData(std::vector<T>& dataBuffer, std::vector<Byte>& maskBuffer, int nDepth, int nCols, int nRows,
- double& maxZError, bool bPassNoDataValue, double& noDataValue, bool& bModifiedMask, bool& bNeedNoData);
+ double& maxZError, bool bPassNoDataValue, double& noDataValue, bool& bModifiedMask, bool& bNeedNoData,
+ double& minVal, double& maxVal);
template<class T>
static ErrCode FilterNoDataAndNaN(std::vector<T>& dataBuffer, std::vector<Byte>& maskBuffer, int nDepth, int nCols, int nRows,
- double& maxZError, bool bPassNoDataValue, double& noDataValue, bool& bModifiedMask, bool& bNeedNoData, bool& bIsFltDblAllInt);
+ double& maxZError, bool bPassNoDataValue, double& noDataValue, bool& bModifiedMask, bool& bNeedNoData, bool& bIsFltDblAllInt,
+ double& minVal, double& maxVal);
template<class T>
static bool FindNewNoDataBelowValidMin(double minVal, double maxZErr, bool bAllInt, double lowIntLimit, T& newNoDataVal);
=====================================
src/LercLib/Lerc1Decode/CntZImage.cpp
=====================================
@@ -69,12 +69,16 @@ unsigned int CntZImage::computeNumBytesNeededToReadHeader(bool onlyZPart)
// -------------------------------------------------------------------------- ;
-bool CntZImage::read(const Byte** ppByte, double maxZError, bool onlyHeader, bool onlyZPart)
+bool CntZImage::read(const Byte** ppByte, const Byte* bArr_end, double maxZError, bool onlyHeader, bool onlyZPart)
{
if (!ppByte || !*ppByte)
return false;
size_t len = getTypeString().length();
+
+ if (*ppByte + len > bArr_end)
+ return false;
+
string typeStr(len, '0');
memcpy(&typeStr[0], *ppByte, len);
*ppByte += len;
@@ -87,6 +91,9 @@ bool CntZImage::read(const Byte** ppByte, double maxZError, bool onlyHeader, boo
const Byte* ptr = *ppByte;
+ if (ptr + 4 * sizeof(int) + sizeof(double) > bArr_end)
+ return false;
+
memcpy(&version, ptr, sizeof(int)); ptr += sizeof(int);
memcpy(&type, ptr, sizeof(int)); ptr += sizeof(int);
memcpy(&height, ptr, sizeof(int)); ptr += sizeof(int);
@@ -104,7 +111,7 @@ bool CntZImage::read(const Byte** ppByte, double maxZError, bool onlyHeader, boo
if (version != 11 || type != type_)
return false;
- if (width > 20000 || height > 20000)
+ if (height < 0 || width < 0 || height > 40000 || width > 40000) // guard against bogus numbers; size limitation for old Lerc1
return false;
if (maxZErrorInFile > maxZError)
@@ -130,6 +137,9 @@ bool CntZImage::read(const Byte** ppByte, double maxZError, bool onlyHeader, boo
const Byte* ptr = *ppByte;
+ if (ptr + 3 * sizeof(int) + sizeof(float) > bArr_end)
+ return false;
+
memcpy(&numTilesVert, ptr, sizeof(int)); ptr += sizeof(int);
memcpy(&numTilesHori, ptr, sizeof(int)); ptr += sizeof(int);
memcpy(&numBytes, ptr, sizeof(int)); ptr += sizeof(int);
@@ -143,6 +153,9 @@ bool CntZImage::read(const Byte** ppByte, double maxZError, bool onlyHeader, boo
SWAP_4(numBytes);
SWAP_4(maxValInImg);
+ if (numBytes < 0 || ptr + numBytes > bArr_end)
+ return false;
+
if (!zPart && numTilesVert == 0 && numTilesHori == 0) // no tiling for this cnt part
{
if (numBytes == 0) // cnt part is const
@@ -188,7 +201,8 @@ bool CntZImage::read(const Byte** ppByte, double maxZError, bool onlyHeader, boo
bool CntZImage::readTiles(bool zPart, double maxZErrorInFile, int numTilesVert, int numTilesHori,
float maxValInImg, const Byte* bArr)
{
- if (numTilesVert <= 0 || numTilesHori <= 0)
+ if (numTilesVert <= 0 || numTilesHori <= 0
+ || numTilesVert > height_ || numTilesHori > width_)
return false;
const Byte* ptr = bArr;
=====================================
src/LercLib/Lerc1Decode/CntZImage.h
=====================================
@@ -47,7 +47,7 @@ public:
static unsigned int computeNumBytesNeededToReadHeader(bool onlyZPart);
/// read succeeds only if maxZError on file <= maxZError requested
- bool read(const Byte** ppByte, double maxZError, bool onlyHeader = false, bool onlyZPart = false);
+ bool read(const Byte** ppByte, const Byte* bArr_end, double maxZError, bool onlyHeader = false, bool onlyZPart = false);
protected:
=====================================
src/LercLib/Lerc2.cpp
=====================================
@@ -70,6 +70,7 @@ void Lerc2::Init()
m_maxValToQuantize = 0;
m_encodeMask = true;
m_writeDataOneSweep = false;
+ m_minMaxSet = false;
m_imageEncodeMode = IEM_Tiling;
m_headerInfo.RawInit();
@@ -145,6 +146,31 @@ bool Lerc2::SetIsAllInt(bool bIsAllInt)
// -------------------------------------------------------------------------- ;
+bool Lerc2::SetMinMax(int nDepth, double minVal, double maxVal)
+{
+ ClearMinMax();
+
+ if (nDepth != 1 || minVal > maxVal)
+ return false;
+
+ m_zMinVec.assign(1, minVal);
+ m_zMaxVec.assign(1, maxVal);
+ m_minMaxSet = true;
+
+ return true;
+}
+
+// -------------------------------------------------------------------------- ;
+
+void Lerc2::ClearMinMax()
+{
+ m_zMinVec.clear();
+ m_zMaxVec.clear();
+ m_minMaxSet = false;
+}
+
+// -------------------------------------------------------------------------- ;
+
template<class T>
unsigned int Lerc2::ComputeNumBytesNeededToWrite(const T* arr, double maxZError, bool encodeMask)
{
@@ -214,7 +240,8 @@ unsigned int Lerc2::ComputeNumBytesNeededToWrite(const T* arr, double maxZError,
Byte* ptr = nullptr; // only emulate the writing and just count the bytes needed
int nBytesTiling = 0;
- if (!ComputeMinMaxRanges(arr, m_zMinVec, m_zMaxVec)) // need this for diff encoding before WriteTiles()
+ if ((!m_minMaxSet || m_headerInfo.nDepth > 1)
+ && !ComputeMinMaxRanges(arr, m_zMinVec, m_zMaxVec)) // need this for diff encoding before WriteTiles()
return 0;
m_headerInfo.zMin = *std::min_element(m_zMinVec.begin(), m_zMinVec.end());
@@ -823,8 +850,11 @@ bool Lerc2::ReadHeader(const Byte** ppByte, size_t& nBytesRemainingInOut, struct
hd.microBlockSize = intVec[i++];
hd.blobSize = intVec[i++];
const int dt = intVec[i++];
- if (dt < DT_Char || dt > DT_Double)
+
+ if (hd.nRows <= 0 || hd.nCols <= 0 || hd.nDepth <= 0 || hd.numValidPixel < 0
+ || hd.microBlockSize <= 0 || hd.blobSize <= 0 || dt < DT_Char || dt > DT_Double)
return false;
+
hd.dt = static_cast<DataType>(dt);
hd.nBlobsMore = (hd.version >= 6) ? intVec[i++] : 0;
@@ -841,8 +871,9 @@ bool Lerc2::ReadHeader(const Byte** ppByte, size_t& nBytesRemainingInOut, struct
hd.noDataVal = (hd.version >= 6) ? dblVec[i++] : 0;
hd.noDataValOrig = (hd.version >= 6) ? dblVec[i++] : 0;
- if (hd.nRows <= 0 || hd.nCols <= 0 || hd.nDepth <= 0 || hd.numValidPixel < 0 || hd.microBlockSize <= 0 || hd.blobSize <= 0
- || (hd.nRows > INT_MAX / hd.nCols) || hd.numValidPixel > hd.nRows * hd.nCols)
+ size_t numPixel = (size_t)hd.nRows * hd.nCols;
+
+ if (numPixel > (size_t)INT_MAX || (size_t)hd.numValidPixel > numPixel)
return false;
*ppByte = ptr;
=====================================
src/LercLib/Lerc2.h
=====================================
@@ -86,6 +86,9 @@ public:
bool SetNumBlobsMoreToCome(int nBlobsMore); // for safer decode of multi-band blobs
bool SetIsAllInt(bool bIsAllInt);
+ bool SetMinMax(int nDepth, double minVal, double maxVal); // set min / max but only for nDepth = 1
+ void ClearMinMax();
+
template<class T>
unsigned int ComputeNumBytesNeededToWrite(const T* arr, double maxZError, bool encodeMask);
@@ -146,7 +149,8 @@ private:
HeaderInfo m_headerInfo;
BitStuffer2 m_bitStuffer2;
bool m_encodeMask,
- m_writeDataOneSweep;
+ m_writeDataOneSweep,
+ m_minMaxSet;
ImageEncodeMode m_imageEncodeMode;
std::vector<double> m_zMinVec, m_zMaxVec;
=====================================
src/LercLib/fpl_EsriHuffman.cpp
=====================================
@@ -53,23 +53,28 @@ bool decodePackBits (const unsigned char *ptr, const size_t size, size_t expecte
for (size_t i = 0; i < size; )
{
- // read header byte.
-
- int b = ptr[i];
-
- if (b <= 127)
- {
- while (b >= 0) { i++; out[curr++] = ptr[i]; b--; }
- i++;
- continue;
- }
- else
- {
- i++;
- while (b >= 127) { out[curr++] = ptr[i]; b--; }
- i++;
- continue;
- }
+ int b = ptr[i++]; // read header byte
+
+ if (b <= 127)
+ {
+ if (curr + b >= expected)
+ return false;
+
+ int b1 = b + 1;
+ memcpy(&out[curr], &ptr[i], b1);
+ curr += b1;
+ i += b1;
+ }
+ else
+ {
+ if (curr + b - 127 >= expected)
+ return false;
+
+ int b1 = b - 127 + 1;
+ memset(&out[curr], ptr[i], b1);
+ curr += b1;
+ i++;
+ }
}
return (curr == expected);
@@ -353,6 +358,11 @@ int fpl_EsriHuffman::EncodeHuffman (const char *input, size_t input_len, unsigne
long rle_len = getPackBitsSize ((unsigned char *)input, input_len, &limit);
if (rle_len > 0 && (rle_len < numBytes) && (rle_len < (long)input_len))
{
+ if ((rle_len + 1) <= 0) // rle_len is maximum long value, so adding 1 results in overflow.
+ {
+ return HUFF_UNEXPECTED; // this should not normally happen.
+ }
+
*ppByte = (unsigned char *)malloc (rle_len + 1);
if (*ppByte == NULL)
=====================================
src/LercLib/include/Lerc_c_api.h
=====================================
@@ -38,7 +38,7 @@ extern "C" {
#define LERC_VERSION_MAJOR 4
#define LERC_VERSION_MINOR 1
-#define LERC_VERSION_PATCH 0
+#define LERC_VERSION_PATCH 1
/* Macro to compute a LERC version number from its components */
#define LERC_COMPUTE_VERSION(maj,min,patch) ((maj)*10000+(min)*100+(patch))
=====================================
src/LercTest/main.cpp
=====================================
@@ -799,17 +799,23 @@ bool ReadFile(const string& fn, Byte* pBuffer, size_t bufferSize, size_t& nBytes
}
fseek(fp, 0, SEEK_END);
- size_t fileSize = ftell(fp); // get the file size
- fclose(fp);
- fp = 0;
+ int rv = ftell(fp); // get the file size
+ if (rv <= 0)
+ {
+ fclose(fp);
+ return false;
+ }
+
+ size_t fileSize = (size_t)rv;
if (fileSize > bufferSize)
{
printf("Lerc blob size %d > buffer size of %d\n", (uint32)fileSize, (uint32)bufferSize);
+ fclose(fp);
return false;
}
- fp = fopen(fn.c_str(), "rb");
+ rewind(fp);
nBytesRead = fread(pBuffer, 1, fileSize, fp); // read Lerc blob into buffer
fclose(fp);
return nBytesRead == fileSize;
View it on GitLab: https://salsa.debian.org/debian-gis-team/lerc/-/commit/4cc04dcdec0f155c7c4b741d06da935a29682feb
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/lerc/-/commit/4cc04dcdec0f155c7c4b741d06da935a29682feb
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20260704/c4f82a58/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list