Package: admesh
Version: 0.98.2-3
Severity: important
Tags: upstream patch
Forwarded: https://github.com/admesh/admesh/pull/26

Dear Maintainer,

Reading binary STLs is broken on big-endian architectures due to the incorrect
little-endian assumption in admesh's STL reading code.

Here's the output from admesh block-binary.stl on partch.debian.org (ppc):
hyperair@partch ~/admesh-0.98.3
 % /usr/bin/admesh block-binary.stl
ADMesh version 0.98.3, Copyright (C) 1995, 1996 Anthony D. Martin
ADMesh comes with NO WARRANTY.  This is free software, and you are welcome to
redistribute it under certain conditions.  See the file COPYING for details.
Opening block-binary.stl
Warning: File size doesn't match number of facets in the header
Checking exact...
All facets connected.  No nearby check necessary.
No unconnected need to be removed.
No holes need to be filled.
Checking normal directions...
Checking normal values...
Calculating volume...
Verifying neighbors...

================= Results produced by ADMesh version 0.98.3 ================
Input file         : block-binary.stl
File type          : Binary STL file
Header             : Processed by ADMesh version 0.98.3
============== Size ==============
Min X = -613977118228749856000863895552.000000, Max X =
-613972282525471397484165070848.000000
Min Y = -613977118228749856000863895552.000000, Max Y =
-613972282525471397484165070848.000000
Min Z = -613977118228749856000863895552.000000, Max Z =
-613972282525471397484165070848.000000
========= Facet Status ========== Original ============ Final ====
Number of facets                 :    12                  12
Facets with 1 disconnected edge  :     0                   0
Facets with 2 disconnected edges :     0                   0
Facets with 3 disconnected edges :     0                   0
Total disconnected facets        :     0                   0
=== Processing Statistics ===     ===== Other Statistics =====
Number of parts       :     1        Volume   :  nan
Degenerate facets     :     0
Edges fixed           :     0
Facets removed        :     0
Facets added          :     0
Facets reversed       :     0
Backwards edges       :     0
Normals fixed         :    12


And the output of admesh with the fix:

hyperair@partch ~/admesh-0.98.3
 % ./admesh block-binary.stl
ADMesh version 0.98.3, Copyright (C) 1995, 1996 Anthony D. Martin
ADMesh comes with NO WARRANTY.  This is free software, and you are welcome to
redistribute it under certain conditions.  See the file COPYING for details.
Opening block-binary.stl
Checking exact...
All facets connected.  No nearby check necessary.
No unconnected need to be removed.
No holes need to be filled.
Checking normal directions...
Checking normal values...
Calculating volume...
Verifying neighbors...

================= Results produced by ADMesh version 0.98.3 ================
Input file         : block-binary.stl
File type          : Binary STL file
Header             : Processed by ADMesh version 0.98.3
============== Size ==============
Min X = -1.968504, Max X =  1.968504
Min Y = -1.968504, Max Y =  1.968504
Min Z = -1.968504, Max Z =  1.968504
========= Facet Status ========== Original ============ Final ====
Number of facets                 :    12                  12
Facets with 1 disconnected edge  :     0                   0
Facets with 2 disconnected edges :     0                   0
Facets with 3 disconnected edges :     0                   0
Total disconnected facets        :     0                   0
=== Processing Statistics ===     ===== Other Statistics =====
Number of parts       :     1        Volume   :  61.023746
Degenerate facets     :     0
Edges fixed           :     0
Facets removed        :     0
Facets added          :     0
Facets reversed       :     0
Backwards edges       :     0
Normals fixed         :     0


I've filed a pull request at https://github.com/admesh/admesh/pull/26 already,
but it might be worth fixing on the Debian side as well.

-- 
Kind regards,
Loong Jin
From f044dd2f807a910c23c998a0a91c69699770c232 Mon Sep 17 00:00:00 2001
From: Chow Loong Jin <[email protected]>
Date: Sun, 1 Oct 2017 17:55:28 +0800
Subject: [PATCH] Fix reading of binary STLs in BE architectures

Also use uint32_t instead of int for header_num_facets as per the binary STL
spec.
---
 src/stlinit.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/src/stlinit.c b/src/stlinit.c
index 40b57a3..da191b2 100644
--- a/src/stlinit.c
+++ b/src/stlinit.c
@@ -20,6 +20,8 @@
  *           https://github.com/admesh/admesh/issues
  */
 
+#include <endian.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -69,7 +71,7 @@ stl_initialize(stl_file *stl) {
 void
 stl_count_facets(stl_file *stl, char *file) {
   long           file_size;
-  int            header_num_facets;
+  uint32_t       header_num_facets;
   int            num_facets;
   int            i, j;
   size_t         s;
@@ -129,7 +131,7 @@ stl_count_facets(stl_file *stl, char *file) {
     }
 
     /* Read the int following the header.  This should contain # of facets */
-    if((!fread(&header_num_facets, sizeof(int), 1, stl->fp)) || (num_facets != header_num_facets)) {
+    if((!fread(&header_num_facets, sizeof(uint32_t), 1, stl->fp)) || (uint32_t)num_facets != le32toh(header_num_facets)) {
       fprintf(stderr,
               "Warning: File size doesn't match number of facets in the header\n");
     }
@@ -253,7 +255,16 @@ stl_reallocate(stl_file *stl) {
 void
 stl_read(stl_file *stl, int first_facet, int first) {
   stl_facet facet;
-  int   i;
+  int   i, j;
+  float *facet_floats[] = {
+    &facet.normal.x, &facet.normal.y, &facet.normal.z,
+    &facet.vertex[0].x, &facet.vertex[0].y, &facet.vertex[0].z,
+    &facet.vertex[1].x, &facet.vertex[1].y, &facet.vertex[1].z,
+    &facet.vertex[2].x, &facet.vertex[2].y, &facet.vertex[2].z
+  };
+  const int facet_float_length = sizeof(facet_floats) / sizeof(*facet_floats);
+  char facet_buffer[facet_float_length * sizeof(float)];
+  uint32_t endianswap_buffer;  /* for byteswapping operations */
 
   if (stl->error) return;
 
@@ -269,14 +280,19 @@ stl_read(stl_file *stl, int first_facet, int first) {
     if(stl->stats.type == binary)
       /* Read a single facet from a binary .STL file */
     {
-      /* we assume little-endian architecture! */
-      if (fread(&facet.normal, sizeof(stl_normal), 1, stl->fp) \
-          + fread(&facet.vertex, sizeof(stl_vertex), 3, stl->fp) \
-          + fread(&facet.extra, sizeof(char), 2, stl->fp) != 6) {
+      if(fread(facet_buffer, sizeof(facet_buffer), 1, stl->fp)
+         + fread(&facet.extra, sizeof(char), 2, stl->fp) != 3) {
         perror("Cannot read facet");
         stl->error = 1;
         return;
       }
+
+      for(j = 0; j < facet_float_length; j++) {
+        /* convert LE float to host byte order */
+        memcpy(&endianswap_buffer, facet_buffer + j * sizeof(float), 4);
+        endianswap_buffer = le32toh(endianswap_buffer);
+        memcpy(facet_floats[j], &endianswap_buffer, 4);
+      }
     } else
       /* Read a single facet from an ASCII .STL file */
     {
-- 
2.11.0

Attachment: signature.asc
Description: PGP signature

Reply via email to