Text   |  XML   |  ReML   |   Visible Warnings:

Null Test After Dereference  at message-header-parser.c:368

No properties have been set. | edit properties
Jump to warning location ↓ warning details...
Show Events | Options

message_parse_header_next

(/home/sate/Testcases/c/cve/dovecot-1.2.0/src/lib-mail/message-header-parser.c)expand/collapse
Show more  
 55  int message_parse_header_next(struct message_header_parser_ctx *ctx,
 56                                struct message_header_line **hdr_r)
 57  {
 58          struct message_header_line *line = &ctx->line;
 59          const unsigned char *msg;
 60          size_t i, size, startpos, colon_pos, parse_size, value_pos;
 61          int ret;
 62          bool continued, continues, last_no_newline, last_crlf;
 63          bool no_newline, crlf_newline;
 64   
 65          *hdr_r = NULL;
 66          if (line->eoh)
 67                  return -1;
 68   
 69          if (ctx->skip > 0) {
 70                  i_stream_skip(ctx->input, ctx->skip);
 71                  ctx->skip = 0;
 72          }
 73   
 74          if (line->continues)
 75                  colon_pos = 0;
 76          else {
 77                  /* new header line */
 78                  line->name_offset = ctx->input->v_offset;
 79                  colon_pos = UINT_MAX;
 80                  buffer_set_used_size(ctx->value_buf, 0);
 81          }
 82   
 83          no_newline = FALSE;
 84          crlf_newline = FALSE;
 85          continued = line->continues;
 86          continues = FALSE;
 87   
 88          for (startpos = 0;;) {
 89                  ret = i_stream_read_data(ctx->input, &msg, &size, startpos+1);
 90                  if (ret >= 0) {
 91                          /* we want to know one byte in advance to find out 
 92                             if it's multiline header */
 93                          parse_size = size == 0 ? 0 : size-1;
 94                  } else {
 95                          parse_size = size;
 96                  }
 97   
 98                  if (ret <= 0 && startpos == parse_size) {
 99                          if (ret == -1) {
 100                                  if (startpos > 0) {
 101                                          /* header ended unexpectedly. */
 102                                          no_newline = TRUE;
 103                                          ctx->skip = startpos;
 104                                          break;
 105                                  }
 106                                  /* error / EOF with no bytes */
 107                                  return -1;
 108                          }
 109   
 110                          if (size > 0 &&
 111                              (msg[0] == '\n' ||
 112                               (msg[0] == '\r' && size > 1 && msg[1] == '\n'))) {
 113                                  /* end of headers - this mostly happens just
 114                                     with mbox where headers are read separately
 115                                     from body */
 116                                  size = 0;
 117                                  if (ctx->hdr_size != NULL)
 118                                          ctx->hdr_size->lines++;
 119                                  if (msg[0] == '\r') {
 120                                          ctx->skip = 2;
 121                                          crlf_newline = TRUE;
 122                                  } else {
 123                                          ctx->skip = 1;
 124                                          if (ctx->hdr_size != NULL)
 125                                                  ctx->hdr_size->virtual_size++;
 126                                  }
 127                                  break;
 128                          }
 129                          if (ret == 0 && !ctx->input->eof) {
 130                                  /* stream is nonblocking - need more data */
 131                                  return 0;
 132                          }
 133                          i_assert(size > 0);
 134   
 135                          /* a) line is larger than input buffer
 136                             b) header ended unexpectedly */
 137                          if (colon_pos == UINT_MAX && ret == -2 && !continued) {
 138                                  /* header name is huge. just skip it. */
 139                                  if (msg[size-1] == '\r')
 140                                          size--;
 141   
 142                                  if (ctx->hdr_size != NULL) {
 143                                          ctx->hdr_size->physical_size += size;
 144                                          ctx->hdr_size->virtual_size += size;
 145                                  }
 146                                  i_stream_skip(ctx->input, size);
 147                                  ctx->skip_line = TRUE;
 148                                  startpos = 0;
 149                                  continue;
 150                          }
 151   
 152                          if (ret == -2) {
 153                                  /* go back to last LWSP if found. */
 154                                  size_t min_pos = !continued ? colon_pos : 0;
 155                                  for (i = size-1; i > min_pos; i--) {
 156                                          if (IS_LWSP(msg[i])) {
 157                                                  size = i;
 158                                                  break;
 159                                          }
 160                                  }
 161   
 162                                  continues = TRUE;
 163                          }
 164                          no_newline = TRUE;
 165                          ctx->skip = size;
 166                          break;
 167                  }
 168   
 169                  /* find ':' */
 170                  if (colon_pos == UINT_MAX) {
 171                          for (i = startpos; i < parse_size; i++) {
 172                                  if (msg[i] > ':')
 173                                          continue;
 174   
 175                                  if (msg[i] == ':') {
 176                                          colon_pos = i;
 177                                          line->full_value_offset =
 178                                                  ctx->input->v_offset + i + 1;
 179                                          break;
 180                                  }
 181                                  if (msg[i] == '\n') {
 182                                          /* end of headers, or error */
 183                                          break;
 184                                  }
 185   
 186                                  if (msg[i] == '\0')
 187                                          ctx->has_nuls = TRUE;
 188                          }
 189                  } else {
 190                          i = startpos;
 191                  }
 192   
 193                  /* find '\n' */
 194                  for (; i < parse_size; i++) {
 195                          if (msg[i] <= '\n') {
 196                                  if (msg[i] == '\n')
 197                                          break;
 198                                  if (msg[i] == '\0')
 199                                          ctx->has_nuls = TRUE;
 200                          }
 201                  }
 202   
 203                  if (i < parse_size) {
 204                          /* got a line */
 205                          if (ctx->skip_line) {
 206                                  /* skipping a huge line */
 207                                  if (ctx->hdr_size != NULL) {
 208                                          ctx->hdr_size->physical_size += i;
 209                                          ctx->hdr_size->virtual_size += i;
 210                                  }
 211   
 212                                  if (i == 0 || msg[i-1] != '\r') {
 213                                          /* missing CR */
 214                                          if (ctx->hdr_size != NULL)
 215                                                  ctx->hdr_size->virtual_size++;
 216                                  } else {
 217                                          crlf_newline = TRUE;
 218                                  }
 219                                  i_stream_skip(ctx->input, i);
 220                                  startpos = 0;
 221                                  ctx->skip_line = FALSE;
 222                                  continue;
 223                          }
 224                          continues = i+1 < size && IS_LWSP(msg[i+1]);
 225   
 226                          if (ctx->hdr_size != NULL)
 227                                  ctx->hdr_size->lines++;
 228                          if (i == 0 || msg[i-1] != '\r') {
 229                                  /* missing CR */
 230                                  if (ctx->hdr_size != NULL)
 231                                          ctx->hdr_size->virtual_size++;
 232                                  size = i;
 233                          } else {
 234                                  size = i-1;
 235                                  crlf_newline = TRUE;
 236                          }
 237   
 238                          ctx->skip = i+1;
 239                          break;
 240                  }
 241   
 242                  startpos = i;
 243          }
 244   
 245          last_crlf = line->crlf_newline &&
 246                  (ctx->flags & MESSAGE_HEADER_PARSER_FLAG_DROP_CR) == 0;
 247          last_no_newline = line->no_newline ||
 248                  (ctx->flags & MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE) != 0;
 249   
 250          line->continues = continues;
 251          line->continued = continued;
 252          line->crlf_newline = crlf_newline;
 253          line->no_newline = no_newline;
 254          if (size == 0) {
 255                  /* end of headers */
 256                  line->eoh = TRUE;
 257                  line->name_len = line->value_len = line->full_value_len = 0;
 258                  line->name = ""; line->value = line->full_value = NULL;
 259                  line->middle = NULL; line->middle_len = 0;
 260                  line->full_value_offset = line->name_offset;
 261                  line->continues = FALSE;
 262          } else if (line->continued) {
 263                  line->value = msg;
 264                  line->value_len = size;
 265          } else if (colon_pos == UINT_MAX) {
 266                  /* missing ':', assume the whole line is name */
 267                  line->value = NULL;
 268                  line->value_len = 0;
 269   
 270                  str_truncate(ctx->name, 0);
 271                  str_append_n(ctx->name, msg, size);
 272                  line->name = str_c(ctx->name);
 273                  line->name_len = str_len(ctx->name);
 274   
 275                  line->middle = NULL;
 276                  line->middle_len = 0;
 277          } else {
 278                  size_t pos;
 279   
 280                  line->value = msg + colon_pos+1;
 281                  line->value_len = size - colon_pos - 1;
 282                  if (ctx->flags & MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP) {
 283                          /* get value. skip all LWSP after ':'. Note that
 284                             RFC2822 doesn't say we should, but history behind 
 285                             it..
 286   
 287                             Exception to this is if the value consists only of 
 288                             LWSP, then skip only the one LWSP after ':'. */
 289                          for (pos = 0; pos < line->value_len; pos++) {
 290                                  if (!IS_LWSP(line->value[pos]))
 291                                          break;
 292                          }
 293   
 294                          if (pos == line->value_len) {
 295                                  /* everything was LWSP */
 296                                  if (line->value_len > 0 &&
 297                                      IS_LWSP(line->value[0]))
 298                                          pos = 1;
 299                          }
 300                  } else {
 301                          pos = line->value_len > 0 &&
 302                                  IS_LWSP(line->value[0]) ? 1 : 0;
 303                  }
 304   
 305                  line->value += pos;
 306                  line->value_len -= pos;
 307                  line->full_value_offset += pos;
 308   
 309                  /* get name, skip LWSP before ':' */
 310                  while (colon_pos > 0 && IS_LWSP(msg[colon_pos-1]))
 311                          colon_pos--;
 312   
 313                  str_truncate(ctx->name, 0);
 314                  str_append_n(ctx->name, msg, colon_pos);
 315                  str_append_c(ctx->name, '\0');
 316   
 317                  /* keep middle stored also in ctx->name so it's available 
 318                     with use_full_value */
 319                  line->middle = msg + colon_pos;
 320                  line->middle_len = (size_t)(line->value - line->middle);
 321                  str_append_n(ctx->name, line->middle, line->middle_len);
 322   
 323                  line->name = str_c(ctx->name);
 324                  line->name_len = colon_pos;
 325                  line->middle = str_data(ctx->name) + line->name_len + 1;
 326          }
 327   
 328          if (!line->continued) {
 329                  /* first header line. make a copy of the line since we can't
 330                     really trust input stream not to lose it. */
 331                  buffer_append(ctx->value_buf, line->value, line->value_len);
 332                  line->value = line->full_value = ctx->value_buf->data;
 333                  line->full_value_len = line->value_len;
 334          } else if (line->use_full_value) {
 335                  /* continue saving the full value. */
 336                  if (last_no_newline) {
 337                          /* line is longer than fit into our buffer, so we
 338                             were forced to break it into multiple
 339                             message_header_lines */
 340                  } else {
 341                          if (last_crlf)
 342                                  buffer_append_c(ctx->value_buf, '\r');
 343                          buffer_append_c(ctx->value_buf, '\n');
 344                  }
 345                  value_pos = ctx->value_buf->used;
 346                  if ((ctx->flags & MESSAGE_HEADER_PARSER_FLAG_CLEAN_ONELINE) &&
 347                      line->value_len > 0 && line->value[0] != ' ' &&
 348                      IS_LWSP(line->value[0])) {
 349                          buffer_append_c(ctx->value_buf, ' ');
 350                          buffer_append(ctx->value_buf,
 351                                        line->value + 1, line->value_len - 1);
 352                  } else {
 353                          buffer_append(ctx->value_buf,
 354                                        line->value, line->value_len);
 355                  }
 356                  line->full_value = buffer_get_data(ctx->value_buf,
 357                                                     &line->full_value_len);
 358                  line->value = line->full_value + value_pos;
 359          } else {
 360                  /* we didn't want full_value, and this is a continued line. */
 361                  line->full_value = NULL;
 362                  line->full_value_len = 0;
 363          }
 364   
 365          /* always reset it */
 366          line->use_full_value = FALSE;
 367   
 368          if (ctx->hdr_size != NULL) {
 369                  ctx->hdr_size->physical_size += ctx->skip;
 370                  ctx->hdr_size->virtual_size += ctx->skip;
 371          }
 372   
 373          *hdr_r = line;
 374          return 1;
 375  }
Show more  




Change Warning 12129.24590 : Null Test After Dereference

Priority:
State:
Finding:
Owner:
Note: