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

« back to all changes in this revision

Viewing changes to src/css-url.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
/* Collect URLs from CSS source.
 
2
   Copyright (C) 1998, 2000, 2001, 2002, 2003, 2009 Free Software
 
3
   Foundation, Inc.
 
4
 
 
5
This file is part of GNU Wget.
 
6
 
 
7
GNU Wget is free software; you can redistribute it and/or modify
 
8
it under the terms of the GNU General Public License as published by
 
9
the Free Software Foundation; either version 3 of the License, or (at
 
10
your option) any later version.
 
11
 
 
12
GNU Wget is distributed in the hope that it will be useful,
 
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
GNU General Public License for more details.
 
16
 
 
17
You should have received a copy of the GNU General Public License
 
18
along with Wget.  If not, see <http://www.gnu.org/licenses/>.
 
19
 
 
20
Additional permission under GNU GPL version 3 section 7
 
21
 
 
22
If you modify this program, or any covered work, by linking or
 
23
combining it with the OpenSSL project's OpenSSL library (or a
 
24
modified version of that library), containing parts covered by the
 
25
terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
 
26
grants you additional permission to convey the resulting work.
 
27
Corresponding Source for a non-source form of such a combination
 
28
shall include the source code for the parts of OpenSSL used as well
 
29
as that of the covered work.  */
 
30
 
 
31
/*
 
32
  Note that this is not an actual CSS parser, but just a lexical
 
33
  scanner with a tiny bit more smarts bolted on top.  A full parser
 
34
  is somewhat overkill for this job.  The only things we're interested
 
35
  in are @import rules and url() tokens, so it's easy enough to
 
36
  grab those without truly understanding the input.  The only downside
 
37
  to this is that we might be coerced into downloading files that
 
38
  a browser would ignore.  That might merit some more investigation.
 
39
 */
 
40
 
 
41
#include <wget.h>
 
42
 
 
43
#include <stdio.h>
 
44
#ifdef HAVE_STRING_H
 
45
# include <string.h>
 
46
#else
 
47
# include <strings.h>
 
48
#endif
 
49
#include <stdlib.h>
 
50
#include <ctype.h>
 
51
#include <errno.h>
 
52
 
 
53
#include "wget.h"
 
54
#include "utils.h"
 
55
#include "convert.h"
 
56
#include "html-url.h"
 
57
#include "css-tokens.h"
 
58
 
 
59
/* from lex.yy.c */
 
60
extern char *yytext;
 
61
extern int yyleng;
 
62
typedef struct yy_buffer_state *YY_BUFFER_STATE;
 
63
extern YY_BUFFER_STATE yy_scan_bytes (const char *bytes,int len  );
 
64
extern int yylex (void);
 
65
 
 
66
#if 1
 
67
const char *token_names[] = {
 
68
  "CSSEOF",
 
69
  "S",
 
70
  "CDO",
 
71
  "CDC",
 
72
  "INCLUDES",
 
73
  "DASHMATCH",
 
74
  "LBRACE",
 
75
  "PLUS",
 
76
  "GREATER",
 
77
  "COMMA",
 
78
  "STRING",
 
79
  "INVALID",
 
80
  "IDENT",
 
81
  "HASH",
 
82
  "IMPORT_SYM",
 
83
  "PAGE_SYM",
 
84
  "MEDIA_SYM",
 
85
  "CHARSET_SYM",
 
86
  "IMPORTANT_SYM",
 
87
  "EMS",
 
88
  "EXS",
 
89
  "LENGTH",
 
90
  "ANGLE",
 
91
  "TIME",
 
92
  "FREQ",
 
93
  "DIMENSION",
 
94
  "PERCENTAGE",
 
95
  "NUMBER",
 
96
  "URI",
 
97
  "FUNCTION"
 
98
};
 
99
#endif
 
100
 
 
101
/*
 
102
  Given a detected URI token, get only the URI specified within.
 
103
  Also adjust the starting position and length of the string.
 
104
 
 
105
  A URI can be specified with or without quotes, and the quotes
 
106
  can be single or double quotes.  In addition there can be
 
107
  whitespace after the opening parenthesis and before the closing
 
108
  parenthesis.
 
109
*/
 
110
char *
 
111
get_uri_string (const char *at, int *pos, int *length)
 
112
{
 
113
  char *uri;
 
114
  /*char buf[1024];
 
115
  strncpy(buf,at + *pos, *length);
 
116
  buf[*length] = '\0';
 
117
  DEBUGP (("get_uri_string: \"%s\"\n", buf));*/
 
118
 
 
119
  if (0 != strncasecmp (at + *pos, "url(", 4))
 
120
    return NULL;
 
121
 
 
122
  *pos += 4;
 
123
  *length -= 5; /* url() */
 
124
  /* skip leading space */
 
125
  while (isspace (at[*pos]))
 
126
    {
 
127
    (*pos)++;
 
128
    (*length)--;
 
129
    }
 
130
  /* skip trailing space */
 
131
  while (isspace (at[*pos + *length - 1]))
 
132
    {
 
133
      (*length)--;
 
134
    }
 
135
  /* trim off quotes */
 
136
  if (at[*pos] == '\'' || at[*pos] == '"')
 
137
    {
 
138
      (*pos)++;
 
139
      *length -= 2;
 
140
    }
 
141
 
 
142
  uri = xmalloc (*length + 1);
 
143
  if (uri)
 
144
    {
 
145
      strncpy (uri, at + *pos, *length);
 
146
      uri[*length] = '\0';
 
147
    }
 
148
 
 
149
  return uri;
 
150
}
 
