chore(deps-dev): bump lodash from 4.17.23 to 4.18.1#6
Open
dependabot[bot] wants to merge 42 commits into
Open
Conversation
- Wrap std::stod/stoll/stoull in safe full-consume parsers: no STL exception
leaks, range-checked, and trailing garbage ('12abc', '1.2.3.4', negative
uint) is now rejected instead of silently accepted.
- Bound string decode with strnlen(str, data_size) (defense-in-depth vs a
non-null-terminated static buffer).
- Guard nested-message init_default against null before calling.
- Guard pb_bytes_array_t offsetof underflow before computing max_size.
- Include actual vs allowed sizes in length/size error messages.
- Reject non-number bytes-array elements directly (no string coercion).
- Hoist pb_field_iter_begin out of the per-entry loop in populateMessage.
- Hard error during generation (non --skipProtoc) when any codec-supported static field (string/bytes/repeated) lacks its required nanopb option (max_length/max_size/max_count). Without it nanopb emits a callback field the codec rejects at runtime; failing early with the exact field list removes the most common foot-gun. oneof/map fields are skipped. - Fix cppString backslash escaping (was only handling double-backslash). - Fix leading-dot strip regex for resolved type names.
Compiles the real codec + nanopb + nitro AnyMap/jsi under -fsanitize=address,undefined and runs ~40k checks: every field type, exact-capacity and over-limit boundaries, type mismatches, and decode fuzzing (20k random buffers, all truncations, all single-bit flips, single-byte buffers, oversize length-delimited fields). Wired into node --test; skips when protoc/nanopb/compiler are absent.
- README: document the JS-thread-only constraint for encode/decode (calling from a worklet/other runtime is unsupported), a JS<->proto value-mapping table (bytes = base64 string or number[], NOT Uint8Array; 64-bit = string), and the new hard .options requirement. - example Podfile: post_install workaround for fmt 11.0.x consteval failing under Xcode 26 clang (force FMT_USE_CONSTEVAL=0 and patch fmt/base.h's unconditional define behind an #ifndef guard; idempotent). - run-example.mjs: fall back to global 'pod install' when 'bundle exec' fails (vendored bundler is incompatible with Ruby 4).
ANALYSIS.md: subsystem-by-subsystem audit vs protobuf.js, hotspot list, host ASan/UBSan fuzz results (0 crashes), iOS-sim agent-device verification (exceptions propagate gracefully, no crashes), and a note that the upstream react-native-nitro-modules AnyMap setters use emplace (no-overwrite) and should be insert_or_assign.
- react-native-nitro-modules & nitrogen 0.33.2 -> 0.35.7 (root + example).
- Regenerate nitrogen specs: C++ HybridProtobufSpec unchanged (C++ ABI stable);
Android OnLoad + iOS autolinking regenerated.
- Migrate android cpp-adapter JNI_OnLoad to the 0.35 breaking-change pattern
facebook::jni::initialize(vm, []{ registerAllNatives(); }); the old
initialize(vm) is now a [[deprecated]] shim.
- Modernize nitro.json autolinking to { all: { language, implementationClassName } },
dropping the deprecated cpp/swift/kotlin syntax warning.
iOS example rebuilt on NitroModules 0.35.7 (BUILD SUCCEEDED); round-trip
verified on iPhone 17 Pro sim via agent-device.
…/ protobufjs 8 - react-native 0.83.1 -> 0.85.3, react 19.2.0 -> 19.2.6, react-native-safe-area-context -> 5.8.0, protobufjs 7 -> 8.4.0, @react-native-community/cli 20.0.0 -> 20.1.0, @react-native/* -> 0.85.3. - App.tsx: StyleSheet.absoluteFillObject -> absoluteFill (removed in 0.85). - jest: preset 'react-native' -> '@react-native/jest-preset' (+ devDep). - Gemfile: add nkf; gradle wrapper 9.0.0 -> 9.3.1. - Pods reintegrated for precompiled RNCore (.xcframework) + Hermes V1 (RCT_REMOVE_LEGACY_ARCH=1); fmt bumped to 12.1.0 upstream. protobufjs-8 generation verified; iOS example built (BUILD SUCCEEDED) and round-trip verified on iPhone 17 Pro (70 bytes, encode 0.11ms/decode 0.05ms).
The codec included ArrayBuffer.hpp / AnyMap.hpp by bare name, which only resolves on iOS (pod header search paths). Android's prefab exposes them under include/NitroModules/, so the bare include failed at compile time with "'ArrayBuffer.hpp' file not found", breaking the Android CMake build. The <NitroModules/...> form resolves on both platforms. Android example now builds (libNitroProtobuf.so for all ABIs); iOS rebuilt clean.
…artup
NitroProtobufModule only loaded libNitroProtobuf.so from its lazy static
initializer (touched when the TurboModule is first requested). But
`NitroModules.createHybridObject('Protobuf')` runs at JS import time, before
that — so JNI_OnLoad/registerAllNatives had not run and the 'Protobuf'
HybridObject was unregistered, throwing at launch on Android.
Load the native library from the autolinked NitroProtobufPackage's init block
(constructed during MainApplication.onCreate, before JS runs), registering the
HybridObject in time. Verified: Android round-trip now matches iOS byte-for-byte
(70 bytes, identical base64) on an android-35 arm64 emulator via agent-device.
The codec now includes <NitroModules/...> (for the Android prefab build); a raw host compile needs a shim dir mapping NitroModules/ to the package's flat cpp/core layout, otherwise the fuzz harness no longer compiles. Verified: native-fuzz passes again (full ASan/UBSan run).
… report
- bench/payloads.mjs: 8 shared payload profiles (tiny..large).
- bench/native-bench.cpp + run-native.mjs: clang -O2 microbench of the raw
codec (no JSI) — ns/op, p50/p95/p99, ops/sec, allocs/op.
- bench/js-bench.mjs: protobuf.js 8 vs JSON on node.
- example/src/bench.ts + App.tsx "Run benchmark": on-device (Hermes) bench of
NitroProtobuf vs protobuf.js vs JSON; full ops/sec table rendered on screen.
- bench/results-*.{json,txt}: captured runs (M1 Pro / iPhone 17 Pro sim /
android-35 emulator).
- PERFORMANCE.md: methodology, environment, tables, analysis, caveats.
Findings: vs protobuf.js on Hermes, NitroProtobuf encodes ~2-7x faster and
decodes ~2x faster (medium/large); Hermes native JSON is faster raw but protobuf
is ~3x smaller on the wire; the JSI boundary costs ~3-5us/call. Adds protobufjs
to the example app deps.
- Hoist the nanopb field iterator out of the per-field decode loops (decodeMessageInternal + nested decodeSingleValue); it was re-running pb_field_iter_begin_const for every field. - Build the decoded result by moving arrays/objects/nested maps in via AnyMap::getMap() instead of copying through setAny. - Reserve nested AnyMaps; O(1) descriptor-keyed field-name lookup (was linear, O(fields x entries)); drop a redundant memset after a zero-initialized vector. Native (M1 Pro, -O2): decode 34-43% faster, encode 21-42% faster, ~30% fewer allocations (default 32->22, large 40->25). On-device (Release/Hermes): default decode +41% iOS / +27% Android, encode +28% iOS. No API/behavior change; encoded sizes identical. All tests green incl. ASan/UBSan fuzz + native round-trip. Also fix native-roundtrip.test.mjs to compile the codec with the <NitroModules/...> include shim (matching native-fuzz). PERFORMANCE.md documents the before/after and a rejected AnyMap-bypass (JSON-string boundary) experiment that showed no consistent win.
… Expo plugin Make setup and .proto management easy: - Toolchain: bundle protoc via grpc-tools and auto-install the matching nanopb generator (0.4.9.1) into a cache on first run -- no manual protoc/nanopb install. - Field sizes: apply default max_length/max_size/max_count (256/256/16) via a synthesized wildcard .options so protos compile with no hand-written options; user .options / config override per field; --strict restores the explicit requirement. - Types: emit generated/nitro-protobuf.ts with per-message interfaces (codec JS shapes) + a typed encode/decode facade. - `init` command scaffolds proto/, nitro-protobuf.config.json, and a proto:generate script. - Add the previously-missing Expo config plugin (app.plugin.js) to regenerate on expo prebuild. - README quickstart rewrite (zero-install, optional .options).
The example now relies on the generator's default field sizes (256/256/16) instead of a hand-written .options, showing the zero-setup path; per-field overrides remain available via .options or nitro-protobuf.config.json. Verified: example regenerates with defaults and the iOS app builds clean.
Modeled on top React Native library docs: hero + badges, features, requirements, installation, quickstart, configuration + CLI reference, typed usage + value mapping, performance summary, threading, limitations, how-it-works, troubleshooting, and development. Reflects the current behavior (zero-install codegen, automatic field-size defaults, generated TS types, Expo plugin); drops the stale manual protoc/nanopb + mandatory .options instructions.
- Scope the package to @klaappinc/react-native-nitro-protobuf (publishConfig access: public) and update all self-references: the generator-emitted import, the Expo plugin, the example imports/dependency, and the README. The CocoaPods name (NitroProtobuf) is hardcoded in the podspec, so autolinking is unaffected. - Add `build` + `prepublishOnly` (tsc) so every publish ships a fresh lib/. - .github/workflows/test.yml: reusable CI (npm ci, typecheck, build, then install protoc + nanopb 0.4.9.1 + clang and run `npm test`, including the native ASan/UBSan fuzz + round-trip) on every push and pull request. - .github/workflows/release.yml: on release published / v* tag / manual dispatch, gate on the CI suite then `npm publish --access public` to registry.npmjs.org using the NPM_TOKEN secret, with a tag-must-match-version guard. - Remove the old GitHub Packages publish.yml; sync package-lock.json. - README: add a Releasing section.
Empty std::vector::data() is nullptr on libstdc++ (Linux), so ArrayBuffer::copy did memcpy(dst, nullptr, 0) - benign but UBSan flags the NON_NULL violation and failed CI. Reserve so data() is non-null while size stays 0; the 0-length decode path is still exercised.
- test.yml: add a lint job (eslint + prettier --check). Fix the eslint config (add @react-native/babel-preset + the github-actions formatter; ignore example/generated/cpp), normalize formatting, add format/format:check scripts. - codeql.yml: CodeQL for javascript-typescript (no build) and c-cpp (manual build that compiles the codec via the NitroModules shim); push/PR to main + weekly. - dependabot.yml: weekly npm (root + example) and github-actions updates. - dependency-review.yml: fail PRs that add high-severity deps (needs public repo or GitHub Advanced Security). - release-please: config + manifest + workflow maintaining a release PR (version + CHANGELOG from Conventional Commits); merging it creates a Release that release.yml publishes. release.yml now triggers only on release published + dispatch (release-please owns tagging). README Releasing section updated.
- CI triggers for Git Flow: test.yml on push to main/develop/feature|release| hotfix + PRs to develop/main; codeql.yml also covers develop. - Add FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 to every workflow so the Node-20 JS actions run on Node 24 (silences the deprecation; Dependabot will bump majors). - Add CONTRIBUTING.md (Git Flow branch model + release-please flow), a PR template, and a Contributing section in the README.
- Emit a typed per-message object (Message.encode/decode) alongside the interface and generic facade: no magic strings, full TS inference. - Resolve google.protobuf.* imports (Timestamp/Duration/Empty/FieldMask/ wrappers) via the bundled WKT protos; register them so nested fields decode, and size their repeated/string fields with the wildcard options (incl. WKT .options so FieldMask.paths stays a static array). - Map Timestamp <-> Date|ISO string and Duration <-> milliseconds with a spec-driven recursive transform in the generated module. - Add 'generate --watch' (debounced) + proto:watch script. - Tests: WKT generation (TS shape + registry) and native WKT round-trip. map/oneof (and thus Struct/Value/Any) remain rejected by the codec at encode time with a clear message; see ROADMAP.
- Add a structured acme.Blob message (bench/proto/blob.proto) and a representative ~1KB/10KB/50KB size sweep across the native codec and protobuf.js/JSON. Top size is 50KB: nanopb's default build caps a single message at 64KB, which is what the library ships. - Add a base64 / number[] conversion micro-bench: converting a Uint8Array to the number[] the codec uses for bytes is ~10-50x more expensive than base64 and can dwarf encode/decode (~5ms at 100KB). Time-budgeted so per-op costs spanning 4us-5ms stay bounded. - PERFORMANCE.md: new 'Size sweep & boundary cost' section + TL;DR/methodology notes; documents the 64KB message cap and the bytes tax.
…rs + ROADMAP - README: document the typed per-message API (Message.encode/decode), the well-known types subset (Timestamp/Duration/Empty/FieldMask/wrappers) with natural JS mapping, and --watch. - README: add a Compatibility matrix (RN/New Arch/Hermes/Nitro/Expo/platforms), a Semver & deprecation policy, and an Errors & validation table describing the real throw-on-invalid behavior (never silent truncation). - README: refresh Limitations (WKT supported subset, 64KB message cap, what still throws) and value-mapping table (Timestamp/Duration rows). - Add ROADMAP.md: full prioritized backlog from user feedback, marking this round's items done and capturing deferred work with design notes.
A schema importing google/protobuf/*.proto generates nanopb sources under
generated/google/protobuf/, which include their headers by subpath
("google/protobuf/timestamp.pb.h"). Two build configs missed them:
- iOS podspec: add generated/ to HEADER_SEARCH_PATHS so the subpath include
resolves (previously only cpp/nanopb was on the path -> 'file not found').
- Android CMake: GLOB_RECURSE the generated *.pb.c / *.cpp so the nested
well-known-type sources are compiled (previously the non-recursive glob
missed them -> undefined symbols at link).
Verified with a clean iOS simulator build of the example importing
Timestamp/Duration/FieldMask.
…check Add an acme.Session message (Timestamp/Duration/FieldMask/repeated Timestamp) to the example proto and a feature self-test card to the example app that exercises the generated typed API (AcmeUser/AcmeSession .encode/.decode) and the WKT JS mapping on mount, rendering FEATURES_PASS/FAIL. Verified all 6 checks pass on the iPhone 17 Pro simulator (Hermes, clean build).
- --bigint / config.bigint: type int64/uint64 fields as bigint (converted to decimal strings at the codec boundary). Default stays precision-safe string. - --enums string / config.enums: type enums as their value-name string-literal union, mapping names<->numbers in encode/decode. Default stays number. - Typed error classes (ProtobufError + Limit/Field subclasses) + classifyProtobufError; the generated facade wraps native throws into them. - Non-strict codegen warns about fields falling back to default size limits. Codegen conversion runtime extended with i64 + enum kinds; back-compatible (no flags = previous output). Tests: bigint/enum generation + error classifier.
- Native byteLength(messageName, message): encoded size without allocating the output buffer (reuses nanopb's pb_get_encoded_size). New Nitro spec method, nitrogen-regenerated bindings, codec encodedByteLength(). - Generated facade exposes typed byteLength (generic + per-message) and a readonly fields metadata array per message (name/tag/proto-type/repeated) for lightweight runtime reflection. - Native round-trip test asserts byteLength == encoded buffer size. (strict decode that errors on unknown fields is not feasible with nanopb, which silently skips unknown fields by design; tracked in ROADMAP.)
- tests/interop: a message encoded by protobuf.js decodes + re-encodes through the native codec and decodes back identically in protobuf.js (all field kinds incl int64/bytes/nested/repeated) — proves standard wire compatibility. - metro.js: withNitroProtobuf(config, opts) runs codegen on Metro startup (opt-in, never crashes the bundler; supports outDir/tsOut/bigint/enums/ skipProtoc). Added to published files. Pairs with proto:generate --watch.
README: bigint/enums config + CLI, runtime helpers (byteLength, fields reflection, typed ProtobufError), Metro integration. ROADMAP: mark this round's items done; record honest deferral rationale for oneof/map (memory-safety fuzzing bar), Uint8Array bytes (AnyMap core constraint), strict decode (nanopb skips unknowns by design), and canonical JSON.
Extend the example feature self-test to assert byteLength == encoded size, generated fields metadata, and that an unknown field throws a typed ProtobufError(kind='unknown-field'). Verified FEATURES_PASS (9/9) on the iPhone 17 Pro simulator with a clean build.
Encode sets the nanopb which_<oneof> selector to the chosen member's tag and writes only that union member (last-wins across members of the same oneof, matching proto semantics); decode surfaces only the member whose tag equals which_. Factored the per-field presence check into fieldIsPresent() shared by the top-level and nested decode paths. Each oneof member is exposed as an optional field in the generated TS (no codec or codegen change needed beyond removing the runtime rejection). Verified: native round-trip of string/int/message members (+ absence of the others), and ~40k adversarial garbage decodes + full bit-flip sweep of a oneof buffer under the ASan/UBSan fuzz harness. 18/18 tests green.
A proto map<K,V> maps to a JS object ({ [key]: value }). nanopb models a map as
a repeated synthetic entry message ('<Msg>_<Field>Entry { key=1; value=2 }')
that protobuf.js does not surface, so the generator synthesizes its registry
entry (key type from keyType, value type from the field) and flags it
is_map_entry so listMessages() hides it. The codec encodes/decodes each entry
via that descriptor (reusing populateMessage/decodeMessageInternal) and
transforms array<->object; integer/bool keys are coerced to/from JS string keys.
Added is_map_entry to MessageInfo. Generated TS types a map field as
{ [key: string|number]: V }.
Verified: native round-trip of map<string,int32> and map<string,Message> (+
listMessages hiding entries), and ~40k adversarial garbage decodes + bit-flip
sweep of a map buffer under the ASan/UBSan fuzz harness. 18/18 tests green.
(map values that are well-known types are not auto-converted yet; see ROADMAP.)
…map_entry) Add an acme.Shape message (oneof + map<string,int32> + map<string,Address>) to the example and self-test checks; verified FEATURES_PASS (12/12) on the iPhone 17 Pro simulator (clean build) — oneof set-member-only, map<string,int32>, and map<string,Message> all round-trip over JSI. Regenerate the shipped registry to the new MessageInfo layout (trailing is_map_entry flag).
Map fields whose value type needs conversion now use an m:<kind> spec so the runtime transforms each map value (e.g. map<string,Timestamp> <-> Date/ISO, map<string,Duration> <-> ms). Plain-scalar maps (map<string,int32>) keep the fast no-conversion path. needsConv runs on the value's base kind to avoid recursion through the map wrapper.
proto2 optional (explicit presence via nanopb has_), required, repeated and field defaults round-trip through the codec (the existing OPTIONAL/has_ handling covers it); unset optionals are omitted on decode. Extensions and groups are unsupported (best-effort guard for extend/group fields in the generator). Tests: native proto2 round-trip (required + optional + repeated + int64 + unset-omitted) and a proto2 generator test.
Generated toJson/fromJson (generic + per-message) following the proto3 JSON mapping: lowerCamelCase keys (both forms accepted on input), enum value names, 64-bit as strings (bigint-aware), base64 bytes, Timestamp as RFC3339, Duration as "Ns", nested messages, repeated + maps. Distinct from the binary encode/decode JS shape; Struct/Value/Any pass through (unsupported). Test transpiles the generated module (typescript) with the native import stubbed and exercises the real toJson/fromJson round-trip + WKT/enum/camelCase cases.
- package.json 1.0.0 -> 1.1.0 (all the additive features land in one minor). - ROADMAP: merge the two Shipped sections into 'Shipped (1.1.0)'; relabel inline (1.2.0) markers to (1.1.0). - example: relabel the on-device feature card to '1.1.0 features'. - Code formatted (prettier + eslint --fix); format:check + typecheck clean. Verified: host suite 22/22 green; clean iOS simulator build -> FEATURES_PASS (12/12) incl typed API, WKT, byteLength, reflection, typed errors, oneof, and map (scalar + message).
Add a Color enum + AllTypes message exercising all 15 proto3 scalar types (incl sint/fixed/sfixed), enum, nested message, repeated (scalar/string/message), maps with string AND integer keys, and a oneof. Native round-trip asserts every field type survives encode/decode. Also fix bench/run-native.mjs to collect *.pb.c recursively (well-known-type sources live under generated/google/protobuf/).
Re-ran the full perf suite in a single quiet run (Spotlight indexing disabled) so the small-payload, size-sweep and base64 numbers are directly comparable: - native -O2 microbench (default ~1.5µs enc/dec; was noisy before) - protobuf.js vs JSON on node - base64 / number[] boundary cost (u8->number[] ~1.8ms at 100KB) - iOS on-device Release (reproduces prior run: default 0.180M enc / 0.251M dec, ~2-3x over protobuf.js) Refreshed all tables + the derived JSI/ratio numbers; Android retained from the prior Release run (noted).
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.23 to 4.18.1. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](lodash/lodash@4.17.23...4.18.1) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.18.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps lodash from 4.17.23 to 4.18.1.
Release notes
Sourced from lodash's releases.
Commits
cb0b9b9release(patch): bump main to 4.18.1 (#6177)75535f5chore: prune stale advisory refs (#6170)62e91bcdocs: remove n_ Node.js < 6 REPL note from README (#6165)59be2derelease(minor): bump to 4.18.0 (#6161)af63457fix: broken tests for _.template 879aaa91073a76fix: linting issues879aaa9fix: validate imports keys in _.templatefe8d32efix: block prototype pollution in baseUnset via constructor/prototype traversal18ba0a3refactor(fromPairs): use baseAssignValue for consistent assignment (#6153)b819080ci: add dist sync validation workflow (#6137)Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)You can disable automated security fix PRs for this repo from the Security Alerts page.