Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add checks to ensure that Blob allocation sizes are within a legal max range, failing if they're too big, to address 'uv add' misbehavior reported in forum post d5cd3e3c19. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
6efd41941ced78c5f34ea2c141c400f4 |
User & Date: | stephan 2023-06-22 10:47:34 |
Context
2023-06-22
| ||
11:01 | Allow more than ~128 MiB in a blob ;) ... (check-in: 1c2c0a1f user: danield tags: trunk) | |
10:47 | Add checks to ensure that Blob allocation sizes are within a legal max range, failing if they're too big, to address 'uv add' misbehavior reported in forum post d5cd3e3c19. ... (check-in: 6efd4194 user: stephan tags: trunk) | |
08:46 |
merge build system compilation database generation
Tested on OpenBSD 7.3-current and macOS Ventura 13.4 by me, and also on some Linux machines by stephan@ This automatically generates a compile_commands.json file on machines that support the -MJ clang compiler option, which can be consumed by language server clients. ... (check-in: 91f0f00f user: mark tags: trunk) | |
Changes
Changes to src/blob.c.
︙ | ︙ | |||
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | ** have run out of memory. */ static void blob_panic(void){ static const char zErrMsg[] = "out of memory\n"; fputs(zErrMsg, stderr); fossil_exit(1); } /* ** A reallocation function that assumes that aData came from malloc(). ** This function attempts to resize the buffer of the blob to hold ** newSize bytes. ** ** No attempt is made to recover from an out-of-memory error. ** If an OOM error occurs, an error message is printed on stderr ** and the program exits. */ void blobReallocMalloc(Blob *pBlob, unsigned int newSize){ if( newSize==0 ){ free(pBlob->aData); pBlob->aData = 0; pBlob->nAlloc = 0; pBlob->nUsed = 0; pBlob->iCursor = 0; pBlob->blobFlags = 0; }else if( newSize>pBlob->nAlloc || newSize+4000<pBlob->nAlloc ){ | > > > > > > > > > > > > > > > > > > > | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | ** have run out of memory. */ static void blob_panic(void){ static const char zErrMsg[] = "out of memory\n"; fputs(zErrMsg, stderr); fossil_exit(1); } /* ** Maximum size of a Blob's managed memory. This is ~2GB, largely for ** historical reasons. ** */ #define MAX_BLOB_SIZE 0x7fff000 /* ** If n >= MAX_BLOB_SIZE, calls blob_panic(), ** else this is a no-op. */ static void blob_assert_safe_size(i64 n){ if( n>=(i64)MAX_BLOB_SIZE ){ blob_panic(); } } /* ** A reallocation function that assumes that aData came from malloc(). ** This function attempts to resize the buffer of the blob to hold ** newSize bytes. ** ** No attempt is made to recover from an out-of-memory error. ** If an OOM error occurs, an error message is printed on stderr ** and the program exits. */ void blobReallocMalloc(Blob *pBlob, unsigned int newSize){ if( newSize==0 ){ free(pBlob->aData); pBlob->aData = 0; pBlob->nAlloc = 0; pBlob->nUsed = 0; pBlob->iCursor = 0; pBlob->blobFlags = 0; }else if( newSize>pBlob->nAlloc || newSize+4000<pBlob->nAlloc ){ char *pNew; blob_assert_safe_size((i64)newSize); pNew = fossil_realloc(pBlob->aData, newSize); pBlob->aData = pNew; pBlob->nAlloc = newSize; if( pBlob->nUsed>pBlob->nAlloc ){ pBlob->nUsed = pBlob->nAlloc; } } } |
︙ | ︙ | |||
217 218 219 220 221 222 223 | ** A reallocation function for when the initial string is in unmanaged ** space. Copy the string to memory obtained from malloc(). */ static void blobReallocStatic(Blob *pBlob, unsigned int newSize){ if( newSize==0 ){ *pBlob = empty_blob; }else{ | > > | | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | ** A reallocation function for when the initial string is in unmanaged ** space. Copy the string to memory obtained from malloc(). */ static void blobReallocStatic(Blob *pBlob, unsigned int newSize){ if( newSize==0 ){ *pBlob = empty_blob; }else{ char *pNew; blob_assert_safe_size((i64)newSize); pNew = fossil_malloc( newSize ); if( pBlob->nUsed>newSize ) pBlob->nUsed = newSize; memcpy(pNew, pBlob->aData, pBlob->nUsed); pBlob->aData = pNew; pBlob->xRealloc = blobReallocMalloc; pBlob->nAlloc = newSize; } } |
︙ | ︙ | |||
327 328 329 330 331 332 333 | } } nNew = pBlob->nUsed; nNew += nData; if( nNew >= pBlob->nAlloc ){ nNew += pBlob->nAlloc; nNew += 100; | < | < | | 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | } } nNew = pBlob->nUsed; nNew += nData; if( nNew >= pBlob->nAlloc ){ nNew += pBlob->nAlloc; nNew += 100; blob_assert_safe_size(nNew); pBlob->xRealloc(pBlob, (unsigned)nNew); if( pBlob->nUsed + nData >= pBlob->nAlloc ){ blob_panic(); } } memcpy(&pBlob->aData[pBlob->nUsed], aData, nData); pBlob->nUsed += nData; pBlob->aData[pBlob->nUsed] = 0; /* Blobs are always nul-terminated */ |
︙ | ︙ | |||
603 604 605 606 607 608 609 | /* ** Ensures that the given blob has at least the given amount of memory ** allocated to it. Does not modify pBlob->nUsed nor will it reduce ** the currently-allocated amount of memory. ** ** For semantic compatibility with blob_append_full(), if newSize is | | | | < | | 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 | /* ** Ensures that the given blob has at least the given amount of memory ** allocated to it. Does not modify pBlob->nUsed nor will it reduce ** the currently-allocated amount of memory. ** ** For semantic compatibility with blob_append_full(), if newSize is ** >=MAX_BLOB_SIZE then this function will trigger blob_panic(). If it ** didn't, it would be possible to bypass that hard-coded limit via ** this function. ** ** We've had at least one report: ** https://fossil-scm.org/forum/forumpost/b7bbd28db4 ** which implies that this is unconditionally failing on mingw 32-bit ** builds. */ void blob_reserve(Blob *pBlob, unsigned int newSize){ blob_assert_safe_size( (i64)newSize ); if(newSize>pBlob->nAlloc){ pBlob->xRealloc(pBlob, newSize+1); pBlob->aData[newSize] = 0; } } /* ** Make sure a blob is nul-terminated and is not a pointer to unmanaged |
︙ | ︙ | |||
917 918 919 920 921 922 923 | int w = 0; memset(&dCfg, 0, sizeof(dCfg)); sbs = find_option("side-by-side","y",0)!=0; if( (z = find_option("width","W",1))!=0 && (w = atoi(z))>0 ){ dCfg.wColumn = w; | | | 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 | int w = 0; memset(&dCfg, 0, sizeof(dCfg)); sbs = find_option("side-by-side","y",0)!=0; if( (z = find_option("width","W",1))!=0 && (w = atoi(z))>0 ){ dCfg.wColumn = w; } verify_all_options(); if( g.argc!=3 ) usage("INPUTFILE"); blob_read_from_file(&f, g.argv[2], ExtFILE); blob_strip_comment_lines(&f, &h); if ( !sbs ){ |
︙ | ︙ |