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

Update classfile.ts for better parser #260

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Kreijstal
Copy link

This is a more complete parser, that I tested that parse class files more completely.

This is a more complete parser, that I tested that parse class files more completely.
example/classfile.ts Fixed Show fixed Hide fixed
example/classfile.ts Fixed Show fixed Hide fixed
@keichi
Copy link
Owner

keichi commented Oct 2, 2024

Hi, thanks for extending the example. Can you fix the formatting errors?

npm run format:fix

Should automatically fix them.

@Kreijstal
Copy link
Author

Hi, thanks for extending the example. Can you fix the formatting errors?

npm run format:fix

Should automatically fix them.

I'll do it in a bit, I wrote it in javascript though, I'll attempt to translate it to typescript if it is a better example.

@keichi
Copy link
Owner

keichi commented Oct 2, 2024

The updated code does not compile with the following errors:

TSError: ⨯ Unable to compile TypeScript:
classfile.ts:108:28 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

108           console.log(this.$parent.frame_type);
                               ~~~~~~~
classfile.ts:110:20 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

110           if (this.$parent.frame_type >= 0 && this.$parent.frame_type <= 63)
                       ~~~~~~~
classfile.ts:110:52 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

110           if (this.$parent.frame_type >= 0 && this.$parent.frame_type <= 63)
                                                       ~~~~~~~
classfile.ts:112:20 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

112           if (this.$parent.frame_type >= 64 && this.$parent.frame_type <= 127)
                       ~~~~~~~
classfile.ts:112:53 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

112           if (this.$parent.frame_type >= 64 && this.$parent.frame_type <= 127)
                                                        ~~~~~~~
classfile.ts:114:20 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

114           if (this.$parent.frame_type === 247) return 2; // same_locals_1_stack_item_frame_extended
                       ~~~~~~~
classfile.ts:115:20 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

115           if (this.$parent.frame_type >= 248 && this.$parent.frame_type <= 250)
                       ~~~~~~~
classfile.ts:115:54 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

115           if (this.$parent.frame_type >= 248 && this.$parent.frame_type <= 250)
                                                         ~~~~~~~
classfile.ts:117:20 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

117           if (this.$parent.frame_type === 251) return 4; // same_frame_extended
                       ~~~~~~~
classfile.ts:118:20 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

118           if (this.$parent.frame_type >= 252 && this.$parent.frame_type <= 254)
                       ~~~~~~~
classfile.ts:118:54 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

118           if (this.$parent.frame_type >= 252 && this.$parent.frame_type <= 254)
                                                         ~~~~~~~
classfile.ts:120:20 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

120           if (this.$parent.frame_type === 255) return 6; // full_frame
                       ~~~~~~~
classfile.ts:142:29 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

142                 return this.$parent.$parent.frame_type - 251;
                                ~~~~~~~
classfile.ts:160:18 - error TS2339: Property 'frame_type' does not exist on type 'ParserOptions'.

