Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [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 | |
| 22 | import ( |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 23 | "context" |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 24 | "errors" |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 25 | "fmt" |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 26 | ) |
| 27 | |
| 28 | const ( |
| 29 | VERSION_MASK = 0xffff0000 |
| 30 | VERSION_1 = 0x80010000 |
| 31 | ) |
| 32 | |
| 33 | type TProtocol interface { |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [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 |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 55 | |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 56 | ReadMessageBegin(ctx context.Context) (name string, typeId TMessageType, seqid int32, err error) |
| 57 | ReadMessageEnd(ctx context.Context) error |
| 58 | ReadStructBegin(ctx context.Context) (name string, err error) |
| 59 | ReadStructEnd(ctx context.Context) error |
| 60 | ReadFieldBegin(ctx context.Context) (name string, typeId TType, id int16, err error) |
| 61 | ReadFieldEnd(ctx context.Context) error |
| 62 | ReadMapBegin(ctx context.Context) (keyType TType, valueType TType, size int, err error) |
| 63 | ReadMapEnd(ctx context.Context) error |
| 64 | ReadListBegin(ctx context.Context) (elemType TType, size int, err error) |
| 65 | ReadListEnd(ctx context.Context) error |
| 66 | ReadSetBegin(ctx context.Context) (elemType TType, size int, err error) |
| 67 | ReadSetEnd(ctx context.Context) error |
| 68 | ReadBool(ctx context.Context) (value bool, err error) |
| 69 | ReadByte(ctx context.Context) (value int8, err error) |
| 70 | ReadI16(ctx context.Context) (value int16, err error) |
| 71 | ReadI32(ctx context.Context) (value int32, err error) |
| 72 | ReadI64(ctx context.Context) (value int64, err error) |
| 73 | ReadDouble(ctx context.Context) (value float64, err error) |
| 74 | ReadString(ctx context.Context) (value string, err error) |
| 75 | ReadBinary(ctx context.Context) (value []byte, err error) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 76 | |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 77 | Skip(ctx context.Context, fieldType TType) (err error) |
| 78 | Flush(ctx context.Context) (err error) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 79 | |
| 80 | Transport() TTransport |
| 81 | } |
| 82 | |
| 83 | // The maximum recursive depth the skip() function will traverse |
| 84 | const DEFAULT_RECURSION_DEPTH = 64 |
| 85 | |
| 86 | // Skips over the next data element from the provided input TProtocol object. |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 87 | func SkipDefaultDepth(ctx context.Context, prot TProtocol, typeId TType) (err error) { |
| 88 | return Skip(ctx, prot, typeId, DEFAULT_RECURSION_DEPTH) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 89 | } |
| 90 | |
| 91 | // Skips over the next data element from the provided input TProtocol object. |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 92 | func Skip(ctx context.Context, self TProtocol, fieldType TType, maxDepth int) (err error) { |
| 93 | |
| 94 | if maxDepth <= 0 { |
| 95 | return NewTProtocolExceptionWithType(DEPTH_LIMIT, errors.New("Depth limit exceeded")) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 96 | } |
| 97 | |
| 98 | switch fieldType { |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 99 | case BOOL: |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 100 | _, err = self.ReadBool(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 101 | return |
| 102 | case BYTE: |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 103 | _, err = self.ReadByte(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 104 | return |
| 105 | case I16: |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 106 | _, err = self.ReadI16(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 107 | return |
| 108 | case I32: |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 109 | _, err = self.ReadI32(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 110 | return |
| 111 | case I64: |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 112 | _, err = self.ReadI64(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 113 | return |
| 114 | case DOUBLE: |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 115 | _, err = self.ReadDouble(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 116 | return |
| 117 | case STRING: |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 118 | _, err = self.ReadString(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 119 | return |
| 120 | case STRUCT: |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 121 | if _, err = self.ReadStructBegin(ctx); err != nil { |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 122 | return err |
| 123 | } |
| 124 | for { |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 125 | _, typeId, _, _ := self.ReadFieldBegin(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 126 | if typeId == STOP { |
| 127 | break |
| 128 | } |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 129 | err := Skip(ctx, self, typeId, maxDepth-1) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 130 | if err != nil { |
| 131 | return err |
| 132 | } |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 133 | self.ReadFieldEnd(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 134 | } |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 135 | return self.ReadStructEnd(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 136 | case MAP: |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 137 | keyType, valueType, size, err := self.ReadMapBegin(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 138 | if err != nil { |
| 139 | return err |
| 140 | } |
| 141 | for i := 0; i < size; i++ { |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 142 | err := Skip(ctx, self, keyType, maxDepth-1) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 143 | if err != nil { |
| 144 | return err |
| 145 | } |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 146 | self.Skip(ctx, valueType) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 147 | } |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 148 | return self.ReadMapEnd(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 149 | case SET: |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 150 | elemType, size, err := self.ReadSetBegin(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 151 | if err != nil { |
| 152 | return err |
| 153 | } |
| 154 | for i := 0; i < size; i++ { |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 155 | err := Skip(ctx, self, elemType, maxDepth-1) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 156 | if err != nil { |
| 157 | return err |
| 158 | } |
| 159 | } |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 160 | return self.ReadSetEnd(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 161 | case LIST: |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 162 | elemType, size, err := self.ReadListBegin(ctx) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 163 | if err != nil { |
| 164 | return err |
| 165 | } |
| 166 | for i := 0; i < size; i++ { |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 167 | err := Skip(ctx, self, elemType, maxDepth-1) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 168 | if err != nil { |
| 169 | return err |
| 170 | } |
| 171 | } |
David K. Bainbridge | e05cf0c | 2021-08-19 03:16:50 +0000 | [diff] [blame^] | 172 | return self.ReadListEnd(ctx) |
| 173 | default: |
| 174 | return NewTProtocolExceptionWithType(INVALID_DATA, errors.New(fmt.Sprintf("Unknown data type %d", fieldType))) |
Rohan Agrawal | c32d993 | 2020-06-15 11:01:47 +0000 | [diff] [blame] | 175 | } |
| 176 | return nil |
| 177 | } |