summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am11
-rw-r--r--configure.ac13
-rw-r--r--src/dtddata.S40
-rw-r--r--src/scanner.c71
4 files changed, 132 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am
index 9114d98..7d31a39 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,11 +23,16 @@ pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA =
bin_PROGRAMS = wayland-scanner
-wayland_scanner_SOURCES = src/scanner.c
-wayland_scanner_CFLAGS = $(EXPAT_CFLAGS) $(AM_CFLAGS)
-wayland_scanner_LDADD = $(EXPAT_LIBS) libwayland-util.la
+wayland_scanner_SOURCES = src/scanner.c src/dtddata.S
+wayland_scanner_CFLAGS = $(EXPAT_CFLAGS) $(LIBXML_CFLAGS) $(AM_CFLAGS)
+wayland_scanner_LDADD = $(EXPAT_LIBS) $(LIBXML_LIBS) libwayland-util.la
pkgconfig_DATA += src/wayland-scanner.pc
+src/dtddata.o: protocol/wayland.dtd
+
+%.o: %.S
+ $(AM_V_GEN)$(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c -o $@ $<
+
if USE_HOST_SCANNER
wayland_scanner = wayland-scanner
else
diff --git a/configure.ac b/configure.ac
index ef26929..48658cf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,6 +28,7 @@ AM_SILENT_RULES([yes])
AC_PROG_CC
AC_PROG_CXX
AC_PROG_GREP
+AM_PROG_AS
# check if we have C++ compiler. This is hacky workaround,
# for a reason why it is this way see
@@ -71,6 +72,12 @@ AC_ARG_ENABLE([documentation],
[],
[enable_documentation=yes])
+AC_ARG_ENABLE([dtd-validation],
+ [AC_HELP_STRING([--disable-dtd-validation],
+ [Disable DTD validation of the protocol])],
+ [],
+ [enable_dtdvalidation=yes])
+
AM_CONDITIONAL(USE_HOST_SCANNER, test "x$with_host_scanner" = xyes)
AM_CONDITIONAL(ENABLE_LIBRARIES, test "x$enable_libraries" = xyes)
@@ -105,6 +112,12 @@ PKG_CHECK_MODULES(EXPAT, [expat], [],
AC_SUBST(EXPAT_LIBS)
])
+if test "x$enable_dtdvalidation" = "xyes"; then
+ PKG_CHECK_MODULES(LIBXML, [libxml-2.0])
+ AC_DEFINE(HAVE_LIBXML, 1, [libxml-2.0 is available])
+ AC_CONFIG_LINKS([src/wayland.dtd.embed:protocol/wayland.dtd])
+fi
+
AC_PATH_PROG(XSLTPROC, xsltproc)
AM_CONDITIONAL([HAVE_XSLTPROC], [test "x$XSLTPROC" != "x"])
diff --git a/src/dtddata.S b/src/dtddata.S
new file mode 100644
index 0000000..53debf3
--- /dev/null
+++ b/src/dtddata.S
@@ -0,0 +1,40 @@
+/*
+ * Copyright © 2015 Collabora, Ltd.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* from: http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967#comment-348129 */
+
+.altmacro
+.macro binfile name file
+ .p2align 2
+ .globl \name&_begin
+\name&_begin:
+ .incbin \file
+\name&_end:
+ .byte 0
+ .p2align 2
+ .globl \name&_len
+\name&_len:
+ .int (\name&_end - \name&_begin)
+.endm
+
+.section .rodata
+binfile DTD_DATA "src/wayland.dtd.embed"
diff --git a/src/scanner.c b/src/scanner.c
index 8ecdd56..406519f 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -25,6 +25,8 @@
* SOFTWARE.
*/
+#include "config.h"
+
#include <stdbool.h>
#include <stdio.h>
#include <stdarg.h>
@@ -34,9 +36,18 @@
#include <expat.h>
#include <getopt.h>
#include <limits.h>
+#include <unistd.h>
+
+#if HAVE_LIBXML
+#include <libxml/parser.h>
+#endif
#include "wayland-util.h"
+/* Embedded wayland.dtd file, see dtddata.S */
+extern char DTD_DATA_begin;
+extern int DTD_DATA_len;
+
enum side {
CLIENT,
SERVER,
@@ -59,6 +70,57 @@ usage(int ret)
exit(ret);
}
+static bool
+is_dtd_valid(FILE *input)
+{
+ bool rc = true;
+#if HAVE_LIBXML
+ xmlParserCtxtPtr ctx = NULL;
+ xmlDocPtr doc = NULL;
+ xmlDtdPtr dtd = NULL;
+ xmlValidCtxtPtr dtdctx;
+ xmlParserInputBufferPtr buffer;
+ int fd = fileno(input);
+
+ dtdctx = xmlNewValidCtxt();
+ ctx = xmlNewParserCtxt();
+ if (!ctx || !dtdctx)
+ abort();
+
+ buffer = xmlParserInputBufferCreateMem(&DTD_DATA_begin,
+ DTD_DATA_len,
+ XML_CHAR_ENCODING_UTF8);
+ if (!buffer) {
+ fprintf(stderr, "Failed to init buffer for DTD.\n");
+ abort();
+ }
+
+ dtd = xmlIOParseDTD(NULL, buffer, XML_CHAR_ENCODING_UTF8);
+ if (!dtd) {
+ fprintf(stderr, "Failed to parse DTD.\n");
+ abort();
+ }
+
+ doc = xmlCtxtReadFd(ctx, fd, "protocol", NULL, 0);
+ if (!doc) {
+ fprintf(stderr, "Failed to read XML\n");
+ abort();
+ }
+
+ rc = xmlValidateDtd(dtdctx, doc, dtd);
+ xmlFreeDoc(doc);
+ xmlFreeParserCtxt(ctx);
+ xmlFreeValidCtxt(dtdctx);
+ /* xmlIOParseDTD consumes buffer */
+
+ if (lseek(fd, 0, SEEK_SET) != 0) {
+ fprintf(stderr, "Failed to reset fd, output would be garbage.\n");
+ abort();
+ }
+#endif
+ return rc;
+}
+
#define XML_BUFFER_SIZE 4096
struct location {
@@ -1617,6 +1679,15 @@ int main(int argc, char *argv[])
ctx.protocol = &protocol;
ctx.loc.filename = "<stdin>";
+ if (!is_dtd_valid(input)) {
+ fprintf(stderr,
+ "*******************************************************\n"
+ "* *\n"
+ "* WARNING: XML failed validation against built-in DTD *\n"
+ "* *\n"
+ "*******************************************************\n");
+ }
+
/* create XML parser */
ctx.parser = XML_ParserCreate(NULL);
XML_SetUserData(ctx.parser, &ctx);