Skip to content

Commit

Permalink
improvement for class parser
Browse files Browse the repository at this point in the history
  • Loading branch information
phith0n committed Mar 22, 2024
1 parent 6529d29 commit d9b3e4d
Show file tree
Hide file tree
Showing 22 changed files with 144 additions and 105 deletions.
22 changes: 19 additions & 3 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
linters:
disable-all: true
enable:
- deadcode
- unused
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- structcheck
- unused
- varcheck
- gofmt
- goconst
- misspell
- nolintlint
- tagliatelle
linters-settings:
misspell:
locale: US
nolintlint:
allow-unused: false # report any unused nolint directives
require-explanation: false # don't require an explanation for nolint directives
require-specific: false # don't require nolint directives to be specific about which linter is being skipped
tagliatelle:
case:
rules:
json: snake
yaml: snake
xml: snake
form: snake
msgpack: snake
49 changes: 0 additions & 49 deletions class/access.go

This file was deleted.

22 changes: 22 additions & 0 deletions class/attribute_access.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package class

type AttrAccessFlag uint16

const (
AttrAccPublic AttrAccessFlag = 0x0001 // Declared public; may be accessed from outside its package.
AttrAccPrivate AttrAccessFlag = 0x0002 // Declared private; accessible only within the defining class and other classes belonging to the same nest (§5.4.4).
AttrAccProtected AttrAccessFlag = 0x0004 // Declared protected; may be accessed within subclasses.
AttrAccStatic AttrAccessFlag = 0x0008 // Declared static.
AttrAccFinal AttrAccessFlag = 0x0010 // Declared final; must not be overridden (§5.4.5).
AttrAccSynchronized AttrAccessFlag = 0x0020 // Declared synchronized; invocation is wrapped by a monitor use.
AttrAccBridge AttrAccessFlag = 0x0040 // A bridge method, generated by the compiler.
AttrAccVarargs AttrAccessFlag = 0x0080 // Declared with variable number of arguments.
AttrAccNative AttrAccessFlag = 0x0100 // Declared native; implemented in a language other than the Java programming language.
AttrAccAbstract AttrAccessFlag = 0x0400 // Declared abstract; no implementation is provided.
AttrAccStrict AttrAccessFlag = 0x0800 // In a class file whose major version number is at least 46 and at most 60: Declared strictfp.
AttrAccSynthetic AttrAccessFlag = 0x1000 // Declared synthetic; not present in the source code.
)

func (aaf AttrAccessFlag) HasAccessFlag(flag AttrAccessFlag) bool {
return (flag & aaf) == flag
}
50 changes: 50 additions & 0 deletions class/class_access.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package class

import (
"encoding/binary"
"fmt"
"github.com/phith0n/zkar/commons"
)

type ClassAccessFlag uint16

const (
ClassAccPublic ClassAccessFlag = 0x0001 // Declared public; may be accessed from outside its package.
ClassAccPrivate ClassAccessFlag = 0x0002 // Marked private in source.
ClassAccProtected ClassAccessFlag = 0x0004 // Marked protected in source.
ClassAccStatic ClassAccessFlag = 0x0008 // Marked or implicitly static in source.
ClassAccFinal ClassAccessFlag = 0x0010 // Declared final; no subclasses allowed.
ClassAccSuper ClassAccessFlag = 0x0020 // Treat superclass methods specially when invoked by the invokespecial instruction.
ClassAccInterface ClassAccessFlag = 0x0200 // Is an interface, not a class.
ClassAccAbstract ClassAccessFlag = 0x0400 // Declared abstract; must not be instantiated.
ClassAccSynthetic ClassAccessFlag = 0x1000 // Declared synthetic; not present in the source code.
ClassAccAnnotation ClassAccessFlag = 0x2000 // Declared as an annotation type.
ClassAccEnum ClassAccessFlag = 0x4000 // Declared as an enum type.
ClassAccModule ClassAccessFlag = 0x8000 // Is a module, not a class or interface.
)

func (caf ClassAccessFlag) HasAccessFlag(flag ClassAccessFlag) bool {
return (flag & caf) == flag
}

