Skip to content

Commit

Permalink
[powershell-experimental] Protects against stackoverflow when OAS spe…
Browse files Browse the repository at this point in the history
…c has circular references (OpenAPITools#5646)

* protects against stackoverflow when OAS spec has circular references

* protects against stackoverflow when OAS spec has circular references
  • Loading branch information
vvb authored and michaelpro1 committed May 7, 2020
1 parent 139714d commit a54f141
Showing 1 changed file with 20 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ public String toParamName(String name) {
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
HashMap<String, CodegenModel> modelMaps = new HashMap<String, CodegenModel>();
HashMap<String, Boolean> processedModelMaps = new HashMap<String, Boolean>();

for (Object o : allModels) {
HashMap<String, Object> h = (HashMap<String, Object>) o;
Expand All @@ -606,7 +607,7 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
int index = 0;
for (CodegenParameter p : op.allParams) {
p.vendorExtensions.put("x-powershell-data-type", getPSDataType(p));
p.vendorExtensions.put("x-powershell-example", constructExampleCode(p, modelMaps));
p.vendorExtensions.put("x-powershell-example", constructExampleCode(p, modelMaps, processedModelMaps));
p.vendorExtensions.put("x-index", index);
index++;
}
Expand All @@ -620,9 +621,10 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
}
}

processedModelMaps.clear();
for (CodegenOperation operation : operationList) {
for (CodegenParameter cp : operation.allParams) {
cp.vendorExtensions.put("x-powershell-example", constructExampleCode(cp, modelMaps));
cp.vendorExtensions.put("x-powershell-example", constructExampleCode(cp, modelMaps, processedModelMaps));
}
}

Expand Down Expand Up @@ -670,9 +672,9 @@ public String toVarName(String name) {
return name;
}

private String constructExampleCode(CodegenParameter codegenParameter, HashMap<String, CodegenModel> modelMaps) {
private String constructExampleCode(CodegenParameter codegenParameter, HashMap<String, CodegenModel> modelMaps, HashMap<String, Boolean> processedModelMap) {
if (codegenParameter.isListContainer) { // array
return "@(" + constructExampleCode(codegenParameter.items, modelMaps) + ")";
return "@(" + constructExampleCode(codegenParameter.items, modelMaps, processedModelMap) + ")";
} else if (codegenParameter.isMapContainer) { // TODO: map, file type
return "\"TODO\"";
} else if (languageSpecificPrimitives.contains(codegenParameter.dataType) ||
Expand Down Expand Up @@ -704,17 +706,17 @@ private String constructExampleCode(CodegenParameter codegenParameter, HashMap<S
} else { // model
// look up the model
if (modelMaps.containsKey(codegenParameter.dataType)) {
return constructExampleCode(modelMaps.get(codegenParameter.dataType), modelMaps);
return constructExampleCode(modelMaps.get(codegenParameter.dataType), modelMaps, processedModelMap);
} else {
//LOGGER.error("Error in constructing examples. Failed to look up the model " + codegenParameter.dataType);
return "TODO";
}
}
}

private String constructExampleCode(CodegenProperty codegenProperty, HashMap<String, CodegenModel> modelMaps) {
private String constructExampleCode(CodegenProperty codegenProperty, HashMap<String, CodegenModel> modelMaps, HashMap<String, Boolean> processedModelMap) {
if (codegenProperty.isListContainer) { // array
return "@(" + constructExampleCode(codegenProperty.items, modelMaps) + ")";
return "@(" + constructExampleCode(codegenProperty.items, modelMaps, processedModelMap) + ")";
} else if (codegenProperty.isMapContainer) { // map
return "\"TODO\"";
} else if (languageSpecificPrimitives.contains(codegenProperty.dataType) || // primitive type
Expand Down Expand Up @@ -746,20 +748,28 @@ private String constructExampleCode(CodegenProperty codegenProperty, HashMap<Str
} else {
// look up the model
if (modelMaps.containsKey(codegenProperty.dataType)) {
return constructExampleCode(modelMaps.get(codegenProperty.dataType), modelMaps);
return constructExampleCode(modelMaps.get(codegenProperty.dataType), modelMaps, processedModelMap);
} else {
//LOGGER.error("Error in constructing examples. Failed to look up the model " + codegenProperty.dataType);
return "\"TODO\"";
}
}
}

private String constructExampleCode(CodegenModel codegenModel, HashMap<String, CodegenModel> modelMaps) {
private String constructExampleCode(CodegenModel codegenModel, HashMap<String, CodegenModel> modelMaps, HashMap<String, Boolean> processedModelMap) {
String example;

// break infinite recursion. Return, in case a model is already processed in the current context.
String model = codegenModel.name;
if (processedModelMap.containsKey(model)) {
return "";
}
processedModelMap.put(model, true);

example = "(New-" + codegenModel.name;
List<String> propertyExamples = new ArrayList<>();
for (CodegenProperty codegenProperty : codegenModel.vars) {
propertyExamples.add(" -" + codegenProperty.name + " " + constructExampleCode(codegenProperty, modelMaps));
propertyExamples.add(" -" + codegenProperty.name + " " + constructExampleCode(codegenProperty, modelMaps, processedModelMap));
}
example += StringUtils.join(propertyExamples, " ");
example += ")";
Expand Down

0 comments on commit a54f141

Please sign in to comment.