aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile.am47
-rw-r--r--src/blogc-git-receiver/pre-receive-parser.c77
-rw-r--r--src/blogc-git-receiver/pre-receive-parser.h14
-rw-r--r--src/blogc-git-receiver/pre-receive.c91
-rw-r--r--src/common/stdin.c23
-rw-r--r--src/common/stdin.h14
-rw-r--r--tests/blogc-git-receiver/check_pre_receive_parser.c101
-rw-r--r--tests/common/check_stdin.c53
9 files changed, 341 insertions, 81 deletions
diff --git a/.gitignore b/.gitignore
index a222ebe..af2b5d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -57,10 +57,12 @@ blogc*.html
/tests/blogc/check_renderer
/tests/blogc/check_source_parser
/tests/blogc/check_template_parser
+/tests/blogc-git-receiver/check_pre_receive_parser
/tests/blogc-runserver/check_httpd_utils
/tests/blogc-runserver/check_mime
/tests/common/check_config_parser
/tests/common/check_error
+/tests/common/check_stdin
/tests/common/check_utf8
/tests/common/check_utils
diff --git a/Makefile.am b/Makefile.am
index ef4e282..fff49b9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -41,6 +41,7 @@ noinst_HEADERS = \
src/blogc/template-parser.h \
src/blogc-git-receiver/post-receive.h \
src/blogc-git-receiver/pre-receive.h \
+ src/blogc-git-receiver/pre-receive-parser.h \
src/blogc-git-receiver/shell.h \
src/blogc-runserver/httpd.h \
src/blogc-runserver/httpd-utils.h \
@@ -48,6 +49,7 @@ noinst_HEADERS = \
src/common/config-parser.h \
src/common/error.h \
src/common/file.h \
+ src/common/stdin.h \
src/common/utf8.h \
src/common/utils.h \
$(NULL)
@@ -110,6 +112,7 @@ libblogc_common_la_SOURCES = \
src/common/config-parser.c \
src/common/error.c \
src/common/file.c \
+ src/common/stdin.c \
src/common/utf8.c \
src/common/utils.c \
$(NULL)
@@ -151,6 +154,7 @@ blogc_git_receiver_LDADD = \
libblogc_git_receiver_la_SOURCES = \
src/blogc-git-receiver/post-receive.c \
src/blogc-git-receiver/pre-receive.c \
+ src/blogc-git-receiver/pre-receive-parser.c \
src/blogc-git-receiver/shell.c \
$(NULL)
@@ -319,6 +323,7 @@ check_PROGRAMS += \
tests/blogc/check_template_parser \
tests/common/check_config_parser \
tests/common/check_error \
+ tests/common/check_stdin \
tests/common/check_utf8 \
tests/common/check_utils \
$(NULL)
@@ -466,6 +471,24 @@ tests_common_check_error_LDADD = \
libblogc_common.la \
$(NULL)
+tests_common_check_stdin_SOURCES = \
+ tests/common/check_stdin.c \
+ $(NULL)
+
+tests_common_check_stdin_CFLAGS = \
+ $(CMOCKA_CFLAGS) \
+ $(NULL)
+
+tests_common_check_stdin_LDFLAGS = \
+ -no-install \
+ -Wl,--wrap=fgetc \
+ $(NULL)
+
+tests_common_check_stdin_LDADD = \
+ $(CMOCKA_LIBS) \
+ libblogc_common.la \
+ $(NULL)
+
tests_common_check_utf8_SOURCES = \
tests/common/check_utf8.c \
$(NULL)
@@ -545,6 +568,30 @@ tests_blogc_runserver_check_mime_LDADD = \
$(NULL)
endif
+if BUILD_GIT_RECEIVER
+check_PROGRAMS += \
+ tests/blogc-git-receiver/check_pre_receive_parser \
+ $(NULL)
+
+tests_blogc_git_receiver_check_pre_receive_parser_SOURCES = \
+ tests/blogc-git-receiver/check_pre_receive_parser.c \
+ $(NULL)
+
+tests_blogc_git_receiver_check_pre_receive_parser_CFLAGS = \
+ $(CMOCKA_CFLAGS) \
+ $(NULL)
+
+tests_blogc_git_receiver_check_pre_receive_parser_LDFLAGS = \
+ -no-install \
+ $(NULL)
+
+tests_blogc_git_receiver_check_pre_receive_parser_LDADD = \
+ $(CMOCKA_LIBS) \
+ libblogc_git_receiver.la \
+ libblogc_common.la \
+ $(NULL)
+endif
+
endif
TESTS = \
diff --git a/src/blogc-git-receiver/pre-receive-parser.c b/src/blogc-git-receiver/pre-receive-parser.c
new file mode 100644
index 0000000..a842a9d
--- /dev/null
+++ b/src/blogc-git-receiver/pre-receive-parser.c
@@ -0,0 +1,77 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "../common/utils.h"
+#include "pre-receive-parser.h"
+
+typedef enum {
+ START_OLD = 1,
+ OLD,
+ START_NEW,
+ NEW,
+ START_REF,
+ REF
+} input_state_t;
+
+
+char*
+bgr_pre_receive_parse(const char *input)
+{
+ input_state_t state = START_OLD;
+ size_t start = 0;
+ size_t start_new = 0;
+ size_t input_len = strlen(input);
+
+ for (size_t current = 0; current < input_len; current++) {
+
+ char c = input[current];
+
+ switch (state) {
+ case START_OLD:
+ start = current;
+ state = OLD;
+ break;
+ case OLD:
+ if (c != ' ')
+ break;
+ // no need to store old
+ state = START_NEW;
+ break;
+ case START_NEW:
+ start = current;
+ state = NEW;
+ break;
+ case NEW:
+ if (c != ' ')
+ break;
+ state = START_REF;
+ start_new = start;
+ break;
+ case START_REF:
+ start = current;
+ state = REF;
+ break;
+ case REF:
+ if (c != '\n')
+ break;
+ state = START_OLD;
+ // we just care about a ref (refs/heads/master), everything
+ // else is disposable :)
+ if ((current - start == 17) &&
+ (0 == strncmp("refs/heads/master", input + start, 17)))
+ {
+ return bc_strndup(input + start_new, start - 1 - start_new);
+ }
+ break;
+ }
+ }
+
+ return NULL;
+}
diff --git a/src/blogc-git-receiver/pre-receive-parser.h b/src/blogc-git-receiver/pre-receive-parser.h
new file mode 100644
index 0000000..3a605da
--- /dev/null
+++ b/src/blogc-git-receiver/pre-receive-parser.h
@@ -0,0 +1,14 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifndef _PRE_RECEIVE_PARSER_H
+#define _PRE_RECEIVE_PARSER_H
+
+char* bgr_pre_receive_parse(const char *input);
+
+#endif /* _PRE_RECEIVE_PARSER_H */
diff --git a/src/blogc-git-receiver/pre-receive.c b/src/blogc-git-receiver/pre-receive.c
index 8c35537..ca239da 100644
--- a/src/blogc-git-receiver/pre-receive.c
+++ b/src/blogc-git-receiver/pre-receive.c
@@ -17,12 +17,10 @@
#include <sys/stat.h>
#include <dirent.h>
#include <time.h>
-
#include "../common/utils.h"
-
-#ifndef BUFFER_SIZE
-#define BUFFER_SIZE 4096
-#endif
+#include "../common/stdin.h"
+#include "pre-receive-parser.h"
+#include "pre-receive.h"
static unsigned int
@@ -91,93 +89,26 @@ rmdir_recursive(const char *dir)
}
-typedef enum {
- START_OLD = 1,
- OLD,
- START_NEW,
- NEW,
- START_REF,
- REF
-} input_state_t;
-
-
int
bgr_pre_receive_hook(int argc, char *argv[])
{
- int c;
- char buffer[BUFFER_SIZE];
-
- input_state_t state = START_OLD;
- size_t i = 0;
- size_t start = 0;
-
int rv = 0;
- char *new = NULL;
- char *master = NULL;
+ char buffer[4096];
- while (EOF != (c = getc(stdin))) {
-
- buffer[i] = (char) c;
-
- switch (state) {
- case START_OLD:
- start = i;
- state = OLD;
- break;
- case OLD:
- if (c != ' ')
- break;
- // no need to store old
- state = START_NEW;
- break;
- case START_NEW:
- start = i;
- state = NEW;
- break;
- case NEW:
- if (c != ' ')
- break;
- state = START_REF;
- new = strndup(buffer + start, i - start);
- break;
- case START_REF:
- start = i;
- state = REF;
- break;
- case REF:
- if (c != '\n')
- break;
- state = START_OLD;
- // we just care about a ref (refs/heads/master), everything
- // else is disposable :)
- if (!((i - start == 17) &&
- (0 == strncmp("refs/heads/master", buffer + start, 17))))
- {
- free(new);
- new = NULL;
- break;
- }
- master = new;
- break;
- }
-
- if (++i >= BUFFER_SIZE) {
- fprintf(stderr, "error: pre-receive hook payload is too big.\n");
- rv = 1;
- goto cleanup2;
- }
- }
+ char *input = bc_stdin_read();
+ char *master = bgr_pre_receive_parse(input);
+ free(input);
if (master == NULL) {
fprintf(stderr, "warning: no reference to master branch found. "
"nothing to deploy.\n");
- goto cleanup2;
+ return rv;
}
char *repo_dir = NULL;
char *output_dir = NULL;
- if (NULL == getcwd(buffer, BUFFER_SIZE)) {
+ if (NULL == getcwd(buffer, sizeof(buffer))) {
fprintf(stderr, "error: failed to get repository remote path: %s\n",
strerror(errno));
rv = 1;
@@ -247,7 +178,7 @@ bgr_pre_receive_hook(int argc, char *argv[])
}
char *htdocs_sym = NULL;
- ssize_t htdocs_sym_len = readlink("htdocs", buffer, BUFFER_SIZE);
+ ssize_t htdocs_sym_len = readlink("htdocs", buffer, sizeof(buffer));
if (0 < htdocs_sym_len) {
if (0 != unlink("htdocs")) {
fprintf(stderr, "error: failed to remove symlink (%s/htdocs): %s\n",
@@ -275,7 +206,5 @@ cleanup:
free(output_dir);
rmdir_recursive(dir);
free(repo_dir);
-cleanup2:
- free(new);
return rv;
}
diff --git a/src/common/stdin.c b/src/common/stdin.c
new file mode 100644
index 0000000..2664c3e
--- /dev/null
+++ b/src/common/stdin.c
@@ -0,0 +1,23 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdio.h>
+#include "utils.h"
+#include "stdin.h"
+
+
+// splitted in single file to make it easier to test
+char*
+bc_stdin_read(void)
+{
+ int c;
+ bc_string_t *rv = bc_string_new();
+ while (EOF != (c = fgetc(stdin)))
+ bc_string_append_c(rv, c);
+ return bc_string_free(rv, false);
+}
diff --git a/src/common/stdin.h b/src/common/stdin.h
new file mode 100644
index 0000000..ebf042d
--- /dev/null
+++ b/src/common/stdin.h
@@ -0,0 +1,14 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#ifndef _STDIN_H
+#define _STDIN_H
+
+char* bc_stdin_read(void);
+
+#endif /* _STDIN_H */
diff --git a/tests/blogc-git-receiver/check_pre_receive_parser.c b/tests/blogc-git-receiver/check_pre_receive_parser.c
new file mode 100644
index 0000000..0c716fa
--- /dev/null
+++ b/tests/blogc-git-receiver/check_pre_receive_parser.c
@@ -0,0 +1,101 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <stdlib.h>
+#include "../../src/blogc-git-receiver/pre-receive-parser.h"
+
+
+static void
+test_pre_receive_parse(void **state)
+{
+ assert_null(bgr_pre_receive_parse(""));
+ assert_null(bgr_pre_receive_parse(
+ "4f1f932f6ef6d6c9770266775c2db072964d7a62"));
+ assert_null(bgr_pre_receive_parse(
+ "4f1f932f6ef6d6c9770266775c2db072964d7a62 "));
+ assert_null(bgr_pre_receive_parse(
+ "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545f3"));
+ assert_null(bgr_pre_receive_parse(
+ "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545f3 "));
+ assert_null(bgr_pre_receive_parse(
+ "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545f3 "
+ "refs/heads/lol"));
+ assert_null(bgr_pre_receive_parse(
+ "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545f3 "
+ "refs/heads/lol"));
+ assert_null(bgr_pre_receive_parse(
+ "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545f3 "
+ "refs/heads/master"));
+ assert_null(bgr_pre_receive_parse(
+ "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545f3 "
+ "refs/heads/master asd\n"));
+ char *t;
+ t = bgr_pre_receive_parse(
+ "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545f3 "
+ "refs/heads/master\n");
+ assert_non_null(t);
+ assert_string_equal(t, "3fff4bb3172f77b292b0c913749e81bedd3545f3");
+ free(t);
+ t = bgr_pre_receive_parse(
+ "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545fa "
+ "refs/heads/master\n"
+ "4f1f932f6ef6d6c9770266775c2db072964d7a63 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545f4 "
+ "refs/heads/bola\n"
+ );
+ assert_non_null(t);
+ assert_string_equal(t, "3fff4bb3172f77b292b0c913749e81bedd3545fa");
+ free(t);
+ t = bgr_pre_receive_parse(
+ "4f1f932f6ef6d6c9770266775c2db072964d7a63 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545f4 "
+ "refs/heads/bola\n"
+ "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545fb "
+ "refs/heads/master\n"
+ );
+ assert_non_null(t);
+ assert_string_equal(t, "3fff4bb3172f77b292b0c913749e81bedd3545fb");
+ free(t);
+ t = bgr_pre_receive_parse(
+ "4f1f932f6ef6d6c9770266775c2db072964d7a63 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545f4 "
+ "refs/heads/bola\n"
+ "4f1f932f6ef6d6c9770266775c2db072964d7a62 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545fc "
+ "refs/heads/master\n"
+ "4f1f932f6ef6d6c9770266775c2db072964d7a64 "
+ "3fff4bb3172f77b292b0c913749e81bedd3545f5 "
+ "refs/heads/bolao\n"
+ );
+ assert_non_null(t);
+ assert_string_equal(t, "3fff4bb3172f77b292b0c913749e81bedd3545fc");
+ free(t);
+}
+
+
+int
+main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_pre_receive_parse),
+ };
+ return run_tests(tests);
+}
diff --git a/tests/common/check_stdin.c b/tests/common/check_stdin.c
new file mode 100644
index 0000000..c0d222d
--- /dev/null
+++ b/tests/common/check_stdin.c
@@ -0,0 +1,53 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <string.h>
+#include <stdio.h>
+#include "../../src/common/stdin.h"
+
+
+int
+__wrap_fgetc(FILE *stream)
+{
+ assert_int_equal(fileno(stream), fileno(stdin));
+ return mock_type(int);
+}
+
+
+static void
+test_read(void **state)
+{
+ will_return(__wrap_fgetc, EOF);
+ char *t = bc_stdin_read();
+ assert_non_null(t);
+ assert_string_equal(t, "");
+ free(t);
+ will_return(__wrap_fgetc, 'b');
+ will_return(__wrap_fgetc, 'o');
+ will_return(__wrap_fgetc, 'l');
+ will_return(__wrap_fgetc, 'a');
+ will_return(__wrap_fgetc, EOF);
+ t = bc_stdin_read();
+ assert_non_null(t);
+ assert_string_equal(t, "bola");
+ free(t);
+}
+
+
+int
+main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_read),
+ };
+ return run_tests(tests);
+}