Merge branch 'master' into master
diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml
index e0f4bd3..90dda94 100644
--- a/.github/workflows/build_test.yml
+++ b/.github/workflows/build_test.yml
@@ -218,7 +218,7 @@
steps:
- name: Harden Runner
- uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
with:
egress-policy: audit
@@ -332,7 +332,7 @@
# cd integration
# mvn -B verify
- - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
+ - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
if: ${{ matrix.build_system == 'python' }}
with:
python-version: ${{ matrix.python_version }}
diff --git a/.github/workflows/build_test_wasm.yml b/.github/workflows/build_test_wasm.yml
index da24387..ead2f21 100644
--- a/.github/workflows/build_test_wasm.yml
+++ b/.github/workflows/build_test_wasm.yml
@@ -35,7 +35,7 @@
steps:
- name: Harden Runner
- uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
with:
egress-policy: audit
@@ -53,7 +53,7 @@
run: which node >> $HOME/.base_node_path
- name: Install emsdk
- uses: mymindstorm/setup-emsdk@6ab9eb1bda2574c4ddb79809fc9247783eaf9021 # v14
+ uses: mymindstorm/setup-emsdk@667eb33f24e84e7f362c16d8d7fff0629a73e15e # v15
with:
version: ${{env.EM_VERSION}}
no-cache: true
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 7a4aa40..f80e7d0 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -35,7 +35,7 @@
steps:
- name: Harden Runner
- uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
with:
egress-policy: audit
@@ -44,7 +44,7 @@
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v3.29.5
+ uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
with:
languages: ${{ matrix.language }}
# CodeQL is currently crashing on files with large lists:
@@ -56,7 +56,7 @@
- if: matrix.language == 'cpp'
name: Build CPP
- uses: github/codeql-action/autobuild@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v3.29.5
+ uses: github/codeql-action/autobuild@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
- if: matrix.language == 'cpp' || matrix.language == 'java'
name: Build Java
@@ -66,7 +66,7 @@
- if: matrix.language == 'javascript'
name: Build JS
- uses: github/codeql-action/autobuild@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v3.29.5
+ uses: github/codeql-action/autobuild@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
- if: matrix.language == 'cpp' || matrix.language == 'python'
name: Build Python
@@ -76,7 +76,7 @@
python setup.py build_ext
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v3.29.5
+ uses: github/codeql-action/analyze@c10b8064de6f491fea524254123dbe5e09572f13 # v3.29.5
with:
category: "/language:${{matrix.language}}"
ref: "${{ github.ref != 'master' && github.ref || '/refs/heads/master' }}"
diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml
index c1ee09d..a1734e4 100644
--- a/.github/workflows/fuzz.yml
+++ b/.github/workflows/fuzz.yml
@@ -22,7 +22,7 @@
steps:
- name: Harden Runner
- uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
with:
egress-policy: audit
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 8d60a65..cecf380 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -30,7 +30,7 @@
steps:
- name: Harden Runner
- uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
with:
egress-policy: audit
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index a995b94..ead2bea 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -64,7 +64,7 @@
steps:
- name: Harden Runner
- uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
with:
egress-policy: audit
@@ -145,7 +145,7 @@
steps:
- name: Harden Runner
- uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
with:
egress-policy: audit
@@ -182,7 +182,7 @@
fetch-depth: 1
- name: Download all artifacts
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: release_assets
merge-multiple: true
@@ -203,7 +203,7 @@
steps:
- name: Harden Runner
- uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
with:
egress-policy: audit
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 9e00961..121d36a 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -37,7 +37,7 @@
steps:
- name: Harden Runner
- uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0
+ uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
with:
egress-policy: audit
@@ -77,6 +77,6 @@
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@cf1bb45a277cb3c205638b2cd5c984db1c46a412 # v2.23.3
+ uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v2.23.3
with:
sarif_file: results.sarif
diff --git a/c/common/platform.h b/c/common/platform.h
index e1254d5..8080cbb 100644
--- a/c/common/platform.h
+++ b/c/common/platform.h
@@ -24,6 +24,7 @@
#ifndef BROTLI_COMMON_PLATFORM_H_
#define BROTLI_COMMON_PLATFORM_H_
+#include <limits.h>
#include <string.h> /* IWYU pragma: export memcmp, memcpy, memset */
#include <stdlib.h> /* IWYU pragma: export exit, free, malloc */
#include <sys/types.h> /* should include endian.h for us */
@@ -522,6 +523,14 @@
#define BROTLI_MIN(T, A, B) (brotli_min_ ## T((A), (B)))
#define BROTLI_MAX(T, A, B) (brotli_max_ ## T((A), (B)))
+static BROTLI_INLINE int brotli_safe_add_int(int a, int b, int* result) {
+ if (b > 0 && a > INT_MAX - b) return 0;
+ if (b < 0 && a < INT_MIN - b) return 0;
+ *result = a + b;
+ return 1;
+}
+#define BROTLI_SAFE_ADD(T, A, B, R) (brotli_safe_add_ ## T((A), (B), (R)))
+
#define BROTLI_SWAP(T, A, I, J) { \
T __brotli_swap_tmp = (A)[(I)]; \
(A)[(I)] = (A)[(J)]; \
@@ -607,6 +616,7 @@
BROTLI_UNUSED(&brotli_max_uint32_t);
BROTLI_UNUSED(&brotli_min_uint8_t);
BROTLI_UNUSED(&brotli_max_uint8_t);
+ BROTLI_UNUSED(&brotli_safe_add_int);
BROTLI_UNUSED(&BrotliDefaultAllocFunc);
BROTLI_UNUSED(&BrotliDefaultFreeFunc);
BROTLI_UNUSED(&BrotliRotateRight16);
@@ -615,6 +625,7 @@
#if BROTLI_ENABLE_DUMP
BROTLI_UNUSED(&BrotliDump);
#endif
+}
#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) && \
!defined(_M_ARM64EC)
@@ -654,7 +665,6 @@
#elif defined(BROTLI_TZCNT64)
#define BROTLI_MAX_SIMD_QUALITY 6
#endif
-}
#if defined(_MSC_VER)
#define BROTLI_CRASH() __debugbreak(), (void)abort()
diff --git a/c/dec/decode.c b/c/dec/decode.c
index 90cce9d..5510d10 100644
--- a/c/dec/decode.c
+++ b/c/dec/decode.c
@@ -1526,6 +1526,8 @@
static BROTLI_BOOL AttachCompoundDictionary(
BrotliDecoderState* state, const uint8_t* data, size_t size) {
BrotliDecoderCompoundDictionary* addon = state->compound_dictionary;
+ int new_size = (int)size;
+ if (new_size < 0 || (size_t)new_size != size) return BROTLI_FALSE;
if (state->state != BROTLI_STATE_UNINITED) return BROTLI_FALSE;
if (!addon) {
addon = (BrotliDecoderCompoundDictionary*)BROTLI_DECODER_ALLOC(
@@ -1540,10 +1542,13 @@
state->compound_dictionary = addon;
}
if (addon->num_chunks == 15) return BROTLI_FALSE;
+ if (!BROTLI_SAFE_ADD(int, addon->total_size, new_size, &new_size)) {
+ return BROTLI_FALSE;
+ }
addon->chunks[addon->num_chunks] = data;
addon->num_chunks++;
- addon->total_size += (int)size;
- addon->chunk_offsets[addon->num_chunks] = addon->total_size;
+ addon->total_size = new_size;
+ addon->chunk_offsets[addon->num_chunks] = new_size;
return BROTLI_TRUE;
}
diff --git a/java/org/brotli/dec/Decode.java b/java/org/brotli/dec/Decode.java
index c4dde3f..d2c71b1 100644
--- a/java/org/brotli/dec/Decode.java
+++ b/java/org/brotli/dec/Decode.java
@@ -224,7 +224,7 @@
/**
* Reads brotli stream header and parses "window bits".
*
- * @param s initialized state, before any read is performed.
+ * @param s initialized state, before any read is performed
* @return -1 if header is invalid
*/
private static int decodeWindowBits(State s) {
@@ -272,7 +272,8 @@
*
* In "eager" mode decoder returns as soon as there is enough data to fill output buffer.
*
- * @param s initialized state, before any read is performed.
+ * @param s initialized state, before any read is performed
+ * @return {@link BROTLI_OK} on success; otherwise an error code
*/
static int enableEagerOutput(State s) {
if (s.runningState != INITIALIZED) {
diff --git a/java/org/brotli/dec/Huffman.java b/java/org/brotli/dec/Huffman.java
index 173075d..25fb622 100644
--- a/java/org/brotli/dec/Huffman.java
+++ b/java/org/brotli/dec/Huffman.java
@@ -40,9 +40,10 @@
}
/**
- * @param count histogram of bit lengths for the remaining symbols,
- * @param len code length of the next processed symbol.
- * @return table width of the next 2nd level table.
+ * @param count histogram of bit lengths for the remaining symbols
+ * @param len code length of the next processed symbol
+ * @param rootBits number of bits in the root table
+ * @return table width of the next 2nd level table
*/
private static int nextTableBitSize(int[] count, int len, int rootBits) {
int bits = len;
diff --git a/java/org/brotli/integration/BundleChecker.java b/java/org/brotli/integration/BundleChecker.java
index b03c1ae..3be98ef 100644
--- a/java/org/brotli/integration/BundleChecker.java
+++ b/java/org/brotli/integration/BundleChecker.java
@@ -31,7 +31,7 @@
private final boolean sanityCheck;
/**
- * @param sanityCheck do not calculate checksum and ignore {@link IOException}.
+ * @param sanityCheck do not calculate checksum and ignore {@link IOException}
*/
public BundleChecker(InputStream input, AtomicInteger nextJob, boolean sanityCheck) {
this.input = input;
diff --git a/java/org/brotli/wrapper/enc/BrotliOutputStream.java b/java/org/brotli/wrapper/enc/BrotliOutputStream.java
index 10595d1..fe3596d 100644
--- a/java/org/brotli/wrapper/enc/BrotliOutputStream.java
+++ b/java/org/brotli/wrapper/enc/BrotliOutputStream.java
@@ -18,6 +18,7 @@
/** The default internal buffer size used by the encoder. */
private static final int DEFAULT_BUFFER_SIZE = 16384;
+ private final Object lock = new Object();
private final Encoder encoder;
/**
@@ -42,31 +43,39 @@
}
public void attachDictionary(PreparedDictionary dictionary) throws IOException {
- encoder.attachDictionary(dictionary);
+ synchronized (lock) {
+ encoder.attachDictionary(dictionary);
+ }
}
@Override
public void close() throws IOException {
- encoder.close();
+ synchronized (lock) {
+ encoder.close();
+ }
}
@Override
public void flush() throws IOException {
- if (encoder.closed) {
- throw new IOException("write after close");
+ synchronized (lock) {
+ if (encoder.closed) {
+ throw new IOException("write after close");
+ }
+ encoder.flush();
}
- encoder.flush();
}
@Override
public void write(int b) throws IOException {
- if (encoder.closed) {
- throw new IOException("write after close");
+ synchronized (lock) {
+ if (encoder.closed) {
+ throw new IOException("write after close");
+ }
+ while (!encoder.encode(EncoderJNI.Operation.PROCESS)) {
+ // Busy-wait loop.
+ }
+ encoder.inputBuffer.put((byte) b);
}
- while (!encoder.encode(EncoderJNI.Operation.PROCESS)) {
- // Busy-wait loop.
- }
- encoder.inputBuffer.put((byte) b);
}
@Override
@@ -76,17 +85,19 @@
@Override
public void write(byte[] b, int off, int len) throws IOException {
- if (encoder.closed) {
- throw new IOException("write after close");
- }
- while (len > 0) {
- if (!encoder.encode(EncoderJNI.Operation.PROCESS)) {
- continue;
+ synchronized (lock) {
+ if (encoder.closed) {
+ throw new IOException("write after close");
}
- int limit = Math.min(len, encoder.inputBuffer.remaining());
- encoder.inputBuffer.put(b, off, limit);
- off += limit;
- len -= limit;
+ while (len > 0) {
+ if (!encoder.encode(EncoderJNI.Operation.PROCESS)) {
+ continue;
+ }
+ int limit = Math.min(len, encoder.inputBuffer.remaining());
+ encoder.inputBuffer.put(b, off, limit);
+ off += limit;
+ len -= limit;
+ }
}
}
}
diff --git a/java/org/brotli/wrapper/enc/Encoder.java b/java/org/brotli/wrapper/enc/Encoder.java
index ab0e5aa..eb929bc 100644
--- a/java/org/brotli/wrapper/enc/Encoder.java
+++ b/java/org/brotli/wrapper/enc/Encoder.java
@@ -69,6 +69,7 @@
* Setup encoder quality.
*
* @param quality compression quality, or -1 for default
+ * @return this
*/
public Parameters setQuality(int quality) {
if (quality < -1 || quality > 11) {
@@ -82,6 +83,7 @@
* Setup encoder window size.
*
* @param lgwin log2(LZ window size), or -1 for default
+ * @return this
*/
public Parameters setWindow(int lgwin) {
if ((lgwin != -1) && ((lgwin < 10) || (lgwin > 24))) {