@@ -49,31 +49,36 @@ namespace kanzi {
4949 char _buffer[BUF_SIZE];
5050
5151 virtual int_type underflow () {
52- if (gptr () < egptr ())
53- return traits_type::to_int_type (*gptr ());
54-
55- const int pbSz = min (int (gptr () - eback ()), BUF_SIZE - 4 );
56- memmove (&_buffer[BUF_SIZE - pbSz], gptr () - pbSz, pbSz);
57- const int r = int (READ (_fd, &_buffer[4 ], BUF_SIZE - 4 ));
58-
59- if (r <= 0 )
60- return EOF;
61-
62- setg (&_buffer[4 - pbSz], &_buffer[4 ], &_buffer[4 + r]);
63- return traits_type::to_int_type (*gptr ());
64- }
65- };
66-
67- class FileInputStream FINAL : public istream
68- {
69- private:
70- ifstreambuf _buf;
71-
72- public:
73- FileInputStream (int fd) : istream(nullptr ), _buf(fd) {
74- rdbuf (&_buf);
75- }
76- };
52+ if (gptr () < egptr ())
53+ return traits_type::to_int_type (*gptr ());
54+
55+ // Preserve up to 4 bytes of putback
56+ const int putback = std::min<int >(gptr () - eback (), 4 );
57+
58+ // Move putback bytes to the front
59+ std::memmove (_buffer + (4 - putback), gptr () - putback, putback);
60+
61+ // Read new bytes after putback
62+ const int n = READ (_fd, _buffer + 4 , BUF_SIZE - 4 );
63+ if (n <= 0 )
64+ return traits_type::eof ();
65+
66+ // Set new buffer pointers
67+ setg (_buffer + (4 - putback), _buffer + 4 , _buffer + 4 + n);
68+ return traits_type::to_int_type (*gptr ());
69+ }
70+ };
71+
72+ class FileInputStream FINAL : public istream
73+ {
74+ private:
75+ ifstreambuf _buf;
76+
77+ public:
78+ FileInputStream (int fd) : istream(nullptr ), _buf(fd) {
79+ rdbuf (&_buf);
80+ }
81+ };
7782}
7883
7984
@@ -103,25 +108,16 @@ int CDECL initDecompressor(struct dData* pData, FILE* src, struct dContext** pCt
103108 if (pData->headerless != 0 ) {
104109 // Headerless mode: process params
105110 string transform = TransformFactory<byte>::getName (TransformFactory<byte>::getType (pData->transform ));
106-
107- if (transform.length () >= 63 ) {
108- delete fis;
109- delete dctx;
110- return Error::ERR_INVALID_PARAM;
111- }
112-
113- strncpy (pData->transform , transform.data (), transform.length ());
114- pData->transform [transform.length () + 1 ] = 0 ;
115111 string entropy = EntropyEncoderFactory::getName (EntropyEncoderFactory::getType (pData->entropy ));
116112
117- if (entropy.length () >= 15 ) {
113+ if ((transform. length () >= 63 ) || ( entropy.length () >= 15 ) ) {
118114 delete fis;
119115 delete dctx;
120116 return Error::ERR_INVALID_PARAM;
121117 }
122118
123- strncpy (pData->entropy , entropy. data (), entropy. length () );
124- pData->entropy [ entropy.length () + 1 ] = 0 ;
119+ strncpy (pData->transform , transform. c_str (), 63 );
120+ strncpy ( pData->entropy , entropy.c_str (), 15 ) ;
125121 pData->blockSize = (pData->blockSize + 15 ) & -16 ;
126122
127123 dctx->pCis = new CompressedInputStream (*fis, pData->jobs ,
@@ -141,7 +137,7 @@ int CDECL initDecompressor(struct dData* pData, FILE* src, struct dContext** pCt
141137 dctx->fis = fis;
142138 *pCtx = dctx;
143139 }
144- catch (exception&) {
140+ catch (const exception&) {
145141 if (fis != nullptr )
146142 delete fis;
147143
@@ -154,30 +150,38 @@ int CDECL initDecompressor(struct dData* pData, FILE* src, struct dContext** pCt
154150 return 0 ;
155151}
156152
157- int CDECL decompress (struct dContext * pCtx, BYTE * dst, int * inSize, int * outSize)
153+ int CDECL decompress (struct dContext * pCtx, unsigned char * dst, int * inSize, int * outSize)
158154{
159- *inSize = 0 ;
160- int res = 0 ;
161-
162- if ((pCtx == nullptr ) || (*outSize > int (pCtx->bufferSize ))) {
155+ if ((pCtx == nullptr ) || (inSize == nullptr ) || (outSize == nullptr ) ||
156+ (*outSize < 0 ) || (*outSize > int (pCtx->bufferSize ))) {
163157 *outSize = 0 ;
164158 return Error::ERR_INVALID_PARAM;
165159 }
166160
167- CompressedInputStream* pCis = (CompressedInputStream*)pCtx->pCis ;
168- *outSize = 0 ;
161+ if (*outSize == 0 )
162+ return 0 ;
163+
164+ *inSize = 0 ;
165+ int res = 0 ;
166+ CompressedInputStream* pCis = static_cast <CompressedInputStream*>(pCtx->pCis );
169167
170- if (pCis == nullptr )
168+ if (pCis == nullptr ) {
169+ *outSize = 0 ;
171170 return Error::ERR_INVALID_PARAM;
171+ }
172172
173173 try {
174- const uint64 r = int ( pCis->getRead () );
174+ const uint64 r = pCis->getRead ();
175175 pCis->read ((char *)dst, streamsize (*outSize));
176- res = pCis->good () ? 0 : Error::ERR_READ_FILE;
176+
177+ if (!pCis->good () && !pCis->eof ())
178+ return Error::ERR_READ_FILE;
179+
177180 *inSize = int (pCis->getRead () - r);
178181 *outSize = int (pCis->gcount ());
179182 }
180- catch (exception&) {
183+ catch (const exception&) {
184+ *outSize = 0 ;
181185 return Error::ERR_UNKNOWN;
182186 }
183187
@@ -190,28 +194,25 @@ int CDECL disposeDecompressor(struct dContext* pCtx)
190194 if (pCtx == nullptr )
191195 return Error::ERR_INVALID_PARAM;
192196
193- CompressedInputStream* pCis = ( CompressedInputStream*) pCtx->pCis ;
197+ CompressedInputStream* pCis = static_cast < CompressedInputStream*>( pCtx->pCis ) ;
194198
195199 try {
196200 if (pCis != nullptr ) {
197201 pCis->close ();
198- }
199- }
200- catch (exception&) {
201- return Error::ERR_UNKNOWN;
202- }
203-
204- try {
205- if (pCis != nullptr )
206202 delete pCis;
203+ pCis = nullptr ;
204+ }
207205
208206 if (pCtx->fis != nullptr )
209207 delete (FileInputStream*)pCtx->fis ;
210208
211209 pCtx->fis = nullptr ;
212210 delete pCtx;
213211 }
214- catch (exception&) {
212+ catch (const exception&) {
213+ if (pCis != nullptr )
214+ delete pCis;
215+
215216 if (pCtx->fis != nullptr )
216217 delete (FileInputStream*)pCtx->fis ;
217218
0 commit comments