5353
5454namespace sta {
5555
56+ // Bus bits are generated from the index range instead of being listed, so the
57+ // range is the one count in the format that costs no bytes to inflate. Two int
58+ // fields can otherwise ask for billions of ports out of a handful of bytes.
59+ static void
60+ checkBusRange (int from_index,
61+ int to_index)
62+ {
63+ int64_t from = from_index;
64+ int64_t to = to_index;
65+ int64_t width = (from < to ? to - from : from - to) + 1 ;
66+ if (width > stadb_max_bus_width)
67+ throw DbCorrupt (sta::format (" stadb bus port has {} bits" , width));
68+ }
69+
5670// Rebuilds liberty libraries by replaying the same construction calls that
5771// LibertyReader makes when parsing a .lib, so derived state ends up identical
5872// without being stored.
@@ -131,25 +145,25 @@ DbLibertyReader::port(uint32_t id) const
131145void
132146DbLibertyReader::readPools ()
133147{
134- uint32_t axis_count = reader_.getU32 ( );
148+ size_t axis_count = reader_.getCount ( " liberty axis " );
135149 axes_.reserve (axis_count);
136- for (uint32_t i = 0 ; i < axis_count; i++) {
150+ for (size_t i = 0 ; i < axis_count; i++) {
137151 uint8_t variable = reader_.getU8 ();
138152 if (variable > static_cast <uint8_t >(TableAxisVariable::unknown))
139153 throw DbCorrupt (" stadb liberty table axis variable out of range" );
140- uint32_t value_count = reader_.getU32 ( );
154+ size_t value_count = reader_.getCount ( " liberty axis value " );
141155 FloatSeq values;
142156 values.reserve (value_count);
143- for (uint32_t v = 0 ; v < value_count; v++)
157+ for (size_t v = 0 ; v < value_count; v++)
144158 values.push_back (reader_.getF32 ());
145159 axes_.push_back (std::make_shared<TableAxis>(
146160 static_cast <TableAxisVariable>(variable),
147161 std::move (values)));
148162 }
149163
150- uint32_t table_count = reader_.getU32 ( );
164+ size_t table_count = reader_.getCount ( " liberty table " );
151165 tables_.reserve (table_count);
152- for (uint32_t i = 0 ; i < table_count; i++) {
166+ for (size_t i = 0 ; i < table_count; i++) {
153167 int order = reader_.getU8 ();
154168 TableAxisPtr axis1 = axis (reader_.getU32 ());
155169 TableAxisPtr axis2 = axis (reader_.getU32 ());
@@ -159,24 +173,24 @@ DbLibertyReader::readPools()
159173 tables_.push_back (std::make_shared<Table>(reader_.getF32 ()));
160174 break ;
161175 case 1 : {
162- uint32_t value_count = reader_.getU32 ( );
176+ size_t value_count = reader_.getCount ( " liberty table value " );
163177 FloatSeq values;
164178 values.reserve (value_count);
165- for (uint32_t v = 0 ; v < value_count; v++)
179+ for (size_t v = 0 ; v < value_count; v++)
166180 values.push_back (reader_.getF32 ());
167181 tables_.push_back (std::make_shared<Table>(std::move (values), axis1));
168182 break ;
169183 }
170184 case 2 :
171185 case 3 : {
172- uint32_t row_count = reader_.getU32 ( );
186+ size_t row_count = reader_.getCount ( " liberty table row " );
173187 FloatTable values;
174188 values.reserve (row_count);
175- for (uint32_t r = 0 ; r < row_count; r++) {
176- uint32_t col_count = reader_.getU32 ( );
189+ for (size_t r = 0 ; r < row_count; r++) {
190+ size_t col_count = reader_.getCount ( " liberty table column " );
177191 FloatSeq row;
178192 row.reserve (col_count);
179- for (uint32_t c = 0 ; c < col_count; c++)
193+ for (size_t c = 0 ; c < col_count; c++)
180194 row.push_back (reader_.getF32 ());
181195 values.push_back (std::move (row));
182196 }
@@ -322,6 +336,7 @@ DbLibertyReader::readPortStructure(LibertyCell *cell)
322336 std::string bus_dcl_name (reader_.getStr ());
323337 BusDcl *bus_dcl = bus_dcl_name.empty ()
324338 ? nullptr : library_->findBusDcl (bus_dcl_name);
339+ checkBusRange (from_index, to_index);
325340 builder_.makeBusPort (cell, name, from_index, to_index, bus_dcl);
326341 break ;
327342 }
@@ -759,9 +774,11 @@ DbNetworkReader::readPort(Cell *cell)
759774{
760775 std::string name (reader_.getStr ());
761776 uint8_t kind = reader_.getU8 ();
762- PortDirection *dir = PortDirection::find (reader_.getCstring ());
763- if (dir == nullptr )
764- throw DbCorrupt (" stadb network port direction unknown" );
777+ // Not getCstring: it hands back null for the empty string, and the lookup
778+ // below reads it as a C string.
779+ std::string dir_name (reader_.getStr ());
780+ PortDirection *dir = dbCheck (PortDirection::find (dir_name.c_str ()),
781+ " network port direction" );
765782
766783 Port *port = nullptr ;
767784 switch (static_cast <DbPortKind>(kind)) {
@@ -771,6 +788,7 @@ DbNetworkReader::readPort(Cell *cell)
771788 case DbPortKind::bus: {
772789 int from_index = reader_.getI32 ();
773790 int to_index = reader_.getI32 ();
791+ checkBusRange (from_index, to_index);
774792 port = network_->makeBusPort (cell, name, from_index, to_index);
775793 break ;
776794 }
@@ -833,9 +851,9 @@ DbNetworkReader::readLibraries()
833851void
834852DbNetworkReader::readCellRefs ()
835853{
836- uint32_t cell_count = reader_.getU32 ( );
854+ size_t cell_count = reader_.getCount ( " network cell ref " );
837855 cells_.reserve (cell_count);
838- for (uint32_t i = 0 ; i < cell_count; i++) {
856+ for (size_t i = 0 ; i < cell_count; i++) {
839857 std::string lib_name (reader_.getStr ());
840858 std::string cell_name (reader_.getStr ());
841859 Library *library = network_->findLibrary (lib_name);
854872DbNetworkReader::readInstances ()
855873{
856874 readCellRefs ();
857- uint32_t inst_count = reader_.getU32 ( );
875+ size_t inst_count = reader_.getCount ( " network instance " );
858876 instances_.reserve (inst_count);
859- for (uint32_t i = 0 ; i < inst_count; i++) {
877+ for (size_t i = 0 ; i < inst_count; i++) {
860878 DbInstanceRec rec;
861879 visit (reader_, rec);
862880 // Parents always precede their children because ids are handed out in
@@ -884,10 +902,10 @@ DbNetworkReader::readInstances()
884902void
885903DbNetworkReader::readNets ()
886904{
887- uint32_t net_count = reader_.getU32 ( );
905+ size_t net_count = reader_.getCount ( " network net " );
888906 std::vector<DbNetRec> recs (net_count);
889907 nets_.reserve (net_count);
890- for (uint32_t i = 0 ; i < net_count; i++) {
908+ for (size_t i = 0 ; i < net_count; i++) {
891909 DbNetRec &rec = recs[i];
892910 visit (reader_, rec);
893911 std::string name (reader_.strings ()->string (rec.name ));
@@ -910,11 +928,11 @@ DbNetworkReader::readNets()
910928void
911929DbNetworkReader::readPins ()
912930{
913- uint32_t pin_count = reader_.getU32 ( );
931+ size_t pin_count = reader_.getCount ( " network pin " );
914932 std::vector<Pin*> pins (pin_count);
915933 std::vector<DbNetworkId> term_nets (pin_count, db_network_id_null);
916934 std::vector<bool > has_term (pin_count, false );
917- for (uint32_t i = 0 ; i < pin_count; i++) {
935+ for (size_t i = 0 ; i < pin_count; i++) {
918936 DbPinRec rec;
919937 visit (reader_, rec);
920938 Instance *inst = instance (rec.instance );
@@ -933,8 +951,8 @@ DbNetworkReader::readPins()
933951
934952 // Terms come last and in their own order, because a net holds its terms in
935953 // creation order and upstream does not create them alongside their pin.
936- uint32_t term_count = reader_.getU32 ( );
937- for (uint32_t i = 0 ; i < term_count; i++) {
954+ size_t term_count = reader_.getCount ( " network term " );
955+ for (size_t i = 0 ; i < term_count; i++) {
938956 uint32_t pin_id = reader_.getU32 ();
939957 if (pin_id >= pin_count || !has_term[pin_id])
940958 throw DbCorrupt (" stadb network term pin index out of range" );
0 commit comments