protobuf.js icon indicating copy to clipboard operation
protobuf.js copied to clipboard

Error occurs in parse processing when array is set to field options

Open activeguild opened this issue 4 years ago • 11 comments

protobuf.js version: 6.8.6

Error occurs in parse processing when array is set to field options. I want to avoid the error.

sample repository: https://github.com/activeguild/use-proto-fieldoption

syntax = "proto3";

package sample;

import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
  Scope scope = 50000;
}

message Scope {
  repeated string type = 1;
}

message Sample {
  uint64 id = 1 [
    (scope) = {
      types: ["1"]
    }
  ];
}
import * as protoLoader from '@grpc/proto-loader';
import * as grpcLibrary from 'grpc';

const protoFileNames = [
  './protos/sample_load_success.proto',
  './protos/sample_load_error.proto',
];
const options: protoLoader.Options = {};

protoFileNames.forEach(protoFileName => {
  protoLoader.load(protoFileName, options).then(packageDefinition => {
    const packageObject = grpcLibrary.loadPackageDefinition(packageDefinition);
    console.log(packageObject);
  });
});

error location https://github.com/protobufjs/protobuf.js/blob/2ac09c73a80be733a76b786acf36eec71e043ee6/src/parse.js#L570

error detail:

(node:5172) UnhandledPromiseRejectionWarning: Error: illegal value '[' (protos/sample_load_error.proto, line 18)
    at illegal (/Users/JG20033/Documents/projects/use-grpc-mock/node_modules/protobufjs/src/parse.js:94:16)
    at readValue (/Users/JG20033/Documents/projects/use-grpc-mock/node_modules/protobufjs/src/parse.js:133:19)
    at parseOptionValue (/Users/JG20033/Documents/projects/use-grpc-mock/node_modules/protobufjs/src/parse.js:573:63)
    at parseOption (/Users/JG20033/Documents/projects/use-grpc-mock/node_modules/protobufjs/src/parse.js:551:9)
    at parseInlineOptions (/Users/JG20033/Documents/projects/use-grpc-mock/node_modules/protobufjs/src/parse.js:590:17)
    at parseField_line (/Users/JG20033/Documents/projects/use-grpc-mock/node_modules/protobufjs/src/parse.js:376:13)
    at ifBlock (/Users/JG20033/Documents/projects/use-grpc-mock/node_modules/protobufjs/src/parse.js:290:17)
    at parseField (/Users/JG20033/Documents/projects/use-grpc-mock/node_modules/protobufjs/src/parse.js:366:9)
    at parseType_block (/Users/JG20033/Documents/projects/use-grpc-mock/node_modules/protobufjs/src/parse.js:338:21)
    at ifBlock (/Users/JG20033/Documents/projects/use-grpc-mock/node_modules/protobufjs/src/parse.js:286:17)
(node:5172) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:5172) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I want to temporarily avoid the error as follows.

function parseOptionValue(parent, name) {
  if (skip('{', true)) {
    // { a: "foo" b { c: "bar" } }
    do {
      /* istanbul ignore if */
      if (!nameRe.test((token = next()))) throw illegal(token, 'name');

      if (peek() === '{') parseOptionValue(parent, name + '.' + token);
      else {
        skip(':');
        if (peek() === '{') parseOptionValue(parent, name + '.' + token);
        else if (peek() === '[') {
          skip('[');
          while (next() !== ']') {}
        } else setOption(parent, name + '.' + token, readValue(true));
      }
      skip(',', true);
    } while (!skip('}', true));
  } else setOption(parent, name, readValue(true));
  // Does not enforce a delimiter to be universal
}

activeguild avatar Mar 10 '20 03:03 activeguild

Array is not allowed in option? https://github.com/protocolbuffers/protobuf/blob/09354db1434859a31a3c81abebcc4018d42f2715/src/google/protobuf/descriptor.proto#L499

activeguild avatar Mar 10 '20 10:03 activeguild

@dcodeIO

Excuse me. Can you see it?

activeguild avatar May 20 '20 02:05 activeguild

Is there any updates for the problem?

acrazing avatar Jun 11 '20 04:06 acrazing

@acrazing No solution has been found yet.

activeguild avatar Jun 18 '20 23:06 activeguild

I see this issue as well. I am pretty sure that arrays are allowed in options since my team uses these extensively with parsers for other languages and protoc does provide them in the binary descriptor files it can generate.

I made my own example repo here before I thought to look for an open issue.

svelez avatar Jul 12 '20 01:07 svelez

I would highly appreciate a fix too. A reasonable behavior could be, not to fail, however, just to ignore the option.

@activeguild Any news here?

Thanks a lot.

alxndrdude avatar Aug 12 '20 15:08 alxndrdude

:up:

hugebdu avatar Aug 24 '20 11:08 hugebdu

This has not been resolved yet. A similar error occurs.

activeguild avatar Sep 07 '20 01:09 activeguild

This issue means that messages using some of grpc-gateway's openapi annotations can't be parsed:

https://github.com/grpc-ecosystem/grpc-gateway/blob/master/examples/internal/proto/examplepb/a_bit_of_everything.proto#L271

  float float_value = 3 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Float value field", default: "0.2", required: ['float_value']}];

stfp avatar Dec 13 '20 17:12 stfp

Thanks for this project. Any progress on a resolution to this issue. Would a PR be welcome?

huntc avatar May 26 '21 04:05 huntc

According to the protobuf spec the array structure is acceptable for multiple option names.

Is there any word on whether or not protobufjs plans to respect that spec?

when loading a proto file that uses this syntax, it breaks my js client.

https://protobuf.com/docs/language-spec#resolving-option-names

image

marsh73 avatar Aug 02 '23 15:08 marsh73