Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fromObject should not initialize oneof members #1597

merged 2 commits into from Apr 29, 2021


Copy link

@alexander-fenster alexander-fenster commented Apr 28, 2021

Fixes #1596.

The problem happens when an instance of a statically generated class (e.g. generated with pbjs) is passed to a dynamically generated .fromObject (e.g. from a protobuf Root loaded in the runtime). Since the statically generated instance has all non-optional fields set to their default values in the prototype, including the oneof fields, the resulting message is incorrect because it has all non-primitive members of oneof assigned to the default value (e.g. empty string), which make serialized object deserialize incorrectly by official protobuf implementations (e.g. Python). The implementation of dynamic .fromObject has a safety check that does nothing if the typeof shows it's already an object of the correct type, but this safety check does not work since they technically have different types (static one vs dynamic one) in this particular case.

Real life scenario: someone creates an object using pbjs generated static class and new, then passes it to gRPC client based on proto files loaded dynamically (so the .fromObject it uses comes from a dynamic class).

To fix it, we need to make sure the oneof fields don't get initialized with anything other than null. This is the same logic I added previously (in #1584), so since proto3 optional fields are actually implemented as oneof members, I'm just extending the same logic to all oneof members, not just proto3 optional fields. I think it became clearer.

This PR consists of two parts. First, I'm adding a test to the static code generation (basically, pbjs -t static), because it's currently not covered by any test. The second commit will bring an actual fix to the problem described above.

Copy link
Contributor Author

Expected test failure:

@alexander-fenster alexander-fenster merged commit 90afe44 into master Apr 29, 2021
alexander-fenster added a commit that referenced this pull request Apr 29, 2021
* test: adding test for pbjs static code generation

* fix: fromObject should not initialize oneof members
@dcodeIO dcodeIO deleted the cli-test branch April 7, 2022 04:34
alexander-fenster added a commit that referenced this pull request Jul 7, 2022
* feat: proto3 optional support

* chore: pre-release v6.11.0-pre

* fix: rebuild

* fix: fromObject should not initialize oneof members (#1597)

* test: adding test for pbjs static code generation

* fix: fromObject should not initialize oneof members

* chore: release v6.11.0

* chore: rebuild

* feat: add --no-service option for pbjs static target (#1577)

This option skips generation of service clients.

Co-authored-by: Alexander Fenster <>

* deps: set @types/node to >= (#1575)

* deps: set @types/node to star version

When using `protobuf.js` as a dependency in a project it is important
that `@types/node` package gets de-duped and has the same version as for
the rest of the modules in the project. Otherwise, typing conflicts
could happen as they do between v13 and v14 node types.

* fix: use @types/node >=13.7.0

* fix: use @types/node >=13.7.0

Co-authored-by: Alexander Fenster <>
Co-authored-by: Alexander Fenster <>

* chore: rebuild

* docs: update changelog

* fix: parse.js "parent.add(oneof)“ error (#1602)

Co-authored-by: xiaoweili <>

* chore: release v6.11.1

* fix(types): bring back Field.rule to .d.ts

* fix: rebuild type, release v6.11.2

* build: configure backports

* build: configure 6.x as default branch

* fix: do not let setProperty change the prototype (#1731)

* fix(deps): use eslint 8.x (#1728)

* build: run tests if ci label added (#1734)

* build: publish to main

* chore(6.x): release 6.11.3 (#1737)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]>

* Support parsing of complex options

* Use readValue to read the proto value and add better example

* Fix lint issues

* fix: rollback files

* Re-do parse logic to take arrays into account and make it simpler

Co-authored-by: Alexander Fenster <>
Co-authored-by: Matthew Douglass <>
Co-authored-by: Fedor Indutny <>
Co-authored-by: Alexander Fenster <>
Co-authored-by: leon <>
Co-authored-by: xiaoweili <>
Co-authored-by: Benjamin Coe <>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
None yet

Successfully merging this pull request may close these issues.

fromObject breaks oneof content
2 participants