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 org.apache.thrift.protocol; 21 22 import org.apache.thrift.TException; 23 24 /** 25 * Utility class with static methods for interacting with protocol data 26 * streams. 27 * 28 */ 29 public class TProtocolUtil { 30 31 /** 32 * The maximum recursive depth the skip() function will traverse before 33 * throwing a TException. 34 */ 35 private static int maxSkipDepth = Integer.MAX_VALUE; 36 37 /** 38 * Specifies the maximum recursive depth that the skip function will 39 * traverse before throwing a TException. This is a global setting, so 40 * any call to skip in this JVM will enforce this value. 41 * 42 * @param depth the maximum recursive depth. A value of 2 would allow 43 * the skip function to skip a structure or collection with basic children, 44 * but it would not permit skipping a struct that had a field containing 45 * a child struct. A value of 1 would only allow skipping of simple 46 * types and empty structs/collections. 47 */ setMaxSkipDepth(int depth)48 public static void setMaxSkipDepth(int depth) { 49 maxSkipDepth = depth; 50 } 51 52 /** 53 * Skips over the next data element from the provided input TProtocol object. 54 * 55 * @param prot the protocol object to read from 56 * @param type the next value will be intepreted as this TType value. 57 */ skip(TProtocol prot, byte type)58 public static void skip(TProtocol prot, byte type) 59 throws TException { 60 skip(prot, type, maxSkipDepth); 61 } 62 63 /** 64 * Skips over the next data element from the provided input TProtocol object. 65 * 66 * @param prot the protocol object to read from 67 * @param type the next value will be intepreted as this TType value. 68 * @param maxDepth this function will only skip complex objects to this 69 * recursive depth, to prevent Java stack overflow. 70 */ skip(TProtocol prot, byte type, int maxDepth)71 public static void skip(TProtocol prot, byte type, int maxDepth) 72 throws TException { 73 if (maxDepth <= 0) { 74 throw new TException("Maximum skip depth exceeded"); 75 } 76 switch (type) { 77 case TType.BOOL: 78 { 79 prot.readBool(); 80 break; 81 } 82 case TType.BYTE: 83 { 84 prot.readByte(); 85 break; 86 } 87 case TType.I16: 88 { 89 prot.readI16(); 90 break; 91 } 92 case TType.I32: 93 { 94 prot.readI32(); 95 break; 96 } 97 case TType.I64: 98 { 99 prot.readI64(); 100 break; 101 } 102 case TType.DOUBLE: 103 { 104 prot.readDouble(); 105 break; 106 } 107 case TType.STRING: 108 { 109 prot.readBinary(); 110 break; 111 } 112 case TType.STRUCT: 113 { 114 prot.readStructBegin(); 115 while (true) { 116 TField field = prot.readFieldBegin(); 117 if (field.type == TType.STOP) { 118 break; 119 } 120 skip(prot, field.type, maxDepth - 1); 121 prot.readFieldEnd(); 122 } 123 prot.readStructEnd(); 124 break; 125 } 126 case TType.MAP: 127 { 128 TMap map = prot.readMapBegin(); 129 for (int i = 0; i < map.size; i++) { 130 skip(prot, map.keyType, maxDepth - 1); 131 skip(prot, map.valueType, maxDepth - 1); 132 } 133 prot.readMapEnd(); 134 break; 135 } 136 case TType.SET: 137 { 138 TSet set = prot.readSetBegin(); 139 for (int i = 0; i < set.size; i++) { 140 skip(prot, set.elemType, maxDepth - 1); 141 } 142 prot.readSetEnd(); 143 break; 144 } 145 case TType.LIST: 146 { 147 TList list = prot.readListBegin(); 148 for (int i = 0; i < list.size; i++) { 149 skip(prot, list.elemType, maxDepth - 1); 150 } 151 prot.readListEnd(); 152 break; 153 } 154 default: 155 throw new TProtocolException(TProtocolException.INVALID_DATA, 156 "Unrecognized type " + type); 157 } 158 } 159 } 160