Permalink
Browse files

Break out PackFile_Header validation from PackFile_unpack into a new …

…function
  • Loading branch information...
aantn committed Jan 1, 2011
1 parent 28f157a commit 82bc505f785cee52366bc9e4518eabb47ce36a2c
Showing with 71 additions and 36 deletions.
  1. +10 −0 include/parrot/packfile.h
  2. +61 −36 src/packfile/api.c
View
@@ -712,6 +712,13 @@ void PackFile_funcs_register(SHIM_INTERP,
__attribute__nonnull__(2)
FUNC_MODIFIES(*pf);
+PARROT_EXPORT
+void PackFile_Header_validate(PARROT_INTERP,
+ ARGIN(const PackFile_Header *self),
+ INTVAL pf_options)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
+
PARROT_EXPORT
INTVAL PackFile_map_segments(PARROT_INTERP,
ARGIN(const PackFile_Directory *dir),
@@ -948,6 +955,9 @@ void Parrot_trace_eprintf(ARGIN(const char *s), ...)
PARROT_ASSERT_ARG(interp))
#define ASSERT_ARGS_PackFile_funcs_register __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(pf))
+#define ASSERT_ARGS_PackFile_Header_validate __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(self))
#define ASSERT_ARGS_PackFile_map_segments __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(dir))
View
@@ -676,6 +676,65 @@ mark_const_subs(PARROT_INTERP)
+/*
+
+=item C<void PackFile_Header_validate(PARROT_INTERP, const PackFile_Header
+*self, INTVAL pf_options)>
+
+Validates a C<PackFile_Header>, ensuring that the magic number is valid and
+that Parrot can read this bytecode version.
+
+Raises an exception if the header doesn't validate.
+=cut
+
+*/
+
+PARROT_EXPORT
+void
+PackFile_Header_validate(PARROT_INTERP, ARGIN(const PackFile_Header *self),
+ INTVAL pf_options)
+{
+ ASSERT_ARGS(PackFile_Header_validate)
+
+ /* Ensure the magic is correct. */
+ if (memcmp(self->magic, "\376PBC\r\n\032\n", 8) != 0) {
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
+ "PackFile_unpack: This is not a valid Parrot bytecode file.");
+ }
+
+ /* Ensure the bytecode version is one we can read. Currently, we only
+ * support bytecode versions matching the current one.
+ *
+ * tools/dev/pbc_header.pl --upd t/native_pbc/(ASTERISK).pbc
+ * stamps version and fingerprint in the native tests.
+ * NOTE: (ASTERISK) is *, we don't want to fool the C preprocessor. */
+ if (self->bc_major != PARROT_PBC_MAJOR
+ || self->bc_minor != PARROT_PBC_MINOR) {
+ if (!(pf_options & PFOPT_UTILS))
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PARROT_USAGE_ERROR,
+ "PackFile_unpack: This Parrot cannot read bytecode "
+ "files with version %d.%d.",
+ self->bc_major, self->bc_minor);
+ }
+
+ /* Check wordsize, byte order and floating point number type are valid. */
+ if (self->wordsize != 4 && self->wordsize != 8) {
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
+ "PackFile_unpack: Invalid wordsize %d\n", self->wordsize);
+ }
+
+ if (self->byteorder != 0 && self->byteorder != 1) {
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
+ "PackFile_unpack: Invalid byte ordering %d\n", self->byteorder);
+ }
+
+ if (self->floattype > FLOATTYPE_MAX) {
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
+ "PackFile_unpack: Invalid floattype %d\n", self->floattype);
+ }
+}
+
+
/*
=item C<opcode_t PackFile_unpack(PARROT_INTERP, PackFile *self, const opcode_t
@@ -718,42 +777,8 @@ PackFile_unpack(PARROT_INTERP, ARGMOD(PackFile *self),
/* Extract the header. */
memcpy(header, packed, PACKFILE_HEADER_BYTES);
- /* Ensure the magic is correct. */
- if (memcmp(header->magic, "\376PBC\r\n\032\n", 8) != 0) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
- "PackFile_unpack: This is not a valid Parrot bytecode file.");
- }
-
- /* Ensure the bytecode version is one we can read. Currently, we only
- * support bytecode versions matching the current one.
- *
- * tools/dev/pbc_header.pl --upd t/native_pbc/(ASTERISK).pbc
- * stamps version and fingerprint in the native tests.
- * NOTE: (ASTERISK) is *, we don't want to fool the C preprocessor. */
- if (header->bc_major != PARROT_PBC_MAJOR
- || header->bc_minor != PARROT_PBC_MINOR) {
- if (!(self->options & PFOPT_UTILS))
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PARROT_USAGE_ERROR,
- "PackFile_unpack: This Parrot cannot read bytecode "
- "files with version %d.%d.",
- header->bc_major, header->bc_minor);
- }
-
- /* Check wordsize, byte order and floating point number type are valid. */
- if (header->wordsize != 4 && header->wordsize != 8) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
- "PackFile_unpack: Invalid wordsize %d\n", header->wordsize);
- }
-
- if (header->byteorder != 0 && header->byteorder != 1) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
- "PackFile_unpack: Invalid byte ordering %d\n", header->byteorder);
- }
-
- if (header->floattype > FLOATTYPE_MAX) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_MALFORMED_PACKFILE,
- "PackFile_unpack: Invalid floattype %d\n", header->floattype);
- }
+ /* Validate the header. */
+ PackFile_Header_validate(interp, self->header, self->options);
/* Describe what was read for debugging. */
TRACE_PRINTF(("PackFile_unpack: Wordsize %d.\n", header->wordsize));

0 comments on commit 82bc505

Please sign in to comment.