func (cf *ClassFile) readAccessFlag(stream *commons.Stream) error {
bs, err := stream.ReadN(2)
if err != nil {
return fmt.Errorf("read access flag failed, no enough data in the stream")
}

var i = binary.BigEndian.Uint16(bs)
cf.AccessFlag = ClassAccessFlag(i)

// check access flag valid
if cf.AccessFlag.HasAccessFlag(ClassAccFinal) && cf.AccessFlag.HasAccessFlag(ClassAccAbstract) {
return fmt.Errorf("ACC_FINAL and ACC_ABSTRACT are not able to set at the same time")
}

if cf.AccessFlag.HasAccessFlag(ClassAccAnnotation) && !cf.AccessFlag.HasAccessFlag(ClassAccInterface) {
return fmt.Errorf("if ACC_ANNOTATION is set, ACC_ANNOTATION must also be set")
}

// TODO: maybe need more check
return nil
}
4 changes: 2 additions & 2 deletions class/classfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type ClassFile struct {
MinorVersion uint16
MajorVersion uint16
ConstantPool []Constant
AccessFlag uint16
AccessFlag ClassAccessFlag
ThisClassIndex uint16
SuperClassIndex uint16
InterfaceIndexArray []uint16
Expand All @@ -29,7 +29,7 @@ func (cf *ClassFile) readHeader(stream *commons.Stream) error {
}

if !bytes.Equal(bs, []byte("\xCA\xFE\xBA\xBE")) {
return fmt.Errorf("magic number %v is not equal to CAFEBABE", hex.EncodeToString(bs))
return fmt.Errorf("magic number %v is not equal to 0xCAFEBABE", hex.EncodeToString(bs))
}

cf.MagicNumber = bs
Expand Down
68 changes: 34 additions & 34 deletions class/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@ import (
)

const (
CONSTANT_UTF8_INFO = 1
CONSTANT_INTEGER_INFO = 3
CONSTANT_FLOAT_INFO = 4
CONSTANT_LONG_INFO = 5
CONSTANT_DOUBLE_INFO = 6
CONSTANT_CLASS_INFO = 7
CONSTANT_STRING_INGFO = 8
CONSTANT_FIELD_REF_INFO = 9
CONSTANT_METHOD_REF_INFO = 10
CONSTANT_INTERFACE_METHOD_REF = 11
CONSTANT_NAME_AND_TYPE_INFO = 12
CONSTANT_METHOD_HANDLE_INFO = 15
CONSTANT_METHOD_TYPE_INFO = 16
CONSTANT_DYNAMIC_INFO = 17
CONSTANT_INVOKE_DYNAMIC_INFO = 18
CONSTANT_MODULE_INFO = 19
CONSTANT_PACKAGE_INFO = 20
ConstantUtf8Info = 1
ConstantIntegerInfo = 3
ConstantFloatInfo = 4
ConstantLongInfo = 5
ConstantDoubleInfo = 6
ConstantClassInfo = 7
ConstantStringInfo = 8
ConstantFieldRefInfo = 9
ConstantMethodRefInfo = 10
ConstantInterfaceMethodRefInfo = 11
ConstantNameAndTypeInfo = 12
ConstantMethodHandleInfo = 15
ConstantMethodTypeInfo = 16
ConstantDynamicInfo = 17
ConstantInvokeDynamicInfo = 18
ConstantModuleInfo = 19
ConstantPackageInfo = 20
)

type Constant interface {
Expand Down Expand Up @@ -57,39 +57,39 @@ func (cf *ClassFile) readConstant(stream *commons.Stream) error {

var obj Constant
switch bs[0] {
case CONSTANT_UTF8_INFO:
case ConstantUtf8Info:
obj, err = cf.readConstantUTF8(stream)
case CONSTANT_INTEGER_INFO:
case ConstantIntegerInfo:
obj, err = cf.readConstantInteger(stream)
case CONSTANT_FLOAT_INFO:
case ConstantFloatInfo:
obj, err = cf.readConstantFloat(stream)
case CONSTANT_LONG_INFO:
case ConstantLongInfo:
obj, err = cf.readConstantLong(stream)
case CONSTANT_DOUBLE_INFO:
case ConstantDoubleInfo:
obj, err = cf.readConstantDouble(stream)
case CONSTANT_CLASS_INFO:
case ConstantClassInfo:
obj, err = cf.readConstantClass(stream)
case CONSTANT_STRING_INGFO:
case ConstantStringInfo:
obj, err = cf.readConstantString(stream)
case CONSTANT_FIELD_REF_INFO:
case ConstantFieldRefInfo:
obj, err = cf.readConstantFieldRef(stream)
case CONSTANT_METHOD_REF_INFO:
case ConstantMethodRefInfo:
obj, err = cf.readConstantMethodRef(stream)
case CONSTANT_INTERFACE_METHOD_REF:
case ConstantInterfaceMethodRefInfo:
obj, err = cf.readConstantInterfaceMethodRef(stream)
case CONSTANT_NAME_AND_TYPE_INFO:
case ConstantNameAndTypeInfo:
obj, err = cf.readConstantNameAndType(stream)
case CONSTANT_METHOD_HANDLE_INFO:
case ConstantMethodHandleInfo:
obj, err = cf.readConstantMethodHandle(stream)
case CONSTANT_METHOD_TYPE_INFO:
case ConstantMethodTypeInfo:
obj, err = cf.readConstantMethodType(stream)
case CONSTANT_DYNAMIC_INFO:
case ConstantDynamicInfo:
obj, err = cf.readConstantDynamic(stream)
case CONSTANT_INVOKE_DYNAMIC_INFO:
case ConstantInvokeDynamicInfo:
obj, err = cf.readConstantInvokeDynamic(stream)
case CONSTANT_MODULE_INFO:
case ConstantModuleInfo:
obj, err = cf.readConstantModule(stream)
case CONSTANT_PACKAGE_INFO:
case ConstantPackageInfo:
obj, err = cf.readConstantPackage(stream)
default:
err = fmt.Errorf("constant type %v doesn't exists", bs)
Expand Down
2 changes: 1 addition & 1 deletion class/constant_class.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type ConstantClass struct {
}

func (c *ConstantClass) ToBytes() []byte {
var bs = []byte{CONSTANT_CLASS_INFO}
var bs = []byte{ConstantClassInfo}
bs = append(bs, commons.NumberToBytes(c.NameIndex)...)
return bs
}
Expand Down
2 changes: 1 addition & 1 deletion class/constant_double.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type ConstantDouble struct {
}

func (c *ConstantDouble) ToBytes() []byte {
var bs = []byte{CONSTANT_DOUBLE_INFO}
var bs = []byte{ConstantDoubleInfo}
bs = append(bs, commons.NumberToBytes(c.Double)...)
return bs
}
Expand Down
2 changes: 1 addition & 1 deletion class/constant_dynamic.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type ConstantDynamic struct {
}

func (c *ConstantDynamic) ToBytes() []byte {
var bs = []byte{CONSTANT_DYNAMIC_INFO}
var bs = []byte{ConstantDynamicInfo}
bs = append(bs, commons.NumberToBytes(c.BootstrapMethodIndex)...)
bs = append(bs, commons.NumberToBytes(c.NameAndTypeIndex)...)
return bs
Expand Down
2 changes: 1 addition & 1 deletion class/constant_fieldref.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type ConstantFieldRef struct {
}

func (c *ConstantFieldRef) ToBytes() []byte {
var bs = []byte{CONSTANT_FIELD_REF_INFO}
var bs = []byte{ConstantFieldRefInfo}
bs = append(bs, commons.NumberToBytes(c.ClassIndex)...)
bs = append(bs, commons.NumberToBytes(c.NameAndTypeIndex)...)
return bs
Expand Down
2 changes: 1 addition & 1 deletion class/constant_float.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type ConstantFloat struct {
}

func (c *ConstantFloat) ToBytes() []byte {
var bs = []byte{CONSTANT_FLOAT_INFO}
var bs = []byte{ConstantFloatInfo}
bs = append(bs, commons.NumberToBytes(c.Float)...)
return bs
}
Expand Down
2 changes: 1 addition & 1 deletion class/constant_integer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type ConstantInteger struct {
}

func (c *ConstantInteger) ToBytes() []byte {
var bs = []byte{CONSTANT_INTEGER_INFO}
var bs = []byte{ConstantIntegerInfo}
bs = append(bs, commons.NumberToBytes(c.Integer)...)
return bs
}
Expand Down
2 changes: 1 addition & 1 deletion class/constant_invoke_dynamic.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type ConstantInvokeDynamic struct {
}

func (c *ConstantInvokeDynamic) ToBytes() []byte {
var bs = []byte{CONSTANT_INVOKE_DYNAMIC_INFO}
var bs = []byte{ConstantInvokeDynamicInfo}
bs = append(bs, commons.NumberToBytes(c.BootstrapMethodIndex)...)
bs = append(bs, commons.NumberToBytes(c.NameAndTypeIndex)...)
return bs
Expand Down
2 changes: 1 addition & 1 deletion class/constant_long.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type ConstantLong struct {
}

func (c *ConstantLong) ToBytes() []byte {
var bs = []byte{CONSTANT_LONG_INFO}
var bs = []byte{ConstantLongInfo}
bs = append(bs, commons.NumberToBytes(c.Long)...)
return bs
}
Expand Down
2 changes: 1 addition & 1 deletion class/constant_method_handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type ConstantMethodHandle struct {
}

func (c *ConstantMethodHandle) ToBytes() []byte {
var bs = []byte{CONSTANT_METHOD_HANDLE_INFO}
var bs = []byte{ConstantMethodHandleInfo}
bs = append(bs, c.ReferenceKind)
bs = append(bs, commons.NumberToBytes(c.ReferenceIndex)...)
return bs
Expand Down
2 changes: 1 addition & 1 deletion class/constant_method_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type ConstantMethodType struct {
}

func (c *ConstantMethodType) ToBytes() []byte {
var bs = []byte{CONSTANT_METHOD_TYPE_INFO}
var bs = []byte{ConstantMethodTypeInfo}
bs = append(bs, commons.NumberToBytes(c.DescriptorIndex)...)
return bs
}
Expand Down
2 changes: 1 addition & 1 deletion class/constant_methodref.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type ConstantMethodRef struct {
}

func (c *ConstantMethodRef) ToBytes() []byte {
var bs = []byte{CONSTANT_METHOD_REF_INFO}
var bs = []byte{ConstantMethodRefInfo}
bs = append(bs, commons.NumberToBytes(c.ClassIndex)...)
bs = append(bs, commons.NumberToBytes(c.NameAndTypeIndex)...)
return bs
Expand Down
2 changes: 1 addition & 1 deletion class/constant_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type ConstantModule struct {
}

func (c *ConstantModule) ToBytes() []byte {
var bs = []byte{CONSTANT_MODULE_INFO}
var bs = []byte{ConstantModuleInfo}
bs = append(bs, commons.NumberToBytes(c.NameIndex)...)
return bs
}
Expand Down
2 changes: 1 addition & 1 deletion class/constant_nametype.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type ConstantNameAndType struct {
}

func (c *ConstantNameAndType) ToBytes() []byte {
var bs = []byte{CONSTANT_NAME_AND_TYPE_INFO}
var bs = []byte{ConstantNameAndTypeInfo}
bs = append(bs, commons.NumberToBytes(c.NameIndex)...)
bs = append(bs, commons.NumberToBytes(c.DescriptorIndex)...)
return bs
Expand Down
2 changes: 1 addition & 1 deletion class/constant_package.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type ConstantPackage struct {
}

func (c *ConstantPackage) ToBytes() []byte {
var bs = []byte{CONSTANT_PACKAGE_INFO}
var bs = []byte{ConstantPackageInfo}
bs = append(bs, commons.NumberToBytes(c.NameIndex)...)
return bs
}
Expand Down
Loading

0 comments on commit d9b3e4d

Please sign in to comment.