]> sjero.net Git - wget/commitdiff
[svn] Added support for hexadecimal numeric entities.
authorhniksic <devnull@localhost>
Thu, 2 Oct 2003 17:23:25 +0000 (10:23 -0700)
committerhniksic <devnull@localhost>
Thu, 2 Oct 2003 17:23:25 +0000 (10:23 -0700)
src/ChangeLog
src/html-parse.c

index 9f403b6b6acd5ac25de827acbee6dcc1f93c85a6..b80659493bb9fca9148ec8cf61413f2bbd889ac8 100644 (file)
@@ -1,3 +1,10 @@
+2003-10-02  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * html-parse.c (convert_and_copy): Handle numeric entities in
+       hexadecimal, &#xHH.
+       (convert_and_copy): Copy the contents directly to the pool without
+       a stack-allocated intermediary.
+
 2003-10-02  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * utils.c (alarm_set): New function; use either setitimer or alarm
 2003-10-02  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * utils.c (alarm_set): New function; use either setitimer or alarm
index e454860b4506c72302e51ef60031fe8326a0ed66..86e4195ea5de6ddb63e575ff2562eafb72b930af 100644 (file)
@@ -46,10 +46,7 @@ so, delete this exception statement from your version.  */
    written some time during the Geturl 1.0 beta cycle, and was very
    inefficient and buggy.  It also contained some very complex code to
    remember a list of parser states, because it was supposed to be
    written some time during the Geturl 1.0 beta cycle, and was very
    inefficient and buggy.  It also contained some very complex code to
    remember a list of parser states, because it was supposed to be
-   reentrant.  The idea was that several parsers would be running
-   concurrently, and you'd have pass the function a unique ID string
-   (for example, the URL) by which it found the relevant parser state
-   and returned the next URL.  Over-engineering at its best.
+   reentrant.
 
    The second HTML parser was written for Wget 1.4 (the first version
    by the name `Wget'), and was a complete rewrite.  Although the new
 
    The second HTML parser was written for Wget 1.4 (the first version
    by the name `Wget'), and was a complete rewrite.  Although the new
@@ -110,15 +107,30 @@ so, delete this exception statement from your version.  */
 #include "html-parse.h"
 
 #ifdef STANDALONE
 #include "html-parse.h"
 
 #ifdef STANDALONE
+# undef xmalloc
+# undef xrealloc
+# undef xfree
 # define xmalloc malloc
 # define xrealloc realloc
 # define xfree free
 
 # define xmalloc malloc
 # define xrealloc realloc
 # define xfree free
 
+# undef ISSPACE
+# undef ISDIGIT
+# undef ISXDIGIT
+# undef ISALPHA
+# undef ISALNUM
+# undef TOLOWER
+# undef TOUPPER
+
 # define ISSPACE(x) isspace (x)
 # define ISDIGIT(x) isdigit (x)
 # define ISSPACE(x) isspace (x)
 # define ISDIGIT(x) isdigit (x)
+# define ISXDIGIT(x) isxdigit (x)
 # define ISALPHA(x) isalpha (x)
 # define ISALNUM(x) isalnum (x)
 # define TOLOWER(x) tolower (x)
 # define ISALPHA(x) isalpha (x)
 # define ISALNUM(x) isalnum (x)
 # define TOLOWER(x) tolower (x)
+# define TOUPPER(x) toupper (x)
+
+static struct options opt;
 #endif /* STANDALONE */
 
 /* Pool support.  A pool is a resizable chunk of memory.  It is first
 #endif /* STANDALONE */
 
 /* Pool support.  A pool is a resizable chunk of memory.  It is first
@@ -171,22 +183,20 @@ struct pool {
    is done.  */
 
 #define POOL_APPEND(pool, beg, end) do {                       \
    is done.  */
 
 #define POOL_APPEND(pool, beg, end) do {                       \
-  const char *PA_beg = beg;                                    \
-  int PA_size = end - PA_beg;                                  \
+  const char *PA_beg = (beg);                                  \
+  int PA_size = (end) - PA_beg;                                        \
   POOL_GROW (pool, PA_size);                                   \
   memcpy ((pool).contents + (pool).index, PA_beg, PA_size);    \
   (pool).index += PA_size;                                     \
 } while (0)
 
   POOL_GROW (pool, PA_size);                                   \
   memcpy ((pool).contents + (pool).index, PA_beg, PA_size);    \
   (pool).index += PA_size;                                     \
 } while (0)
 
