Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
github.com/searKing/golang/tools/cmd/protoc-gen-go-tag
Generates Go code using a package as a tag rewriter that enhanced protoc-gen-go.
protoc-gen-go-tag Generates Go code using a package as a tag rewriter that enhanced protoc-gen-go.
The file xxx.pb.go is modified by protoc-gen-go based on xxx.proto. It has helpful defaults designed for use with protobuf with custom struct tags.
For example, given this snippet,
apply this proto file
syntax = "proto3";
package pb;
//import "google/protobuf/descriptor.proto";
import "github.com/searKing/golang/tools/protoc-gen-go-tag/tag/tag.proto";
message Http{
string protocol = 1;
string version = 2[json_name = "Url", (google.protobuf.field_tag) = {struct_tag: "validate:\"gte=0,lte=130\""}];;
Url url = 3[json_name = "Url", (google.protobuf.field_tag) = {struct_tag: "json:\"url_tag,omitempty\""}];
message Url {
string scheme = 1[json_name = "Scheme", (google.protobuf.field_tag) = {struct_tag: "json:\"schema_tag,omitempty\""}];
// string scheme = 1[json_name = "Scheme"];
}
}
running this command
# https://github.com/searKing/golang/blob/master/tools/protoc-gen-go-tag/tag/tag.proto
# `tag.proto` needs to be on the `protoc` include path
protoc -I . --go-tag_out=paths=source_relative:. *.proto
in the same directory will create the file pill.pb.go, containing
// Code generated by protoc-gen-go-tag. DO NOT EDIT.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1
// protoc v3.17.3
// source: example.proto
package pb
import (
_ "github.com/searKing/golang/tools/protoc-gen-go-tag/tag"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Http struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Protocol string `protobuf:"bytes,1,opt,name=protocol,proto3" json:"protocol,omitempty" validate:"oneof=http https"`
// version_default is the same as version_update
VersionDefault string `protobuf:"bytes,2,opt,name=version_default,json=VersionDefault,proto3" json:"version_with_default,omitempty" validate:"gte=0,lte=130"`
VersionUpdate string `protobuf:"bytes,3,opt,name=version_update,json=VersionUpdate,proto3" json:"version_with_update,omitempty" validate:"gte=0,lte=130"`
VersionReplace string `protobuf:"bytes,4,opt,name=version_replace,json=VersionReplace,proto3" json:"version_with_replace" validate:"gte=0,lte=130"`
Url *Http_Url `protobuf:"bytes,5,opt,name=url,json=Url,proto3" json:"url_tag,omitempty"`
}
func (x *Http) Reset() {
*x = Http{}
if protoimpl.UnsafeEnabled {
mi := &file_example_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Http) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Http) ProtoMessage() {}
func (x *Http) ProtoReflect() protoreflect.Message {
mi := &file_example_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Http.ProtoReflect.Descriptor instead.
func (*Http) Descriptor() ([]byte, []int) {
return file_example_proto_rawDescGZIP(), []int{0}
}
func (x *Http) GetProtocol() string {
if x != nil {
return x.Protocol
}
return ""
}
func (x *Http) GetVersionDefault() string {
if x != nil {
return x.VersionDefault
}
return ""
}
func (x *Http) GetVersionUpdate() string {
if x != nil {
return x.VersionUpdate
}
return ""
}
func (x *Http) GetVersionReplace() string {
if x != nil {
return x.VersionReplace
}
return ""
}
func (x *Http) GetUrl() *Http_Url {
if x != nil {
return x.Url
}
return nil
}
type Http_Url struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Scheme string `protobuf:"bytes,1,opt,name=scheme,json=Scheme,proto3" json:"schema_tag,omitempty"` // string scheme = 1[json_name = "Scheme"];
}
func (x *Http_Url) Reset() {
*x = Http_Url{}
if protoimpl.UnsafeEnabled {
mi := &file_example_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Http_Url) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Http_Url) ProtoMessage() {}
func (x *Http_Url) ProtoReflect() protoreflect.Message {
mi := &file_example_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Http_Url.ProtoReflect.Descriptor instead.
func (*Http_Url) Descriptor() ([]byte, []int) {
return file_example_proto_rawDescGZIP(), []int{0, 0}
}
func (x *Http_Url) GetScheme() string {
if x != nil {
return x.Scheme
}
return ""
}
var File_example_proto protoreflect.FileDescriptor
var file_example_proto_rawDesc = []byte{
0x0a, 0x0d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x02, 0x70, 0x62, 0x1a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x73, 0x65, 0x61, 0x72, 0x4b, 0x69, 0x6e, 0x67, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f,
0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e,
0x2d, 0x67, 0x6f, 0x2d, 0x74, 0x61, 0x67, 0x2f, 0x74, 0x61, 0x67, 0x2f, 0x74, 0x61, 0x67, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf5, 0x03, 0x0a, 0x04, 0x48, 0x74, 0x74, 0x70, 0x12, 0x3d,
0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x42, 0x21, 0xc2, 0xde, 0x1f, 0x1d, 0x0a, 0x1b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65,
0x3a, 0x22, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x3d, 0x68, 0x74, 0x74, 0x70, 0x20, 0x68, 0x74, 0x74,
0x70, 0x73, 0x22, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x63, 0x0a,
0x0f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3a, 0xc2, 0xde, 0x1f, 0x36, 0x0a, 0x34, 0x76, 0x61,
0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x22, 0x67, 0x74, 0x65, 0x3d, 0x30, 0x2c, 0x6c, 0x74,
0x65, 0x3d, 0x31, 0x33, 0x30, 0x22, 0x20, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,
0x74, 0x22, 0x52, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75,
0x6c, 0x74, 0x12, 0x60, 0x0a, 0x0e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x70,
0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x39, 0xc2, 0xde, 0x1f, 0x35,
0x0a, 0x33, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x22, 0x67, 0x74, 0x65, 0x3d,
0x30, 0x2c, 0x6c, 0x74, 0x65, 0x3d, 0x31, 0x33, 0x30, 0x22, 0x20, 0x6a, 0x73, 0x6f, 0x6e, 0x3a,
0x22, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x75, 0x70,
0x64, 0x61, 0x74, 0x65, 0x22, 0x52, 0x0d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x70,
0x64, 0x61, 0x74, 0x65, 0x12, 0x65, 0x0a, 0x0f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3c, 0xc2,
0xde, 0x1f, 0x38, 0x0a, 0x34, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x22, 0x67,
0x74, 0x65, 0x3d, 0x30, 0x2c, 0x6c, 0x74, 0x65, 0x3d, 0x31, 0x33, 0x30, 0x22, 0x20, 0x6a, 0x73,
0x6f, 0x6e, 0x3a, 0x22, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x69, 0x74, 0x68,
0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x22, 0x10, 0x01, 0x52, 0x0e, 0x56, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x3e, 0x0a, 0x03, 0x75,
0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x74,
0x74, 0x70, 0x2e, 0x55, 0x72, 0x6c, 0x42, 0x1e, 0xc2, 0xde, 0x1f, 0x1a, 0x0a, 0x18, 0x6a, 0x73,
0x6f, 0x6e, 0x3a, 0x22, 0x75, 0x72, 0x6c, 0x5f, 0x74, 0x61, 0x67, 0x2c, 0x6f, 0x6d, 0x69, 0x74,
0x65, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x52, 0x03, 0x55, 0x72, 0x6c, 0x1a, 0x40, 0x0a, 0x03, 0x55,
0x72, 0x6c, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x42, 0x21, 0xc2, 0xde, 0x1f, 0x1d, 0x0a, 0x1b, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22,
0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x74, 0x61, 0x67, 0x2c, 0x6f, 0x6d, 0x69, 0x74, 0x65,
0x6d, 0x70, 0x74, 0x79, 0x22, 0x52, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x42, 0x40, 0x5a,
0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x61, 0x72,
0x4b, 0x69, 0x6e, 0x67, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x74, 0x6f, 0x6f, 0x6c,
0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d,
0x74, 0x61, 0x67, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x3b, 0x70, 0x62, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_example_proto_rawDescOnce sync.Once
file_example_proto_rawDescData = file_example_proto_rawDesc
)
func file_example_proto_rawDescGZIP() []byte {
file_example_proto_rawDescOnce.Do(func() {
file_example_proto_rawDescData = protoimpl.X.CompressGZIP(file_example_proto_rawDescData)
})
return file_example_proto_rawDescData
}
var file_example_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_example_proto_goTypes = []interface{}{
(*Http)(nil), // 0: pb.Http
(*Http_Url)(nil), // 1: pb.Http.Url
}
var file_example_proto_depIdxs = []int32{
1, // 0: pb.Http.url:type_name -> pb.Http.Url
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_example_proto_init() }
func file_example_proto_init() {
if File_example_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_example_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Http); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_example_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Http_Url); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_example_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_example_proto_goTypes,
DependencyIndexes: file_example_proto_depIdxs,
MessageInfos: file_example_proto_msgTypes,
}.Build()
File_example_proto = out.File
file_example_proto_rawDesc = nil
file_example_proto_goTypes = nil
file_example_proto_depIdxs = nil
}
The easiest way to install is to run go get install github.com/searKing/golang/tools/protoc-gen-go-tag
. You can also manually git clone the repository to $GOPATH/src/github.com/searKing/golang/tools/protoc-gen-go-tag
.
The protoc
compiler expects to find plugins named proto-gen-xxx
on the execution $PATH
. So first:
export PATH=${PATH}:$(go env GOPATH)/bin
protoc-gen-go-tag
rewrites *.pb.go
by proto-gen-go
already. So use protoc-gen-go-tag
instead
of protoc-gen-go
protoc-gen-go
is installed by go get install google.golang.org/protobuf/cmd/protoc-gen-go
--go-tag_out
. That triggers the
protoc-gen-go-tag
plugin to generate *.pb.go
. That's it :)protoc-gen-go
installed by go get install github.com/golang/protobuf/protoc-gen-go
protoc-gen-go-tag
by go get github.com/searKing/golang/tools/protoc-gen-go-tag@e27209892e58d3df53c587f1feefb6290af17d85
protoc -I . --go_out=paths=source_relative:. --go-tag_out=paths=source_relative:. *.proto
*.pb.go
generated by protoc-gen-go
will be rewritten by protoc-gen-go-tag
tag.proto
import "github.com/searKing/golang/tools/protoc-gen-go-tag/tag/tag.proto";
with code in
the tag.proto
google.protobuf.field_tag
with field_tag
syntax = "proto3";
package pb;
// import "github.com/searKing/golang/tools/protoc-gen-go-tag/tag/tag.proto";
import "google/protobuf/descriptor.proto";
extend google.protobuf.FieldOptions {
FieldTag field_tag = 65000;
}
message FieldTag {
// struct tag.
string struct_tag = 1;// custom struct tag
UpdateStrategy update_strategy = 2;// update strategy
enum UpdateStrategy {
update = 0;// use custom struct tag to update struct tag generated by proto
replace = 1;// use custom struct tag to replace struct tag generated by proto
}
}
message Http{
string protocol = 1;
string version = 2[json_name = "Url", (field_tag) = {struct_tag: "validate:\"gte=0,lte=130\""}];;
Url url = 3[json_name = "Url", (field_tag) = {struct_tag: "json:\"url_tag,omitempty\""}];
message Url {
string scheme = 1[json_name = "Scheme", (field_tag) = {struct_tag: "json:\"schema_tag,omitempty\""}];
// string scheme = 1[json_name = "Scheme"];
}
}
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.