Skip to content

Commit b8859ce

Browse files
sbenzaquencopybara-github
authored andcommitted
Fix stack overflow on very deep public dependency chains.
PiperOrigin-RevId: 953438319
1 parent d03f760 commit b8859ce

1 file changed

Lines changed: 18 additions & 8 deletions

File tree

src/google/protobuf/descriptor.cc

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4449,20 +4449,30 @@ bool internal::DescriptorBuilder::IsInPackage(const FileDescriptor* file,
44494449
file->package()[package_name.size()] == '.');
44504450
}
44514451

4452+
static void RecordAllPublicDepsInto(
4453+
const FileDescriptor* file,
4454+
absl::flat_hash_set<const FileDescriptor*>& out) {
4455+
std::vector<const FileDescriptor*> queue = {file};
4456+
while (!queue.empty()) {
4457+
file = queue.back();
4458+
queue.pop_back();
4459+
4460+
if (file == nullptr || !out.insert(file).second) continue;
4461+
4462+
for (int i = 0; i < file->public_dependency_count(); i++) {
4463+
queue.push_back(file->public_dependency(i));
4464+
}
4465+
}
4466+
}
4467+
44524468
void internal::DescriptorBuilder::RecordPublicDependencies(
44534469
const FileDescriptor* file) {
4454-
if (file == nullptr || !dependencies_.insert(file).second) return;
4455-
for (int i = 0; file != nullptr && i < file->public_dependency_count(); i++) {
4456-
RecordPublicDependencies(file->public_dependency(i));
4457-
}
4470+
RecordAllPublicDepsInto(file, dependencies_);
44584471
}
44594472

44604473
void internal::DescriptorBuilder::RecordPublicOptionDependencies(
44614474
const FileDescriptor* file) {
4462-
if (file == nullptr || !option_dependencies_.insert(file).second) return;
4463-
for (int i = 0; i < file->public_dependency_count(); i++) {
4464-
RecordPublicOptionDependencies(file->public_dependency(i));
4465-
}
4475+
RecordAllPublicDepsInto(file, option_dependencies_);
44664476
}
44674477

44684478
Symbol internal::DescriptorBuilder::FindSymbolNotEnforcingDepsHelper(

0 commit comments

Comments
 (0)