| 149 | } |
| 150 | |
| 151 | static rem_fmt* parse_format(const UCHAR*& blr, size_t& blr_length) |
| 152 | { |
| 153 | if (blr_length < 2) |
| 154 | return NULL; |
| 155 | blr_length -= 2; |
| 156 | |
| 157 | USHORT count = *blr++; |
| 158 | count += (*blr++) << 8; |
| 159 | |
| 160 | AutoPtr<rem_fmt> format(FB_NEW rem_fmt(count)); |
| 161 | |
| 162 | ULONG net_length = 0; |
| 163 | ULONG offset = 0; |
| 164 | dsc* const begin = format->fmt_desc.begin(); |
| 165 | |
| 166 | for (dsc* desc = begin; count; --count, ++desc) |
| 167 | { |
| 168 | if (blr_length-- == 0) |
| 169 | return NULL; |
| 170 | |
| 171 | USHORT align = 4; |
| 172 | switch (*blr++) |
| 173 | { |
| 174 | case blr_text: |
| 175 | if (blr_length < 2) |
| 176 | return NULL; |
| 177 | blr_length -= 2; |
| 178 | desc->dsc_dtype = dtype_text; |
| 179 | desc->dsc_length = *blr++; |
| 180 | desc->dsc_length += (*blr++) << 8; |
| 181 | break; |
| 182 | |
| 183 | case blr_varying: |
| 184 | if (blr_length < 2) |
| 185 | return NULL; |
| 186 | blr_length -= 2; |
| 187 | desc->dsc_dtype = dtype_varying; |
| 188 | desc->dsc_length = *blr++ + sizeof(SSHORT); |
| 189 | desc->dsc_length += (*blr++) << 8; |
| 190 | break; |
| 191 | |
| 192 | case blr_cstring: |
| 193 | if (blr_length < 2) |
| 194 | return NULL; |
| 195 | blr_length -= 2; |
| 196 | desc->dsc_dtype = dtype_cstring; |
| 197 | desc->dsc_length = *blr++; |
| 198 | desc->dsc_length += (*blr++) << 8; |
| 199 | break; |
| 200 | |
| 201 | // Parse the tagged blr types correctly |
| 202 | |
| 203 | case blr_text2: |
| 204 | if (blr_length < 4) |
| 205 | return NULL; |
| 206 | blr_length -= 4; |
| 207 | desc->dsc_dtype = dtype_text; |
| 208 | desc->dsc_scale = *blr++; |
no test coverage detected