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

bigints allow type overflow when encoding #925

Closed
8de2fdb0 opened this issue Sep 26, 2023 · 5 comments
Closed

bigints allow type overflow when encoding #925

8de2fdb0 opened this issue Sep 26, 2023 · 5 comments

Comments

@8de2fdb0
Copy link
Contributor

8de2fdb0 commented Sep 26, 2023

I have an issue with following generated snippet:

 encode(message: MyMessage, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
    if (message.ref !== BigInt("0")) {
      writer.uint32(9).fixed64(message.ref.toString());
    }
  },

It uses --ts_proto_opt=forceLong=bigint and uses bigints as input.

If I use following number as input for the fixed64 the encoded protobuf value is 0

18_446_744_073_709_551_615n + 1n

So it basically overflows.

Is there any way to guard against this unexpected behaviour?

@jcready
Copy link

jcready commented Sep 28, 2023

Are you expecting an error to be thrown or for it to just not encode the zero value (after overflow) because it's the default value?.

@8de2fdb0
Copy link
Contributor Author

8de2fdb0 commented Sep 29, 2023

Good question, I could not find compiler spec for protoc and the protoc c++ implementation dos exactly the same, so I would consider that the correct behaviour based on the reference implementation.

On the other hand the rust implementation would catch that at compile-time, and this is a typescript library.

Are there any guards for overflows or malformed input used in ts-proto currently?

Maybe something like :

const MAX_FIXED64 = 18_446_744_073_709_551_615n;

 encode(message: MyMessage, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
    if (message.ref > MAX_FIXED64) {
       throw new Error("value for ref field in MyMessage is larger then MAX_FIXED64");
    }
    if (message.ref !== BigInt("0")) {
      writer.uint32(9).fixed64(message.ref.toString());
    }
  },

@stephenh
Copy link
Owner

We have somewhat similar detection for Number/long overflows:

https://github.com/stephenh/ts-proto/blob/main/src/main.ts#L505

function longToNumber(long: Long): number {
  if (long.gt(globalThis.Number.MAX_SAFE_INTEGER)) {
    throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
  }
  return long.toNumber();
}

So @8de2fdb0 if you wanted to work on a PR that did similar runtime detection of "incoming bigint will be larger than fixed64", that would sgtm.

I think it would be around in here:

https://github.com/stephenh/ts-proto/blob/main/src/main.ts#L1246

But not 100% sure. Thanks!

@8de2fdb0
Copy link
Contributor Author

8de2fdb0 commented Oct 4, 2023

I opened #938

@stephenh
Copy link
Owner

stephenh commented Oct 5, 2023

Fixed in #938 , thanks @8de2fdb0 !

@stephenh stephenh closed this as completed Oct 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants