| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Licensed to the Apache Software Foundation (ASF) under one |
| 3 | * or more contributor license agreements. See the NOTICE file |
| 4 | * distributed with this work for additional information |
| 5 | * regarding copyright ownership. The ASF licenses this file |
| 6 | * to you under the Apache License, Version 2.0 (the |
| 7 | * "License"); you may not use this file except in compliance |
| 8 | * with the License. You may obtain a copy of the License at |
| 9 | * |
| 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | * |
| 12 | * Unless required by applicable law or agreed to in writing, |
| 13 | * software distributed under the License is distributed on an |
| 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 15 | * KIND, either express or implied. See the License for the |
| 16 | * specific language governing permissions and limitations |
| 17 | * under the License. |
| 18 | */ |
| 19 | |
| 20 | package thrift |
| 21 | |
| Jens Geyer | 3ea26be | 2015-07-10 00:23:39 +0200 | [diff] [blame] | 22 | import ( |
| John Boiles | 5785279 | 2018-01-05 14:37:05 -0800 | [diff] [blame] | 23 | "context" |
| Jens Geyer | 3ea26be | 2015-07-10 00:23:39 +0200 | [diff] [blame] | 24 | "errors" |
| Jens Geyer | 5f723cd | 2017-01-10 21:57:48 +0100 | [diff] [blame] | 25 | "fmt" |
| Jens Geyer | 3ea26be | 2015-07-10 00:23:39 +0200 | [diff] [blame] | 26 | ) |
| 27 | |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 28 | const ( |
| 29 | VERSION_MASK = 0xffff0000 |
| 30 | VERSION_1 = 0x80010000 |
| 31 | ) |
| 32 | |
| 33 | type TProtocol interface { |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 34 | WriteMessageBegin(ctx context.Context, name string, typeId TMessageType, seqid int32) error |
| 35 | WriteMessageEnd(ctx context.Context) error |
| 36 | WriteStructBegin(ctx context.Context, name string) error |
| 37 | WriteStructEnd(ctx context.Context) error |
| 38 | WriteFieldBegin(ctx context.Context, name string, typeId TType, id int16) error |
| 39 | WriteFieldEnd(ctx context.Context) error |
| 40 | WriteFieldStop(ctx context.Context) error |
| 41 | WriteMapBegin(ctx context.Context, keyType TType, valueType TType, size int) error |
| 42 | WriteMapEnd(ctx context.Context) error |
| 43 | WriteListBegin(ctx context.Context, elemType TType, size int) error |
| 44 | WriteListEnd(ctx context.Context) error |
| 45 | WriteSetBegin(ctx context.Context, elemType TType, size int) error |
| 46 | WriteSetEnd(ctx context.Context) error |
| 47 | WriteBool(ctx context.Context, value bool) error |
| 48 | WriteByte(ctx context.Context, value int8) error |
| 49 | WriteI16(ctx context.Context, value int16) error |
| 50 | WriteI32(ctx context.Context, value int32) error |
| 51 | WriteI64(ctx context.Context, value int64) error |
| 52 | WriteDouble(ctx context.Context, value float64) error |
| 53 | WriteString(ctx context.Context, value string) error |
| 54 | WriteBinary(ctx context.Context, value []byte) error |
| Yuxuan 'fishy' Wang | 19c13b4 | 2022-10-12 14:13:15 -0700 | [diff] [blame] | 55 | WriteUUID(ctx context.Context, value Tuuid) error |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 56 | |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 57 | ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqid int32, err error) |
| 58 | ReadMessageEnd(ctx context.Context) error |
| 59 | ReadStructBegin(ctx context.Context) (name string, err error) |
| 60 | ReadStructEnd(ctx context.Context) error |
| 61 | ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error) |
| 62 | ReadFieldEnd(ctx context.Context) error |
| 63 | ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) |
| 64 | ReadMapEnd(ctx context.Context) error |
| 65 | ReadListBegin(ctx context.Context) (elemType TType, size int, err error) |
| 66 | ReadListEnd(ctx context.Context) error |
| 67 | ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) |
| 68 | ReadSetEnd(ctx context.Context) error |
| 69 | ReadBool(ctx context.Context) (value bool, err error) |
| 70 | ReadByte(ctx context.Context) (value int8, err error) |
| 71 | ReadI16(ctx context.Context) (value int16, err error) |
| 72 | ReadI32(ctx context.Context) (value int32, err error) |
| 73 | ReadI64(ctx context.Context) (value int64, err error) |
| 74 | ReadDouble(ctx context.Context) (value float64, err error) |
| 75 | ReadString(ctx context.Context) (value string, err error) |
| 76 | ReadBinary(ctx context.Context) (value []byte, err error) |
| Yuxuan 'fishy' Wang | 19c13b4 | 2022-10-12 14:13:15 -0700 | [diff] [blame] | 77 | ReadUUID(ctx context.Context) (value Tuuid, err error) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 78 | |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 79 | Skip(ctx context.Context, fieldType TType) (err error) |
| John Boiles | 5785279 | 2018-01-05 14:37:05 -0800 | [diff] [blame] | 80 | Flush(ctx context.Context) (err error) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 81 | |
| 82 | Transport() TTransport |
| 83 | } |
| 84 | |
| 85 | // The maximum recursive depth the skip() function will traverse |
| Jens Geyer | 3ea26be | 2015-07-10 00:23:39 +0200 | [diff] [blame] | 86 | const DEFAULT_RECURSION_DEPTH = 64 |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 87 | |
| 88 | // Skips over the next data element from the provided input TProtocol object. |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 89 | func SkipDefaultDepth(ctx context.Context, prot TProtocol, typeId TType) (err error) { |
| 90 | return Skip(ctx, prot, typeId, DEFAULT_RECURSION_DEPTH) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 91 | } |
| 92 | |
| 93 | // Skips over the next data element from the provided input TProtocol object. |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 94 | func Skip(ctx context.Context, self TProtocol, fieldType TType, maxDepth int) (err error) { |
| D. Can Celasun | 8da0e72 | 2017-06-02 14:33:32 +0200 | [diff] [blame] | 95 | |
| 96 | if maxDepth <= 0 { |
| 97 | return NewTProtocolExceptionWithType(DEPTH_LIMIT, errors.New("Depth limit exceeded")) |
| Jens Geyer | 3ea26be | 2015-07-10 00:23:39 +0200 | [diff] [blame] | 98 | } |
| 99 | |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 100 | switch fieldType { |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 101 | case BOOL: |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 102 | _, err = self.ReadBool(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 103 | return |
| 104 | case BYTE: |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 105 | _, err = self.ReadByte(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 106 | return |
| 107 | case I16: |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 108 | _, err = self.ReadI16(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 109 | return |
| 110 | case I32: |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 111 | _, err = self.ReadI32(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 112 | return |
| 113 | case I64: |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 114 | _, err = self.ReadI64(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 115 | return |
| 116 | case DOUBLE: |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 117 | _, err = self.ReadDouble(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 118 | return |
| 119 | case STRING: |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 120 | _, err = self.ReadString(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 121 | return |
| Yuxuan 'fishy' Wang | 19c13b4 | 2022-10-12 14:13:15 -0700 | [diff] [blame] | 122 | case UUID: |
| 123 | _, err = self.ReadUUID(ctx) |
| 124 | return |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 125 | case STRUCT: |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 126 | if _, err = self.ReadStructBegin(ctx); err != nil { |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 127 | return err |
| 128 | } |
| 129 | for { |
| Philippe Antoine | 62beb67 | 2021-03-15 09:26:39 +0100 | [diff] [blame] | 130 | _, typeId, _, err := self.ReadFieldBegin(ctx) |
| 131 | if err != nil { |
| 132 | return err |
| 133 | } |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 134 | if typeId == STOP { |
| 135 | break |
| 136 | } |
| Philippe Antoine | 62beb67 | 2021-03-15 09:26:39 +0100 | [diff] [blame] | 137 | err = Skip(ctx, self, typeId, maxDepth-1) |
| Jens Geyer | 3ea26be | 2015-07-10 00:23:39 +0200 | [diff] [blame] | 138 | if err != nil { |
| 139 | return err |
| 140 | } |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 141 | self.ReadFieldEnd(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 142 | } |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 143 | return self.ReadStructEnd(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 144 | case MAP: |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 145 | keyType, valueType, size, err := self.ReadMapBegin(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 146 | if err != nil { |
| 147 | return err |
| 148 | } |
| Yuxuan 'fishy' Wang | 91565d4 | 2024-08-14 09:01:15 -0700 | [diff] [blame] | 149 | for range size { |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 150 | err := Skip(ctx, self, keyType, maxDepth-1) |
| Jens Geyer | 3ea26be | 2015-07-10 00:23:39 +0200 | [diff] [blame] | 151 | if err != nil { |
| 152 | return err |
| 153 | } |
| 郑桐 | 0f76053 | 2021-10-09 16:01:28 +0800 | [diff] [blame] | 154 | |
| 155 | err = Skip(ctx, self, valueType, maxDepth-1) |
| 156 | if err != nil { |
| 157 | return err |
| 158 | } |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 159 | } |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 160 | return self.ReadMapEnd(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 161 | case SET: |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 162 | elemType, size, err := self.ReadSetBegin(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 163 | if err != nil { |
| 164 | return err |
| 165 | } |
| Yuxuan 'fishy' Wang | 91565d4 | 2024-08-14 09:01:15 -0700 | [diff] [blame] | 166 | for range size { |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 167 | err := Skip(ctx, self, elemType, maxDepth-1) |
| Jens Geyer | 3ea26be | 2015-07-10 00:23:39 +0200 | [diff] [blame] | 168 | if err != nil { |
| 169 | return err |
| 170 | } |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 171 | } |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 172 | return self.ReadSetEnd(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 173 | case LIST: |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 174 | elemType, size, err := self.ReadListBegin(ctx) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 175 | if err != nil { |
| 176 | return err |
| 177 | } |
| Yuxuan 'fishy' Wang | 91565d4 | 2024-08-14 09:01:15 -0700 | [diff] [blame] | 178 | for range size { |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 179 | err := Skip(ctx, self, elemType, maxDepth-1) |
| Jens Geyer | 3ea26be | 2015-07-10 00:23:39 +0200 | [diff] [blame] | 180 | if err != nil { |
| 181 | return err |
| 182 | } |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 183 | } |
| Yuxuan 'fishy' Wang | e79f764 | 2020-06-12 22:22:35 -0700 | [diff] [blame] | 184 | return self.ReadListEnd(ctx) |
| Jens Geyer | 5f723cd | 2017-01-10 21:57:48 +0100 | [diff] [blame] | 185 | default: |
| Yuxuan 'fishy' Wang | 17373a3 | 2021-08-26 11:04:27 -0700 | [diff] [blame] | 186 | return NewTProtocolExceptionWithType(INVALID_DATA, fmt.Errorf("Unknown data type %d", fieldType)) |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 187 | } |
| Jens Geyer | 0e87c46 | 2013-06-18 22:25:07 +0200 | [diff] [blame] | 188 | } |