Exemplo n.º 1
0
size_t
ups_autolink__www(size_t *rewind_p, struct buf *link, char *data, size_t offset, size_t size)
{
	size_t link_end;
	int np = 0;

	if (offset > 0 && !ispunct(data[-1]) && !isspace(data[-1]))
		return 0;

	if (size < 4 || memcmp(data, "www.", STRLEN("www.")) != 0)
		return 0;

	link_end = 0;
	while (link_end < size && !isspace(data[link_end])) {
		if (data[link_end] == '.')
			np++;

		link_end++;
	}

	if (np < 2)
		return 0;

	link_end = autolink_delim(data, link_end, offset, size);

	if (link_end == 0)
		return 0;

	bufput(link, data, link_end);
	*rewind_p = 0;

	return (int)link_end;
}
Exemplo n.º 2
0
size_t
sd_autolink__www(
	size_t *rewind_p,
	struct buf *link,
	uint8_t *data,
	size_t max_rewind,
	size_t size,
	unsigned int flags)
{
	size_t link_end;

	if (max_rewind > 0 && !ispunct(data[-1]) && !isspace(data[-1]))
		return 0;

	if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0)
		return 0;

	link_end = check_domain(data, size, 0);

	if (link_end == 0)
		return 0;

	while (link_end < size && !isspace(data[link_end]))
		link_end++;

	link_end = autolink_delim(data, link_end, max_rewind, size);

	if (link_end == 0)
		return 0;

	bufput(link, data, link_end);
	*rewind_p = 0;

	return (int)link_end;
}
Exemplo n.º 3
0
size_t
ups_autolink__url(size_t *rewind_p, struct buf *link, char *data, size_t offset, size_t size)
{
	size_t link_end, rewind = 0;

	if (size < 4 || data[1] != '/' || data[2] != '/')
		return 0;

	while (rewind < offset && isalpha(data[-rewind - 1]))
		rewind++;

	if (!is_safe_link(data - rewind, size + rewind))
		return 0;

	link_end = 0;
	while (link_end < size && !isspace(data[link_end]))
		link_end++;

	link_end = autolink_delim(data, link_end, offset, size);

	if (link_end == 0)
		return 0;

	bufput(link, data - rewind, link_end + rewind);
	*rewind_p = rewind;

	return link_end;
}
Exemplo n.º 4
0
size_t
sd_autolink__url(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size)
{
	size_t link_end, rewind = 0, domain_len;

	if (size < 4 || data[1] != '/' || data[2] != '/')
		return 0;

	while (rewind < offset && isalpha(data[-rewind - 1]))
		rewind++;

	if (!sd_autolink_issafe(data - rewind, size + rewind))
		return 0;
	link_end = strlen("://");

	domain_len = check_domain(data + link_end, size - link_end);
	if (domain_len == 0)
		return 0;

	link_end += domain_len;
	while (link_end < size && !isspace(data[link_end]))
		link_end++;

	link_end = autolink_delim(data, link_end, offset, size);

	if (link_end == 0)
		return 0;

	bufput(link, data - rewind, link_end + rewind);
	*rewind_p = rewind;

	return link_end;
}
Exemplo n.º 5
0
size_t
rfcdown_autolink__email(
	size_t *rewind_p,
	rfcdown_buffer *link,
	uint8_t *data,
	size_t max_rewind,
	size_t size,
	unsigned int flags)
{
	size_t link_end, rewind;
	int nb = 0, np = 0;

	for (rewind = 0; rewind < max_rewind; ++rewind) {
		uint8_t c = data[-1 - rewind];

		if (isalnum(c))
			continue;

		if (strchr(".+-_", c) != NULL)
			continue;

		break;
	}

	if (rewind == 0)
		return 0;

	for (link_end = 0; link_end < size; ++link_end) {
		uint8_t c = data[link_end];

		if (isalnum(c))
			continue;

		if (c == '@')
			nb++;
		else if (c == '.' && link_end < size - 1)
			np++;
		else if (c != '-' && c != '_')
			break;
	}

	if (link_end < 2 || nb != 1 || np == 0 ||
		!isalpha(data[link_end - 1]))
		return 0;

	link_end = autolink_delim(data, link_end, max_rewind, size);

	if (link_end == 0)
		return 0;

	rfcdown_buffer_put(link, data - rewind, link_end + rewind);
	*rewind_p = rewind;

	return link_end;
}
Exemplo n.º 6
0
size_t
sd_autolink__email(
	size_t *rewind_p,
	struct buf *link,
	uint8_t *data,
	size_t offset,
	size_t size,
	unsigned int flags)
{
	size_t link_end, rewind;
	int nb = 0, np = 0;

	for (rewind = 0; rewind < offset; ++rewind) {
		uint8_t c = data[-rewind - 1];

		if (isalnum(c))
			continue;

		if (strchr(".+-_", c) != NULL)
			continue;

		break;
	}

	if (rewind == 0)
		return 0;

	for (link_end = 0; link_end < size; ++link_end) {
		uint8_t c = data[link_end];

		if (isalnum(c))
			continue;

		if (c == '@')
			nb++;
		else if (c == '.' && link_end < size - 1)
			np++;
		else if (c != '-' && c != '_')
			break;
	}

	if (link_end < 2 || nb != 1 || np == 0)
		return 0;

	link_end = autolink_delim(data, link_end, offset, size);

	if (link_end == 0)
		return 0;

	bufput(link, data - rewind, link_end + rewind);
	*rewind_p = rewind;

	return link_end;
}
Exemplo n.º 7
0
static cmark_node *www_match(cmark_parser *parser, cmark_node *parent,
                             cmark_inline_parser *inline_parser) {
  cmark_chunk *chunk = cmark_inline_parser_get_chunk(inline_parser);
  size_t max_rewind = cmark_inline_parser_get_offset(inline_parser);
  uint8_t *data = chunk->data + max_rewind;
  size_t size = chunk->len - max_rewind;
  int start = cmark_inline_parser_get_column(inline_parser);

  size_t link_end;

  if (max_rewind > 0 && strchr("*_~(", data[-1]) == NULL &&
      !cmark_isspace(data[-1]))
    return 0;

  if (size < 4 || memcmp(data, "www.", strlen("www.")) != 0)
    return 0;

  link_end = check_domain(data, size, 0);

  if (link_end == 0)
    return NULL;

  while (link_end < size && !cmark_isspace(data[link_end]))
    link_end++;

  link_end = autolink_delim(data, link_end);

  if (link_end == 0)
    return NULL;

  cmark_inline_parser_set_offset(inline_parser, (int)(max_rewind + link_end));

  cmark_node *node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);

  cmark_strbuf buf;
  cmark_strbuf_init(parser->mem, &buf, 10);
  cmark_strbuf_puts(&buf, "http://");
  cmark_strbuf_put(&buf, data, (bufsize_t)link_end);
  node->as.link.url = cmark_chunk_buf_detach(&buf);

  cmark_node *text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);
  text->as.literal =
      cmark_chunk_dup(chunk, (bufsize_t)max_rewind, (bufsize_t)link_end);
  cmark_node_append_child(node, text);

  node->start_line = text->start_line =
    node->end_line = text->end_line =
    cmark_inline_parser_get_line(inline_parser);

  node->start_column = text->start_column = start - 1;
  node->end_column = text->end_column = cmark_inline_parser_get_column(inline_parser) - 1;

  return node;
}
Exemplo n.º 8
0
static cmark_node *url_match(cmark_parser *parser, cmark_node *parent,
                             cmark_inline_parser *inline_parser) {
  size_t link_end, domain_len;
  int rewind = 0;

  cmark_chunk *chunk = cmark_inline_parser_get_chunk(inline_parser);
  int max_rewind = cmark_inline_parser_get_offset(inline_parser);
  uint8_t *data = chunk->data + max_rewind;
  size_t size = chunk->len - max_rewind;

  if (size < 4 || data[1] != '/' || data[2] != '/')
    return 0;

  while (rewind < max_rewind && cmark_isalpha(data[-rewind - 1]))
    rewind++;

  if (!sd_autolink_issafe(data - rewind, size + rewind))
    return 0;

  link_end = strlen("://");

  domain_len = check_domain(data + link_end, size - link_end, 1);

  if (domain_len == 0)
    return 0;

  link_end += domain_len;
  while (link_end < size && !cmark_isspace(data[link_end]))
    link_end++;

  link_end = autolink_delim(data, link_end);

  if (link_end == 0)
    return NULL;

  cmark_inline_parser_set_offset(inline_parser, (int)(max_rewind + link_end));
  cmark_node_unput(parent, rewind);

  cmark_node *node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);

  cmark_chunk url = cmark_chunk_dup(chunk, max_rewind - rewind,
                                    (bufsize_t)(link_end + rewind));
  node->as.link.url = url;

  cmark_node *text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);
  text->as.literal = url;
  cmark_node_append_child(node, text);

  return node;
}
Exemplo n.º 9
0
size_t
sd_autolink__url(
	size_t *rewind_p,
	struct buf *link,
	uint8_t *data,
	size_t max_rewind,
	size_t size,
	unsigned int flags)
{
	size_t link_end, rewind = 0, domain_len;

	if (size < 4 || data[1] != '/' || data[2] != '/')
		return 0;

	while (rewind < max_rewind && isalpha(data[-rewind - 1]))
		rewind++;

	if (!sd_autolink_issafe(data - rewind, size + rewind))
		return 0;

	link_end = strlen("://");

	domain_len = check_domain(
		data + link_end,
		size - link_end,
		flags & SD_AUTOLINK_SHORT_DOMAINS);

	if (domain_len == 0)
		return 0;

	link_end += domain_len;
	while (link_end < size && !isspace(data[link_end]))
		link_end++;

	link_end = autolink_delim(data, link_end, max_rewind, size);

	if (link_end == 0)
		return 0;

	bufput(link, data - rewind, link_end + rewind);
	*rewind_p = rewind;

	return link_end;
}
Exemplo n.º 10
0
static void postprocess_text(cmark_parser *parser, cmark_node *text, int offset) {
  size_t link_end;
  uint8_t *data = text->as.literal.data,
    *at;
  size_t size = text->as.literal.len;
  int rewind, max_rewind,
      nb = 0, np = 0, ns = 0;

  if (offset < 0 || (size_t)offset >= size)
    return;

  data += offset;
  size -= offset;

  at = (uint8_t *)memchr(data, '@', size);
  if (!at)
    return;

  max_rewind = (int)(at - data);
  data += max_rewind;
  size -= max_rewind;

  for (rewind = 0; rewind < max_rewind; ++rewind) {
    uint8_t c = data[-rewind - 1];

    if (cmark_isalnum(c))
      continue;

    if (strchr(".+-_", c) != NULL)
      continue;

    if (c == '/')
      ns++;

    break;
  }

  if (rewind == 0 || ns > 0) {
    postprocess_text(parser, text, max_rewind + 1 + offset);
    return;
  }

  for (link_end = 0; link_end < size; ++link_end) {
    uint8_t c = data[link_end];

    if (cmark_isalnum(c))
      continue;

    if (c == '@')
      nb++;
    else if (c == '.' && link_end < size - 1 && cmark_isalnum(data[link_end + 1]))
      np++;
    else if (c != '-' && c != '_')
      break;
  }

  if (link_end < 2 || nb != 1 || np == 0 ||
      (!cmark_isalpha(data[link_end - 1]) && data[link_end - 1] != '.')) {
    postprocess_text(parser, text, max_rewind + 1 + offset);
    return;
  }

  link_end = autolink_delim(data, link_end);

  if (link_end == 0) {
    postprocess_text(parser, text, max_rewind + 1 + offset);
    return;
  }

  cmark_chunk_to_cstr(parser->mem, &text->as.literal);

  cmark_node *link_node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);
  cmark_strbuf buf;
  cmark_strbuf_init(parser->mem, &buf, 10);
  cmark_strbuf_puts(&buf, "mailto:");
  cmark_strbuf_put(&buf, data - rewind, (bufsize_t)(link_end + rewind));
  link_node->as.link.url = cmark_chunk_buf_detach(&buf);

  cmark_node *link_text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);
  cmark_chunk email = cmark_chunk_dup(
      &text->as.literal,
      offset + max_rewind - rewind,
      (bufsize_t)(link_end + rewind));
  cmark_chunk_to_cstr(parser->mem, &email);
  link_text->as.literal = email;
  cmark_node_append_child(link_node, link_text);

  cmark_node_insert_after(text, link_node);

  cmark_node *post = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);
  post->as.literal = cmark_chunk_dup(&text->as.literal,
    (bufsize_t)(offset + max_rewind + link_end),
    (bufsize_t)(size - link_end));
  cmark_chunk_to_cstr(parser->mem, &post->as.literal);

  cmark_node_insert_after(link_node, post);

  text->as.literal.len = offset + max_rewind - rewind;
  text->as.literal.data[text->as.literal.len] = 0;

  postprocess_text(parser, post, 0);
}