~ubuntu-branches/ubuntu/lucid/wget/lucid-security

« back to all changes in this revision

Viewing changes to lib/getdelim.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc Deslauriers
  • Date: 2009-12-12 08:15:59 UTC
  • mfrom: (2.1.5 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091212081559-mvccl4kzdqb138y3
Tags: 1.12-1.1ubuntu1
* Merge from debian testing, remaining changes:
  - Add wget-udeb to ship wget.gnu as alternative to busybox wget
    implementation.
* Keep build dependencies in main:
  - debian/control: remove info2man build-dep
  - debian/patches/00list: disable wget-infopod_generated_manpage.dpatch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* getdelim.c --- Implementation of replacement getdelim function.
 
2
   Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006, 2007,
 
3
   2008, 2009 Free Software Foundation, Inc.
 
4
 
 
5
   This program is free software; you can redistribute it and/or
 
6
   modify it under the terms of the GNU General Public License as
 
7
   published by the Free Software Foundation; either version 3, or (at
 
8
   your option) any later version.
 
9
 
 
10
   This program is distributed in the hope that it will be useful, but
 
11
   WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
   General Public License for more details.
 
14
 
 
15
   You should have received a copy of the GNU General Public License
 
16
   along with this program; if not, write to the Free Software
 
17
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
18
   02110-1301, USA.  */
 
19
 
 
20
/* Ported from glibc by Simon Josefsson. */
 
21
 
 
22
#include <config.h>
 
23
 
 
24
#include <stdio.h>
 
25
 
 
26
#include <limits.h>
 
27
#include <stdint.h>
 
28
#include <stdlib.h>
 
29
#include <errno.h>
 
30
 
 
31
#ifndef SSIZE_MAX
 
32
# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
 
33
#endif
 
34
 
 
35
#if USE_UNLOCKED_IO
 
36
# include "unlocked-io.h"
 
37
# define getc_maybe_unlocked(fp)        getc(fp)
 
38
#elif !HAVE_FLOCKFILE || !HAVE_FUNLOCKFILE || !HAVE_DECL_GETC_UNLOCKED
 
39
# undef flockfile
 
40
# undef funlockfile
 
41
# define flockfile(x) ((void) 0)
 
42
# define funlockfile(x) ((void) 0)
 
43
# define getc_maybe_unlocked(fp)        getc(fp)
 
44
#else
 
45
# define getc_maybe_unlocked(fp)        getc_unlocked(fp)
 
46
#endif
 
47
 
 
48
/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
 
49
   NUL-terminate it).  *LINEPTR is a pointer returned from malloc (or
 
50
   NULL), pointing to *N characters of space.  It is realloc'ed as
 
51
   necessary.  Returns the number of characters read (not including
 
52
   the null terminator), or -1 on error or EOF.  */
 
53
 
 
54
ssize_t
 
55
getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
 
56
{
 
57
  ssize_t result;
 
58
  size_t cur_len = 0;
 
59
 
 
60
  if (lineptr == NULL || n == NULL || fp == NULL)
 
61
    {
 
62
      errno = EINVAL;
 
63
      return -1;
 
64
    }
 
65
 
 
66
  flockfile (fp);
 
67
 
 
68
  if (*lineptr == NULL || *n == 0)
 
69
    {
 
70
      char *new_lineptr;
 
71
      *n = 120;
 
72
      new_lineptr = (char *) realloc (*lineptr, *n);
 
73
      if (new_lineptr == NULL)
 
74
        {
 
75
          result = -1;
 
76
          goto unlock_return;
 
77
        }
 
78
      *lineptr = new_lineptr;
 
79
    }
 
80
 
 
81
  for (;;)
 
82
    {
 
83
      int i;
 
84
 
 
85
      i = getc_maybe_unlocked (fp);
 
86
      if (i == EOF)
 
87
        {
 
88
          result = -1;
 
89
          break;
 
90
        }
 
91
 
 
92
      /* Make enough space for len+1 (for final NUL) bytes.  */
 
93
      if (cur_len + 1 >= *n)
 
94
        {
 
95
          size_t needed_max =
 
96
            SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
 
97
          size_t needed = 2 * *n + 1;   /* Be generous. */
 
98
          char *new_lineptr;
 
99
 
 
100
          if (needed_max < needed)
 
101
            needed = needed_max;
 
102
          if (cur_len + 1 >= needed)
 
103
            {
 
104
              result = -1;
 
105
              errno = EOVERFLOW;
 
106
              goto unlock_return;
 
107
            }
 
108
 
 
109
          new_lineptr = (char *) realloc (*lineptr, needed);
 
110
          if (new_lineptr == NULL)
 
111
            {
 
112
              result = -1;
 
113
              goto unlock_return;
 
114
            }
 
115
 
 
116
          *lineptr = new_lineptr;
 
117
          *n = needed;
 
118
        }
 
119
 
 
120
      (*lineptr)[cur_len] = i;
 
121
      cur_len++;
 
122
 
 
123
      if (i == delimiter)
 
124
        break;
 
125
    }
 
126
  (*lineptr)[cur_len] = '\0';
 
127
  result = cur_len ? cur_len : result;
 
128
 
 
129
 unlock_return:
 
130
  funlockfile (fp); /* doesn't set errno */
 
131
 
 
132
  return result;
 
133
}