Exemple #1
0
void
utf8_regression_1(void)
{
  uint32_t i;
  unsigned valid = 0;

  for (i = 0; i < 0xffffffffUL; i++) {
    static char data[5];
    static char hit[0x10FFFFU + 1];
    uint32_t d;

    if (0 == (i % (((uint32_t) -1) / 100))) {
      printf("i=%u\n", i / (((uint32_t) -1) / 100));
    }

    poke_be32(data, i);
    d = utf8_decode(data, 4);
    if ((uint32_t) -1 == d)
      continue;

    if (d > 0x10ffffU || utf32_is_non_character(d) || utf32_is_surrogate(d)) {
      printf("data: %02x %02x %02x %02x\n",
          (unsigned char) data[0],
          (unsigned char) data[1],
          (unsigned char) data[2],
          (unsigned char) data[3]);
      printf("d: U+%lx\n", (unsigned long) d);
      printf("i: %lu\n", (unsigned long) i);
      RUNTIME_ASSERT(d <= 0x10ffffU);
      RUNTIME_ASSERT(!utf32_is_non_character(d));
      RUNTIME_ASSERT(!utf32_is_surrogate(d));
    }

    if (!hit[d]) {
      hit[d] = 1;
      valid++;
    }

    {
      unsigned n;
      char buf[4];

      n = utf8_encode(d, buf);
      RUNTIME_ASSERT(n > 0);
      RUNTIME_ASSERT(n <= 4);
      RUNTIME_ASSERT(n == utf8_first_byte_length_hint(data[0]));

      if (0 != memcmp(data, buf, n)) {
        printf("buf:  %02x %02x %02x %02x\n",
            (unsigned char) buf[0],
            (unsigned char) buf[1],
            (unsigned char) buf[2],
            (unsigned char) buf[3]);
        printf("data: %02x %02x %02x %02x\n",
            (unsigned char) data[0],
            (unsigned char) data[1],
            (unsigned char) data[2],
            (unsigned char) data[3]);
        printf("d: U+%lx\n", (unsigned long) i);
        printf("i: %lu\n", (unsigned long) i);
        printf("n: %u\n", n);
        RUNTIME_ASSERT(0);
      }
    }
  }
  printf("valid=%u\n", valid);

  printf("PASSED\n");
}
Exemple #2
0
static void
handle_qhit(const char *data, size_t size)
{
  const struct gnutella_qhit_header *header;
  const struct gnutella_guid *guid;
  const struct gnutella_qhit_item *item;
  size_t guid_offset = size - sizeof *guid;
  unsigned hits;
  size_t pos;
  
  RUNTIME_ASSERT(size <= GNUTELLA_MAX_PAYLOAD);
  
  if (size < sizeof *header) {
    fprintf(stderr, "handle_qhit(): Too little payload for header.\n");
    return;
  }
  header = cast_to_const_void_ptr(data);
  
  hits = (unsigned char) header->hits;
  printf("Hits: %u\n", hits);
  printf("Address: %s\n",
    net_addr_port_to_string(net_addr_peek_ipv4(cast_to_const_char_ptr(header->addr)),
      peek_le16(header->port)));
  printf("Speed: %lu\n", (unsigned long) peek_le32(header->speed));

  if (size < sizeof *header + sizeof *guid) {
    fprintf(stderr, "handle_qhit(): Insufficient payload for query hit.\n");
    return;
  }
  if (size >= sizeof *header + sizeof *guid) {
    
    guid = cast_to_const_void_ptr(&data[guid_offset]);
    printf("Servent ID: %08lx-%08lx-%08lx-%08lx\n",
        (unsigned long) peek_be32(&guid->data[0]),
        (unsigned long) peek_be32(&guid->data[4]),
        (unsigned long) peek_be32(&guid->data[8]),
        (unsigned long) peek_be32(&guid->data[12]));
  }
  printf("----\n");

  pos = sizeof *header;
  for (/* NOTHING */; hits > 0; hits--) {
    const char *nul_ptr;
   
    if (pos >= guid_offset || guid_offset - pos < sizeof *item + 2)
      break;

    item = cast_to_const_void_ptr(&data[pos]);
    printf("Index: %lu\n", (unsigned long) peek_le32(item->index));
    printf("Size:  %lu\n", (unsigned long) peek_le32(item->size));

    pos += sizeof *item; 

    nul_ptr = memchr(&data[pos], 0, guid_offset - pos);
    if (!nul_ptr) {
      fprintf(stderr, "handle_qhit(): Non-terminated filename.\n");
      return;
    } else {
      size_t len;

      len = (nul_ptr - &data[pos]);
      if (len > (((size_t) -1) / 4 - 1)) {
        fprintf(stderr, "handle_qhit(): Filename is too long.\n");
        /* Ignore */
      } else {
        const char *p;
        size_t avail;
        
        printf("Filename: ");

        avail = len;
        p = &data[pos];
        while (avail > 0) {
          uint32_t cp;
          cp = utf8_decode(p, avail);
          if ((uint32_t) -1 != cp) {
            uint8_t u_len, i;

            u_len = utf8_first_byte_length_hint((unsigned char) *p);
            RUNTIME_ASSERT(u_len > 0);
            RUNTIME_ASSERT(avail >= u_len);
            avail -= u_len;

            if (cp >= 0x20 && cp != 0x7f) {
              for (i = 0; i < u_len; i++) {
                putchar((unsigned char) p[i]);
              }
            } else {
              char ch = cp & 0xff;
              printf("%s", escape_buffer(&ch, 1)); 
            }
            
            p += u_len;
          } else {
            if (verbosity > 0) {
              fprintf(stderr, "handle_qhit(): Invalid UTF-8.\n");
            }
            break;
          }
        }
      }
      printf("\n");

      pos += len;
    }

    RUNTIME_ASSERT(nul_ptr);
    RUNTIME_ASSERT(&data[pos] == nul_ptr);
    RUNTIME_ASSERT('\0' == *nul_ptr);

    pos++;
    RUNTIME_ASSERT(pos <= guid_offset);

    nul_ptr = memchr(&data[pos], 0, guid_offset - pos);
    if (!nul_ptr) {
      fprintf(stderr, "handle_qhit(): Non-terminated extension block.\n");
      return;
    } else if (nul_ptr != &data[pos]) {
      size_t len = nul_ptr - &data[pos];
      
      printf("Extension size:  %lu\n", (unsigned long) len);
     
      handle_extension(&data[pos], len);
      pos += len;
    }

    RUNTIME_ASSERT(nul_ptr);
    RUNTIME_ASSERT(&data[pos] == nul_ptr);
    RUNTIME_ASSERT('\0' == *nul_ptr);

    pos++;
    RUNTIME_ASSERT(pos <= guid_offset);

    printf("------\n");
  }

  if (hits > 0) {
    fprintf(stderr, "handle_qhit(): Expected %u more hits.\n", hits);
  }

  if (pos < guid_offset) {
      static const unsigned vendor_id_len = 4;
      
      printf("Extended QHD size:  %lu\n", (unsigned long) guid_offset - pos);
      if (guid_offset - pos >= vendor_id_len) {

        printf("Vendor ID: %s\n", escape_buffer(&data[pos], vendor_id_len));

        pos += vendor_id_len;
        if (pos < guid_offset) {
          uint8_t open_data_size = data[pos];
          bool has_ggep = false;
          
          printf("Open data size:  %u\n", open_data_size);
          pos++;

          if (open_data_size > guid_offset - pos) {
            printf("Open data size is too large.\n");
            return;
          }

          if (open_data_size >= 2) {
            uint8_t mask = data[pos];
            uint8_t value = data[pos + 1];
          
            printf("mask:  0x%02x\n", mask);
            printf("value: 0x%02x\n", value);
            
            if (0x20 & mask) {
              has_ggep = 0x20 & value;
              printf("Has GGEP: %s\n", has_ggep ? "yes" : "no");
            }
            if (0x10 & mask) {
              printf("Has speed: %s\n", (0x10 & value) ? "yes" : "no");
            }
            if (0x08 & mask) {
              printf("Has uploaded: %s\n", (0x08 & value) ? "yes" : "no");
            }
            if (0x04 & mask) {
              printf("Busy: %s\n", (0x04 & value) ? "yes" : "no");
            }
            /* mask and value are swapped */
            if (0x01 & value) {
              printf("Must push: %s\n", (0x01 & mask) ? "yes" : "no");
            }
          }

          pos += open_data_size;

          if (pos < guid_offset) {
            size_t priv_data_size = guid_offset - pos;
            static const char id_deflate[] = "{deflate}";
            const char *priv_data, *x;
            
            priv_data = &data[pos];
            priv_data_size = guid_offset - pos;
            
            printf("Private data area size:  %lu\n",
              (unsigned long) priv_data_size);

            handle_extension(priv_data, priv_data_size);

            x = compat_memmem(priv_data, priv_data_size,
                    id_deflate, STATIC_STRLEN(id_deflate));
            if (x) {
              char buf[64 * 1024];
              const char *src;
              size_t n, src_len;

              src = &x[STATIC_STRLEN(id_deflate)];
              src_len = priv_data_size - STATIC_STRLEN(id_deflate);
              n = buffer_inflate(buf, sizeof buf, src, src_len);
              if ((size_t) -1 != n) {
                printf("Inflated:  %s\n", escape_buffer(buf, n));
              }
            }

            pos += priv_data_size;
          }

          RUNTIME_ASSERT(pos == guid_offset);
        }
      }
  }
  
  printf("----\n");
}
Exemple #3
0
static void
html_render_text(struct render_context *ctx, const struct array text)
{
	unsigned c_len;
	size_t i;
	bool whitespace = FALSE;
	struct array entity, current;

	entity = zero_array;
	current = zero_array;

	for (i = 0; i < text.size; i += c_len) {
		const unsigned char c = text.data[i];
		bool is_whitespace;

		is_whitespace = FALSE;
		c_len = utf8_first_byte_length_hint(c);
		if (!ctx->preformatted && is_ascii_space(c)) {
			if (whitespace)
				continue;
			is_whitespace = TRUE;
			whitespace = TRUE;
			if (0x20 == c && i > 0 && i < text.size - c_len) {
				const unsigned char next_c = text.data[i + c_len];

				if (!is_ascii_space(next_c))
					is_whitespace = FALSE;
			}
		} else {
			whitespace = FALSE;
		}
		if ('&' == c || ';' == c || is_whitespace) {
			if (current.size > 0) {
				html_output_print(ctx->output, current);
				current = zero_array;
			}
		}
		if (is_whitespace) {
			if (i > 0 || ctx->closing)
				html_output_print(ctx->output, array_from_string(" "));
		} else if ('&' == c) {
			if (entity.data) {
				html_render_entity(ctx, entity);
			}
			entity.data = deconstify_gchar(&text.data[i + c_len]);
			entity.size = 0;
			continue;
		} else if (';' == c) {
			if (entity.data) {
				html_render_entity(ctx, entity);
				entity = zero_array;
				continue;
			}
		} else if (entity.data) {
			entity.size += c_len;
		} else {
			if (!current.data)
				current.data = &text.data[i];
			current.size += c_len;
		}
	}
	if (current.size > 0) {
		html_output_print(ctx->output, current);
	}
}