151
 
 
152
void
 
153
get_urls_css (struct map_context *ctx, int offset, int buf_length)
 
154
{
 
155
  int token;
 
156
  /*char tmp[2048];*/
 
157
  int buffer_pos = 0;
 
158
  int pos, length;
 
159
  char *uri;
 
160
 
 
161
  /*
 
162
  strncpy(tmp,ctx->text + offset, buf_length);
 
163
  tmp[buf_length] = '\0';
 
164
  DEBUGP (("get_urls_css: \"%s\"\n", tmp));
 
165
  */
 
166
 
 
167
  /* tell flex to scan from this buffer */
 
168
  yy_scan_bytes (ctx->text + offset, buf_length);
 
169
 
 
170
  while((token = yylex()) != CSSEOF)
 
171
    {
 
172
      /*DEBUGP (("%s ", token_names[token]));*/
 
173
      /* @import "foo.css"
 
174
         or @import url(foo.css)
 
175
      */
 
176
      if(token == IMPORT_SYM)
 
177
        {
 
178
          do {
 
179
            buffer_pos += yyleng;
 
180
          } while((token = yylex()) == S);
 
181
 
 
182
          /*DEBUGP (("%s ", token_names[token]));*/
 
183
 
 
184
          if (token == STRING || token == URI)
 
185
            {
 
186
              /*DEBUGP (("Got URI "));*/
 
187
              pos = buffer_pos + offset;
 
188
              length = yyleng;
 
189
 
 
190
              if (token == URI)
 
191
                {
 
192
                  uri = get_uri_string (ctx->text, &pos, &length);
 
193
                }
 
194
              else
 
195
                {
 
196
                  /* cut out quote characters */
 
197
                  pos++;
 
198
                  length -= 2;
 
199
                  uri = xmalloc (length + 1);
 
200
                  strncpy (uri, yytext + 1, length);
 
201
                  uri[length] = '\0';
 
202
                }
 
203
 
 
204
              if (uri)
 
205
                {
 
206
                  struct urlpos *up = append_url (uri, pos, length, ctx);
 
207
                  DEBUGP (("Found @import: [%s] at %d [%s]\n", yytext, buffer_pos, uri));
 
208
 
 
209
                  if (up)
 
210
                    {
 
211
                      up->link_inline_p = 1;
 
212
                      up->link_css_p = 1;
 
213
                      up->link_expect_css = 1;
 
214
                    }
 
215
 
 
216
                  xfree(uri);
 
217
                }
 
218
            }
 
219
        }
 
220
      /* background-image: url(foo.png)
 
221
         note that we don't care what
 
222
         property this is actually on.
 
223
      */
 
224
      else if(token == URI)
 
225
        {
 
226
          pos = buffer_pos + offset;
 
227
          length = yyleng;
 
228
          uri = get_uri_string (ctx->text, &pos, &length);
 
229
 
 
230
          if (uri)
 
231
            {
 
232
              struct urlpos *up = append_url (uri, pos, length, ctx);
 
233
              DEBUGP (("Found URI: [%s] at %d [%s]\n", yytext, buffer_pos, uri));
 
234
              if (up)
 
235
                {
 
236
                  up->link_inline_p = 1;
 
237
                  up->link_css_p = 1;
 
238
                }
 
239
 
 
240
              xfree (uri);
 
241
            }
 
242
        }
 
243
      buffer_pos += yyleng;
 
244
    }
 
245
  DEBUGP (("\n"));
 
246
}
 
247
 
 
248
struct urlpos *
 
249
get_urls_css_file (const char *file, const char *url)
 
250
{
 
251
  struct file_memory *fm;
 
252
  struct map_context ctx;
 
253
 
 
254
  /* Load the file. */
 
255
  fm = read_file (file);
 
256
  if (!fm)
 
257
    {
 
258
      logprintf (LOG_NOTQUIET, "%s: %s\n", file, strerror (errno));
 
259
      return NULL;
 
260
    }
 
261
  DEBUGP (("Loaded %s (size %s).\n", file, number_to_static_string (fm->length)));
 
262
 
 
263
  ctx.text = fm->content;
 
264
  ctx.head = ctx.tail = NULL;
 
265
  ctx.base = NULL;
 
266
  ctx.parent_base = url ? url : opt.base_href;
 
267
  ctx.document_file = file;
 
268
  ctx.nofollow = 0;
 
269
 
 
270
  get_urls_css (&ctx, 0, fm->length);
 
271
  read_file_free (fm);
 
272
  return ctx.head;
 
273
}