160         if (this.frame_type >= 0 && this.frame_type <= 63) {
                     ~~~~~~~~~~
classfile.ts:160:42 - error TS2339: Property 'frame_type' does not exist on type 'ParserOptions'.

160         if (this.frame_type >= 0 && this.frame_type <= 63) {
                                             ~~~~~~~~~~
classfile.ts:161:37 - error TS2339: Property 'frame_type' does not exist on type 'ParserOptions'.

161           frame.offset_delta = this.frame_type;
                                        ~~~~~~~~~~
classfile.ts:162:25 - error TS2339: Property 'frame_type' does not exist on type 'ParserOptions'.

162         } else if (this.frame_type >= 64 && this.frame_type <= 127) {
                            ~~~~~~~~~~
classfile.ts:162:50 - error TS2339: Property 'frame_type' does not exist on type 'ParserOptions'.

162         } else if (this.frame_type >= 64 && this.frame_type <= 127) {
                                                     ~~~~~~~~~~
classfile.ts:163:37 - error TS2339: Property 'frame_type' does not exist on type 'ParserOptions'.

163           frame.offset_delta = this.frame_type - 64;
                                        ~~~~~~~~~~
classfile.ts:333:39 - error TS2339: Property '$root' does not exist on type 'ParserOptions'.

333         return { index: _, name: this.$root.constant_pool?.entries[_] };
                                          ~~~~~
classfile.ts:339:31 - error TS2339: Property 'attribute_name_index' does not exist on type 'ParserOptions'.

339         const nameInfo = this.attribute_name_index.name;
                                  ~~~~~~~~~~~~~~~~~~~~
classfile.ts:420:25 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

420             return this.$parent.attribute_length;
                            ~~~~~~~
classfile.ts:460:21 - error TS2339: Property 'high' does not exist on type 'ParserOptions'.

460         return this.high - this.low + 1;
                        ~~~~
classfile.ts:460:33 - error TS2339: Property 'low' does not exist on type 'ParserOptions'.

460         return this.high - this.low + 1;
                                    ~~~
classfile.ts:702:18 - error TS2339: Property 'opcode' does not exist on type 'ParserOptions'.

702             this.opcode // Access the "opcode" property of the current item
                     ~~~~~~
classfile.ts:722:7 - error TS2322: Type '(item: any, buffer: any) => any' is not assignable to type 'string | number | ((item: any) => number) | undefined'.
  Type '(item: any, buffer: any) => any' is not assignable to type '(item: any) => number'.
    Target signature provides too few arguments. Expected 2 or more, but got 1.

722       lengthInBytes: function (item, buffer) {
          ~~~~~~~~~~~~~

  ../lib/binary_parser.ts:116:3
    116   lengthInBytes?: number | string | ((item: any) => number);
          ~~~~~~~~~~~~~
    The expected type comes from property 'lengthInBytes' which is declared here on type 'ParserOptions'
classfile.ts:722:32 - error TS6133: 'item' is declared but its value is never read.

722       lengthInBytes: function (item, buffer) {
                                   ~~~~
classfile.ts:722:32 - error TS7006: Parameter 'item' implicitly has an 'any' type.

722       lengthInBytes: function (item, buffer) {
                                   ~~~~
classfile.ts:722:38 - error TS6133: 'buffer' is declared but its value is never read.

722       lengthInBytes: function (item, buffer) {
                                         ~~~~~~
classfile.ts:722:38 - error TS7006: Parameter 'buffer' implicitly has an 'any' type.

722       lengthInBytes: function (item, buffer) {
                                         ~~~~~~
classfile.ts:724:21 - error TS2339: Property '$parent' does not exist on type 'ParserOptions'.

724         return this.$parent.code_length;
                        ~~~~~~~
classfile.ts:775:7 - error TS2322: Type '(item: any, buffer: any, offset: any) => boolean' is not assignable to type '"eof" | ((item: any, buffer: Buffer) => boolean) | undefined'.
  Type '(item: any, buffer: any, offset: any) => boolean' is not assignable to type '(item: any, buffer: Buffer) => boolean'.
    Target signature provides too few arguments. Expected 3 or more, but got 2.

775       readUntil: function (item, buffer, offset) {
          ~~~~~~~~~

  ../lib/binary_parser.ts:120:3
    120   readUntil?: "eof" | ((item: any, buffer: Buffer) => boolean);
          ~~~~~~~~~
    The expected type comes from property 'readUntil' which is declared here on type 'ParserOptions'
classfile.ts:775:28 - error TS7006: Parameter 'item' implicitly has an 'any' type.

775       readUntil: function (item, buffer, offset) {
                               ~~~~
classfile.ts:775:34 - error TS6133: 'buffer' is declared but its value is never read.

775       readUntil: function (item, buffer, offset) {
                                     ~~~~~~
classfile.ts:775:34 - error TS7006: Parameter 'buffer' implicitly has an 'any' type.

775       readUntil: function (item, buffer, offset) {
                                     ~~~~~~
classfile.ts:775:42 - error TS6133: 'offset' is declared but its value is never read.

775       readUntil: function (item, buffer, offset) {
                                             ~~~~~~
classfile.ts:775:42 - error TS7006: Parameter 'offset' implicitly has an 'any' type.

775       readUntil: function (item, buffer, offset) {
                                             ~~~~~~
classfile.ts:776:18 - error TS2339: Property 'entries' does not exist on type 'ParserOptions'.

776         if (this.entries.length >= this.count - 1) return true;
                     ~~~~~~~
classfile.ts:776:41 - error TS2339: Property 'count' does not exist on type 'ParserOptions'.

776         if (this.entries.length >= this.count - 1) return true;
                                            ~~~~~
classfile.ts:779:16 - error TS2339: Property 'entries' does not exist on type 'ParserOptions'.

779           this.entries.push(null); // Add placeholder for the second slot
                   ~~~~~~~

    at createTSError (/Users/keichi/Projects/binary-parser/node_modules/ts-node/src/index.ts:859:12)
    at reportTSError (/Users/keichi/Projects/binary-parser/node_modules/ts-node/src/index.ts:863:19)
    at getOutput (/Users/keichi/Projects/binary-parser/node_modules/ts-node/src/index.ts:1077:36)
    at Object.compile (/Users/keichi/Projects/binary-parser/node_modules/ts-node/src/index.ts:1433:41)
    at Module.m._compile (/Users/keichi/Projects/binary-parser/node_modules/ts-node/src/index.ts:1617:30)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/keichi/Projects/binary-parser/node_modules/ts-node/src/index.ts:1621:12)
    at Module.load (node:internal/modules/cjs/loader:1317:32)
    at Function.Module._load (node:internal/modules/cjs/loader:1127:12)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14) {
  diagnosticCodes: [
    2339, 2339, 2339, 2339, 2339, 2339,
    2339, 2339, 2339, 2339, 2339, 2339,
    2339, 2339, 2339, 2339, 2339, 2339,
    2339, 2339, 2339, 2339, 2339, 2339,
    2339, 2322, 6133, 7006, 6133, 7006,
    2339, 2322, 7006, 6133, 7006, 6133,
    7006, 2339, 2339, 2339
  ]
}

@Kreijstal
Copy link
Author

Kreijstal commented Oct 2, 2024

@keichi Thanks a lot for the feedback, I did some changes (changed everything to const, fixed comments, fixed the ts errors), and tested with the following commands:

npx tsc example/classfile.ts 
node example/classfile.js

I get no warnings and works. But maybe I am running it wrong?

Comment on lines +197 to +218
ElementValue = ElementValue.choice("value", {
tag: "tag",
choices: {
66: Parser.start().uint16be("const_value_index"), // byte ('B')
67: Parser.start().uint16be("const_value_index"), // char ('C')
68: Parser.start().uint16be("const_value_index"), // double ('D')
70: Parser.start().uint16be("const_value_index"), // float ('F')
73: Parser.start().uint16be("const_value_index"), // int ('I')
74: Parser.start().uint16be("const_value_index"), // long ('J')
83: Parser.start().uint16be("const_value_index"), // short ('S')
90: Parser.start().uint16be("const_value_index"), // boolean ('Z')
115: Parser.start().uint16be("const_value_index"), // String ('s')
101: Parser.start()
.uint16be("type_name_index")
.uint16be("const_name_index"), // enum constant ('e')
99: Parser.start().uint16be("class_info_index"), // class ('c')
64: Parser.start().nest("annotation_value", { type: "annotation" }), // annotation ('@')
91: Parser.start() // array ('[')
.uint16be("num_values")
.array("values", { type: "elementvalue", length: "num_values" }),
},
});

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning

The value assigned to ElementValue here is unused.
Comment on lines +1219 to +1239
CodeAttribute = CodeAttribute.useContextVars()
.uint16be("max_stack")
.uint16be("max_locals")
.uint32be("code_length")
.nest("code", {
type: BytecodeParser,
})
.uint16be("exception_table_length")
.array("exception_table", {
type: Parser.start()
.uint16be("start_pc")
.uint16be("end_pc")
.uint16be("handler_pc")
.uint16be("catch_type"),
length: "exception_table_length",
})
.uint16be("attributes_count")
.array("attributes", {
type: "attribute_info",
length: "attributes_count",
});

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning

The value assigned to CodeAttribute here is unused.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About these two warnings, I used let instead of const, because parser is a bit recursive, and I needed to define the "head" first otherwise it wouldn't let me use it. Something like, parser is not defined yet, maybe you know better.

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

Successfully merging this pull request may close these issues.

2 participants