-/* The same as the above, but with zero termination. */
+/* Append one character to the pool.  Can be used to zero-terminate
+   pool strings.  */
 
 
-#define POOL_APPEND_ZT(pool, beg, end) do {                    \
-  const char *PA_beg = beg;                                    \
-  int PA_size = end - PA_beg;                                  \
-  POOL_GROW (pool, PA_size + 1);                               \
-  memcpy ((pool).contents + (pool).index, PA_beg, PA_size);    \
-  (pool).contents[(pool).index + PA_size] = '\0';              \
-  (pool).index += PA_size + 1;                                 \
+#define POOL_APPEND_CHR(pool, ch) do {         \
+  char PAC_char = (ch);                                \
+  POOL_GROW (pool, 1);                         \
+  (pool).contents[(pool).index++] = PAC_char;  \
 } while (0)
 
 /* Forget old pool contents.  The allocated memory is not freed. */
 } while (0)
 
 /* Forget old pool contents.  The allocated memory is not freed. */
@@ -210,11 +220,11 @@ struct pool {
 \f
 #define AP_DOWNCASE            1
 #define AP_PROCESS_ENTITIES    2
 \f
 #define AP_DOWNCASE            1
 #define AP_PROCESS_ENTITIES    2
-#define AP_SKIP_BLANKS         4
+#define AP_TRIM_BLANKS         4
 
 /* Copy the text in the range [BEG, END) to POOL, optionally
    performing operations specified by FLAGS.  FLAGS may be any
 
 /* Copy the text in the range [BEG, END) to POOL, optionally
    performing operations specified by FLAGS.  FLAGS may be any
-   combination of AP_DOWNCASE, AP_PROCESS_ENTITIES and AP_SKIP_BLANKS
+   combination of AP_DOWNCASE, AP_PROCESS_ENTITIES and AP_TRIM_BLANKS
    with the following meaning:
 
    * AP_DOWNCASE -- downcase all the letters;
    with the following meaning:
 
    * AP_DOWNCASE -- downcase all the letters;
@@ -223,8 +233,9 @@ struct pool {
    the decoded string.  Recognized entities are &lt, &gt, &amp, &quot,
    &nbsp and the numerical entities.
 
    the decoded string.  Recognized entities are &lt, &gt, &amp, &quot,
    &nbsp and the numerical entities.
 
-   * AP_SKIP_BLANKS -- ignore blanks at the beginning and at the end
+   * AP_TRIM_BLANKS -- ignore blanks at the beginning and at the end
    of text.  */
    of text.  */
+
 static void
 convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags)
 {
 static void
 convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags)
 {
@@ -234,7 +245,7 @@ convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags
   /* First, skip blanks if required.  We must do this before entities
      are processed, so that blanks can still be inserted as, for
      instance, `&#32;'.  */
   /* First, skip blanks if required.  We must do this before entities
      are processed, so that blanks can still be inserted as, for
      instance, `&#32;'.  */
-  if (flags & AP_SKIP_BLANKS)
+  if (flags & AP_TRIM_BLANKS)
     {
       while (beg < end && ISSPACE (*beg))
        ++beg;
     {
       while (beg < end && ISSPACE (*beg))
        ++beg;
@@ -245,11 +256,16 @@ convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags
 
   if (flags & AP_PROCESS_ENTITIES)
     {
 
   if (flags & AP_PROCESS_ENTITIES)
     {
-      /* Stack-allocate a copy of text, process entities and copy it
-         to the pool.  */
-      char *local_copy = (char *)alloca (size + 1);
+      /* Grow the pool, then copy the text to the pool character by
+        character, processing the encountered entities as we go
+        along.
+
+        It's safe (and necessary) to grow the pool in advance because
+        processing the entities can only *shorten* the string, it can
+        never lengthen it.  */
+      POOL_GROW (*pool, end - beg);
       const char *from = beg;
       const char *from = beg;
-      char *to = local_copy;
+      char *to = pool->contents + pool->index;
 
       while (from < end)
        {
 
       while (from < end)
        {
@@ -260,22 +276,33 @@ convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags
              const char *save = from;
              int remain;
 
              const char *save = from;
              int remain;
 
-             if (++from == end) goto lose;
+             if (++from == end)
+               goto lose;
              remain = end - from;
 
              remain = end - from;
 
+             /* Process numeric entities "&#DDD;" and "&#xHH;".  */
              if (*from == '#')
                {
              if (*from == '#')
                {
-                 int numeric;
+                 int numeric = 0, digits = 0;
                  ++from;
                  ++from;
-                 if (from == end || !ISDIGIT (*from)) goto lose;
-                 for (numeric = 0; from < end && ISDIGIT (*from); from++)
-                   numeric = 10 * numeric + (*from) - '0';
-                 if (from < end && ISALPHA (*from)) goto lose;
+                 if (*from == 'x')
+                   {
+                     ++from;
+                     for (; from < end && ISXDIGIT (*from); from++, digits++)
+                       numeric = (numeric << 4) + XDIGIT_TO_NUM (*from);
+                   }
+                 else
+                   {
+                     for (; from < end && ISDIGIT (*from); from++, digits++)
+                       numeric = (numeric * 10) + (*from - '0');
+                   }
+                 if (!digits)
+                   goto lose;
                  numeric &= 0xff;
                  *to++ = numeric;
                }
 #define FROB(x) (remain >= (sizeof (x) - 1)                    \
                  numeric &= 0xff;
                  *to++ = numeric;
                }
 #define FROB(x) (remain >= (sizeof (x) - 1)                    \
-                && !memcmp (from, x, sizeof (x) - 1)           \
+                && 0 == memcmp (from, x, sizeof (x) - 1)       \
                 && (*(from + sizeof (x) - 1) == ';'            \
                     || remain == sizeof (x) - 1                \
                     || !ISALNUM (*(from + sizeof (x) - 1))))
                 && (*(from + sizeof (x) - 1) == ';'            \
                     || remain == sizeof (x) - 1                \
                     || !ISALNUM (*(from + sizeof (x) - 1))))
@@ -309,13 +336,20 @@ convert_and_copy (struct pool *pool, const char *beg, const char *end, int flags
              *to++ = *from++;
            }
        }
              *to++ = *from++;
            }
        }
-      *to++ = '\0';
-      POOL_APPEND (*pool, local_copy, to);
+      /* Verify that we haven't exceeded the original size.  (It
+        shouldn't happen, hence the assert.)  */
+      assert (to - (pool->contents + pool->index) <= end - beg);
+
+      /* Make POOL's tail point to the position following the string
+        we've written.  */
+      pool->index = to - pool->contents;
+      POOL_APPEND_CHR (*pool, '\0');
     }
   else
     {
       /* Just copy the text to the pool.  */
     }
   else
     {
       /* Just copy the text to the pool.  */
-      POOL_APPEND_ZT (*pool, beg, end);
+      POOL_APPEND (*pool, beg, end);
+      POOL_APPEND_CHR (*pool, '\0');
     }
 
   if (flags & AP_DOWNCASE)
     }
 
   if (flags & AP_DOWNCASE)
@@ -822,10 +856,11 @@ map_html_tags (const char *text, int size,
                  goto look_for_tag;
                attr_raw_value_end = p; /* <foo bar="baz"> */
                                        /*               ^ */
                  goto look_for_tag;
                attr_raw_value_end = p; /* <foo bar="baz"> */
                                        /*               ^ */
-               /* The AP_SKIP_BLANKS part is not entirely correct,
-                  because we don't want to skip blanks for all the
-                  attribute values.  */
-               operation = AP_PROCESS_ENTITIES | AP_SKIP_BLANKS;
+               /* The AP_TRIM_BLANKS is there for buggy HTML
+                  generators that generate <a href=" foo"> instead of
+                  <a href="foo"> (Netscape ignores spaces as well.)
+                  If you really mean space, use &32; or %20.  */
+               operation = AP_PROCESS_ENTITIES | AP_TRIM_BLANKS;
              }
            else
              {
              }
            else
              {