LCOV - code coverage report
Current view: top level - gcc/rust/metadata - rust-extern-crate.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 79.4 % 68 54
Test Date: 2024-03-23 14:05:01 Functions: 75.0 % 8 6
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2020-2024 Free Software Foundation, Inc.
       2                 :             : 
       3                 :             : // This file is part of GCC.
       4                 :             : 
       5                 :             : // GCC is free software; you can redistribute it and/or modify it under
       6                 :             : // the terms of the GNU General Public License as published by the Free
       7                 :             : // Software Foundation; either version 3, or (at your option) any later
       8                 :             : // version.
       9                 :             : 
      10                 :             : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11                 :             : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12                 :             : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13                 :             : // for more details.
      14                 :             : 
      15                 :             : // You should have received a copy of the GNU General Public License
      16                 :             : // along with GCC; see the file COPYING3.  If not see
      17                 :             : // <http://www.gnu.org/licenses/>.
      18                 :             : 
      19                 :             : #include "rust-extern-crate.h"
      20                 :             : #include "rust-diagnostics.h"
      21                 :             : #include "rust-export-metadata.h"
      22                 :             : 
      23                 :             : #include "md5.h"
      24                 :             : 
      25                 :             : namespace Rust {
      26                 :             : namespace Imports {
      27                 :             : 
      28                 :          16 : ExternCrate::ExternCrate (Import::Stream &stream) : import_stream (stream) {}
      29                 :             : 
      30                 :           0 : ExternCrate::ExternCrate (const std::string &crate_name,
      31                 :           0 :                           std::vector<ProcMacro::Procmacro> macros)
      32                 :           0 :   : proc_macros (macros), crate_name (crate_name)
      33                 :           0 : {}
      34                 :             : 
      35                 :          16 : ExternCrate::~ExternCrate () {}
      36                 :             : 
      37                 :             : bool
      38                 :           0 : ExternCrate::ok () const
      39                 :             : {
      40                 :           0 :   return !import_stream->get ().saw_error ();
      41                 :             : }
      42                 :             : 
      43                 :             : bool
      44                 :          16 : ExternCrate::load (location_t locus)
      45                 :             : {
      46                 :          16 :   rust_assert (this->import_stream.has_value ());
      47                 :          16 :   auto &import_stream = this->import_stream->get ();
      48                 :             :   // match header
      49                 :          16 :   import_stream.require_bytes (locus, Metadata::kMagicHeader,
      50                 :             :                                sizeof (Metadata::kMagicHeader));
      51                 :          16 :   if (import_stream.saw_error ())
      52                 :             :     return false;
      53                 :             : 
      54                 :             :   // parse 16 bytes md5
      55                 :          16 :   unsigned char checksum[16];
      56                 :          16 :   bool ok
      57                 :          16 :     = import_stream.do_peek (sizeof (checksum), (const char **) &checksum);
      58                 :          16 :   if (!ok)
      59                 :             :     return false;
      60                 :             : 
      61                 :          16 :   import_stream.advance (sizeof (checksum));
      62                 :             : 
      63                 :             :   // parse delim
      64                 :          16 :   import_stream.require_bytes (locus, Metadata::kSzDelim,
      65                 :             :                                sizeof (Metadata::kSzDelim));
      66                 :          16 :   if (import_stream.saw_error ())
      67                 :             :     return false;
      68                 :             : 
      69                 :             :   // parse crate name
      70                 :             :   bool saw_delim = false;
      71                 :         592 :   while (!import_stream.saw_error () && !import_stream.at_eof ())
      72                 :             :     {
      73                 :         296 :       unsigned char byte = import_stream.get_char ();
      74                 :         296 :       saw_delim
      75                 :         296 :         = memcmp (&byte, Metadata::kSzDelim, sizeof (Metadata::kSzDelim)) == 0;
      76                 :         296 :       if (saw_delim)
      77                 :             :         break;
      78                 :             : 
      79                 :         280 :       crate_name += byte;
      80                 :             :     }
      81                 :          16 :   if (!saw_delim || crate_name.empty ())
      82                 :             :     {
      83                 :           0 :       import_stream.set_saw_error ();
      84                 :           0 :       rust_error_at (locus, "failed to read crate name field");
      85                 :             : 
      86                 :           0 :       return false;
      87                 :             :     }
      88                 :             : 
      89                 :             :   // read until delim which is the size of the meta data
      90                 :          16 :   std::string metadata_length_buffer;
      91                 :          16 :   saw_delim = false;
      92                 :         112 :   while (!import_stream.saw_error () && !import_stream.at_eof ())
      93                 :             :     {
      94                 :          56 :       unsigned char byte = import_stream.get_char ();
      95                 :          56 :       saw_delim
      96                 :          56 :         = memcmp (&byte, Metadata::kSzDelim, sizeof (Metadata::kSzDelim)) == 0;
      97                 :          56 :       if (saw_delim)
      98                 :             :         break;
      99                 :             : 
     100                 :          40 :       metadata_length_buffer += byte;
     101                 :             :     }
     102                 :          16 :   if (!saw_delim || metadata_length_buffer.empty ())
     103                 :             :     {
     104                 :           0 :       import_stream.set_saw_error ();
     105                 :           0 :       rust_error_at (locus, "failed to read metatadata size");
     106                 :             : 
     107                 :           0 :       return false;
     108                 :             :     }
     109                 :             : 
     110                 :             :   // interpret the string size
     111                 :          16 :   int expected_buffer_length = -1;
     112                 :          16 :   ok = ExternCrate::string_to_int (locus, metadata_length_buffer, false,
     113                 :             :                                    &expected_buffer_length);
     114                 :          16 :   if (!ok)
     115                 :             :     return false;
     116                 :             : 
     117                 :             :   // read the parsed size and it should be eof
     118                 :          16 :   metadata_buffer.reserve (expected_buffer_length);
     119                 :        1384 :   for (int i = 0; i < expected_buffer_length && !import_stream.saw_error ()
     120                 :        2752 :                   && !import_stream.at_eof ();
     121                 :             :        i++)
     122                 :             :     {
     123                 :        1368 :       metadata_buffer += import_stream.get_char ();
     124                 :             :     }
     125                 :             : 
     126                 :             :   // compute the md5
     127                 :          16 :   struct md5_ctx chksm;
     128                 :          16 :   unsigned char computed_checksum[16];
     129                 :             : 
     130                 :          16 :   md5_init_ctx (&chksm);
     131                 :          16 :   md5_process_bytes (metadata_buffer.c_str (), metadata_buffer.size (), &chksm);
     132                 :          16 :   md5_finish_ctx (&chksm, computed_checksum);
     133                 :             : 
     134                 :             :   // FIXME i think the encoding and decoding of md5 is going wrong or else we
     135                 :             :   // are not computing it correctly
     136                 :             :   //
     137                 :             :   // compare the checksums
     138                 :             :   // if (memcmp(computed_checksum, checksum, sizeof (checksum)) != 0)
     139                 :             :   //   {
     140                 :             :   //     rust_error_at (locus,
     141                 :             :   //                 "checksum mismatch in metadata: %<%.*s%> vs %<%.*s%>",
     142                 :             :   //                 sizeof (computed_checksum), computed_checksum,
     143                 :             :   //                 sizeof (checksum), checksum);
     144                 :             :   //     return false;
     145                 :             :   //   }
     146                 :             : 
     147                 :             :   // all good
     148                 :          16 :   return true;
     149                 :          16 : }
     150                 :             : 
     151                 :             : const std::string &
     152                 :          32 : ExternCrate::get_crate_name () const
     153                 :             : {
     154                 :          32 :   return crate_name;
     155                 :             : }
     156                 :             : 
     157                 :             : const std::string &
     158                 :          16 : ExternCrate::get_metadata () const
     159                 :             : {
     160                 :          16 :   return metadata_buffer;
     161                 :             : }
     162                 :             : 
     163                 :             : // Turn a string into a integer with appropriate error handling.
     164                 :             : bool
     165                 :          16 : ExternCrate::string_to_int (location_t locus, const std::string &s,
     166                 :             :                             bool is_neg_ok, int *ret)
     167                 :             : {
     168                 :          16 :   char *end;
     169                 :          16 :   long prio = strtol (s.c_str (), &end, 10);
     170                 :          16 :   if (*end != '\0' || prio > 0x7fffffff || (prio < 0 && !is_neg_ok))
     171                 :             :     {
     172                 :           0 :       rust_error_at (locus, "invalid integer in import data");
     173                 :           0 :       return false;
     174                 :             :     }
     175                 :          16 :   *ret = prio;
     176                 :          16 :   return true;
     177                 :             : }
     178                 :             : 
     179                 :             : } // namespace Imports
     180                 :             : } // namespace Rust
        

Generated by: LCOV version 2.0-1

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.