Skip to content

Commit f4271fa

Browse files
authored
Fix a few issues with the C generator (part 3) (#20269)
* [C] Clear the response code from previous api calls Before making an api call, reset apiClient->response_code to zero. That will protect us from checking stale values if the curl request fails. * [C] Check that string arguments are not null Check early on that the arguments are not null, to prevent crashes on strdup() calls. * [C] Don't attempt to fill in a type with error info Check if the api call returned an error before attempting to parse the reply as the expected type. * [C] Handle binary and integer return types * [C] Update test schemas with binary and integer return types * Update samples
1 parent 0a7e784 commit f4271fa

File tree

16 files changed

+955
-201
lines changed

16 files changed

+955
-201
lines changed

modules/openapi-generator/src/main/resources/C-libcurl/api-body.mustache

Lines changed: 70 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ end:
9898
// {{{.}}}
9999
//
100100
{{/notes}}
101-
{{#returnType}}{{#returnTypeIsPrimitive}}{{#returnSimpleType}}{{{.}}}*{{/returnSimpleType}}{{^returnSimpleType}}{{#isArray}}{{{.}}}_t*{{/isArray}}{{#isMap}}{{{.}}}{{/isMap}}{{/returnSimpleType}}{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}{{#returnProperty}}{{^isEnum}}{{{returnType}}}_t*{{/isEnum}}{{#isEnum}}{{projectName}}_{{{returnType}}}_{{returnEnumName}}_e{{/isEnum}}{{/returnProperty}}{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}void{{/returnType}}
101+
{{#returnType}}{{#returnTypeIsPrimitive}}{{#returnSimpleType}}{{{.}}}{{#returnProperty}}{{#isString}}*{{/isString}}{{/returnProperty}}{{/returnSimpleType}}{{^returnSimpleType}}{{#isArray}}{{{.}}}_t*{{/isArray}}{{#isMap}}{{{.}}}{{/isMap}}{{/returnSimpleType}}{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}{{#returnProperty}}{{^isEnum}}{{{returnType}}}_t*{{/isEnum}}{{#isEnum}}{{projectName}}_{{{returnType}}}_{{returnEnumName}}_e{{/isEnum}}{{/returnProperty}}{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}void{{/returnType}}
102102
{{{classname}}}_{{{operationId}}}(apiClient_t *apiClient{{#allParams}}, {{#isPrimitiveType}}{{#isNumber}}{{{dataType}}} {{/isNumber}}{{#isLong}}{{{dataType}}} {{/isLong}}{{#isInteger}}{{{dataType}}} *{{/isInteger}}{{#isDouble}}{{{dataType}}} {{/isDouble}}{{#isFloat}}{{{dataType}}} {{/isFloat}}{{#isBoolean}}{{dataType}} *{{/isBoolean}}{{#isEnum}}{{#isString}}{{projectName}}_{{operationId}}_{{baseName}}_e {{/isString}}{{/isEnum}}{{^isEnum}}{{#isString}}{{{dataType}}} *{{/isString}}{{/isEnum}}{{#isByteArray}}{{{dataType}}} *{{/isByteArray}}{{#isDate}}{{{dataType}}} {{/isDate}}{{#isDateTime}}{{{dataType}}} {{/isDateTime}}{{#isFile}}{{{dataType}}} {{/isFile}}{{#isFreeFormObject}}{{dataType}}_t *{{/isFreeFormObject}}{{/isPrimitiveType}}{{^isArray}}{{^isPrimitiveType}}{{#isModel}}{{#isEnum}}{{datatypeWithEnum}}_e {{/isEnum}}{{^isEnum}}{{{dataType}}}_t *{{/isEnum}}{{/isModel}}{{^isModel}}{{#isEnum}}{{datatypeWithEnum}}_e {{/isEnum}}{{/isModel}}{{#isUuid}}{{dataType}} *{{/isUuid}}{{#isEmail}}{{dataType}} {{/isEmail}}{{/isPrimitiveType}}{{/isArray}}{{#isContainer}}{{#isArray}}{{dataType}}_t *{{/isArray}}{{#isMap}}{{dataType}} {{/isMap}}{{/isContainer}}{{{paramName}}}{{/allParams}})
103103
{
104104
list_t *localVarQueryParameters = {{#hasQueryParams}}list_createList();{{/hasQueryParams}}{{^hasQueryParams}}NULL;{{/hasQueryParams}}
@@ -108,11 +108,21 @@ end:
108108
list_t *localVarContentType = {{#hasConsumes}}list_createList();{{/hasConsumes}}{{^hasConsumes}}NULL;{{/hasConsumes}}
109109
char *localVarBodyParameters = NULL;
110110

111+
// clear the error code from the previous api call
112+
apiClient->response_code = 0;
113+
111114
// create the path
112115
long sizeOfPath = strlen("{{{path}}}")+1;
113116
char *localVarPath = malloc(sizeOfPath);
114117
snprintf(localVarPath, sizeOfPath, "{{{path}}}");
115118

119+
{{#pathParams}}
120+
{{#isString}}
121+
if(!{{paramName}})
122+
goto end;
123+
{{/isString}}
124+
{{/pathParams}}
125+
116126
{{#pathParams}}
117127

118128
// Path Params
@@ -363,51 +373,80 @@ end:
363373
{{#returnType}}
364374
{{#returnTypeIsPrimitive}}
365375
{{#returnSimpleType}}
366-
//primitive return type simple
367-
{{returnType}}* elementToReturn = strdup(({{returnType}}*)apiClient->dataReceived);
376+
{{#returnProperty}}
377+
{{#isBinary}}
378+
//primitive return type simple binary
379+
{{returnType}} elementToReturn = NULL;
380+
if(apiClient->response_code >= 200 && apiClient->response_code < 300)
381+
elementToReturn = instantiate_binary_t(apiClient->dataReceived, apiClient->dataReceivedLen);
382+
383+
{{/isBinary}}
384+
{{#isString}}
385+
//primitive return type simple string
386+
{{returnType}}* elementToReturn = NULL;
387+
if(apiClient->response_code >= 200 && apiClient->response_code < 300)
388+
elementToReturn = strdup(({{returnType}}*)apiClient->dataReceived);
368389

390+
{{/isString}}
391+
{{#isInteger}}
392+
//primitive return type simple integer
393+
{{returnType}} elementToReturn = 0;
394+
if(apiClient->response_code >= 200 && apiClient->response_code < 300)
395+
elementToReturn = atoi(apiClient->dataReceived);
396+
397+
{{/isInteger}}
398+
{{/returnProperty}}
369399
{{/returnSimpleType}}
370400
{{^returnSimpleType}}
371401
//primitive return type not simple
372-
cJSON *{{paramName}}localVarJSON = cJSON_Parse(apiClient->dataReceived);
373-
cJSON *{{{paramName}}}VarJSON;
374-
list_t *elementToReturn = list_createList();
375-
cJSON_ArrayForEach({{{paramName}}}VarJSON, {{paramName}}localVarJSON){
376-
keyValuePair_t *keyPair = keyValuePair_create(strdup({{{paramName}}}VarJSON->string), {{{cJSONPrint}}}({{{paramName}}}VarJSON));
377-
list_addElement(elementToReturn, keyPair);
402+
list_t *elementToReturn = NULL;
403+
if(apiClient->response_code >= 200 && apiClient->response_code < 300) {
404+
cJSON *{{paramName}}localVarJSON = cJSON_Parse(apiClient->dataReceived);
405+
cJSON *{{{paramName}}}VarJSON;
406+
elementToReturn = list_createList();
407+
cJSON_ArrayForEach({{{paramName}}}VarJSON, {{paramName}}localVarJSON){
408+
keyValuePair_t *keyPair = keyValuePair_create(strdup({{{paramName}}}VarJSON->string), {{{cJSONPrint}}}({{{paramName}}}VarJSON));
409+
list_addElement(elementToReturn, keyPair);
410+
}
411+
cJSON_Delete({{paramName}}localVarJSON);
378412
}
379-
cJSON_Delete({{paramName}}localVarJSON);
380413

381414
{{/returnSimpleType}}
382415
{{/returnTypeIsPrimitive}}
383416
{{^returnTypeIsPrimitive}}
384417
{{#returnContainer}}
385-
cJSON *{{classname}}localVarJSON = cJSON_Parse(apiClient->dataReceived);
386-
if(!cJSON_IsArray({{classname}}localVarJSON)) {
387-
return 0;//nonprimitive container
388-
}
389-
list_t *elementToReturn = list_createList();
390-
cJSON *{{{paramName}}}VarJSON;
391-
cJSON_ArrayForEach({{{paramName}}}VarJSON, {{classname}}localVarJSON)
392-
{
393-
if(!cJSON_IsObject({{{paramName}}}VarJSON))
418+
list_t *elementToReturn = NULL;
419+
if(apiClient->response_code >= 200 && apiClient->response_code < 300) {
420+
cJSON *{{classname}}localVarJSON = cJSON_Parse(apiClient->dataReceived);
421+
if(!cJSON_IsArray({{classname}}localVarJSON)) {
422+
return 0;//nonprimitive container
423+
}
424+
elementToReturn = list_createList();
425+
cJSON *{{{paramName}}}VarJSON;
426+
cJSON_ArrayForEach({{{paramName}}}VarJSON, {{classname}}localVarJSON)
394427
{
395-
// return 0;
428+
if(!cJSON_IsObject({{{paramName}}}VarJSON))
429+
{
430+
// return 0;
431+
}
432+
char *localVarJSONToChar = {{{cJSONPrint}}}({{{paramName}}}VarJSON);
433+
list_addElement(elementToReturn , localVarJSONToChar);
396434
}
397-
char *localVarJSONToChar = {{{cJSONPrint}}}({{{paramName}}}VarJSON);
398-
list_addElement(elementToReturn , localVarJSONToChar);
399-
}
400435

401-
cJSON_Delete( {{classname}}localVarJSON);
402-
cJSON_Delete( {{{paramName}}}VarJSON);
436+
cJSON_Delete( {{classname}}localVarJSON);
437+
cJSON_Delete( {{{paramName}}}VarJSON);
438+
}
403439
{{/returnContainer}}
404440
{{^returnContainer}}
405441
//nonprimitive not container
406-
cJSON *{{classname}}localVarJSON = cJSON_Parse(apiClient->dataReceived);
407-
{{#returnProperty}}{{^isEnum}}{{{returnBaseType}}}_t *{{/isEnum}}{{#isEnum}}{{projectName}}_{{{returnType}}}_{{returnEnumName}}_e {{/isEnum}}{{/returnProperty}}elementToReturn = {{{returnBaseType}}}_parseFromJSON({{classname}}localVarJSON);
408-
cJSON_Delete({{classname}}localVarJSON);
409-
if(elementToReturn == {{#returnProperty}}{{^isEnum}}NULL{{/isEnum}}{{#isEnum}}0{{/isEnum}}{{/returnProperty}}) {
410-
// return 0;
442+
{{#returnProperty}}{{^isEnum}}{{{returnBaseType}}}_t *{{/isEnum}}{{#isEnum}}{{projectName}}_{{{returnType}}}_{{returnEnumName}}_e {{/isEnum}}{{/returnProperty}}elementToReturn = {{#returnProperty}}{{^isEnum}}NULL{{/isEnum}}{{#isEnum}}0{{/isEnum}}{{/returnProperty}};
443+
if(apiClient->response_code >= 200 && apiClient->response_code < 300) {
444+
cJSON *{{classname}}localVarJSON = cJSON_Parse(apiClient->dataReceived);
445+
elementToReturn = {{{returnBaseType}}}_parseFromJSON({{classname}}localVarJSON);
446+
cJSON_Delete({{classname}}localVarJSON);
447+
if(elementToReturn == {{#returnProperty}}{{^isEnum}}NULL{{/isEnum}}{{#isEnum}}0{{/isEnum}}{{/returnProperty}}) {
448+
// return 0;
449+
}
411450
}
412451

413452
{{/returnContainer}}
@@ -550,7 +589,7 @@ end:
550589
return elementToReturn;
551590
end:
552591
free(localVarPath);
553-
return {{#returnProperty}}{{^isEnum}}NULL{{/isEnum}}{{#isEnum}}0{{/isEnum}}{{/returnProperty}};
592+
return {{#returnProperty}}{{#isInteger}}0{{/isInteger}}{{^isInteger}}{{^isEnum}}NULL{{/isEnum}}{{#isEnum}}0{{/isEnum}}{{/isInteger}}{{/returnProperty}};
554593
{{/returnType}}
555594
{{^returnType}}
556595
//No return type

modules/openapi-generator/src/main/resources/C-libcurl/api-header.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ typedef enum { {{projectName}}_{{operationId}}_{{enumName}}_NULL = 0{{#enumVars
3232
// {{{.}}}
3333
//
3434
{{/notes}}
35-
{{#returnType}}{{#returnTypeIsPrimitive}}{{#returnSimpleType}}{{{.}}}*{{/returnSimpleType}}{{^returnSimpleType}}{{#isArray}}{{{.}}}_t*{{/isArray}}{{#isMap}}{{{.}}}{{/isMap}}{{/returnSimpleType}}{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}{{#returnProperty}}{{^isEnum}}{{{returnType}}}_t*{{/isEnum}}{{#isEnum}}{{projectName}}_{{{returnType}}}_{{returnEnumName}}_e{{/isEnum}}{{/returnProperty}}{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}void{{/returnType}}
35+
{{#returnType}}{{#returnTypeIsPrimitive}}{{#returnSimpleType}}{{{.}}}{{#returnProperty}}{{#isString}}*{{/isString}}{{/returnProperty}}{{/returnSimpleType}}{{^returnSimpleType}}{{#isArray}}{{{.}}}_t*{{/isArray}}{{#isMap}}{{{.}}}{{/isMap}}{{/returnSimpleType}}{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}{{#returnProperty}}{{^isEnum}}{{{returnType}}}_t*{{/isEnum}}{{#isEnum}}{{projectName}}_{{{returnType}}}_{{returnEnumName}}_e{{/isEnum}}{{/returnProperty}}{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}void{{/returnType}}
3636
{{{classname}}}_{{{operationId}}}(apiClient_t *apiClient{{#allParams}}, {{#isPrimitiveType}}{{#isNumber}}{{{dataType}}} {{/isNumber}}{{#isLong}}{{{dataType}}} {{/isLong}}{{#isInteger}}{{{dataType}}} *{{/isInteger}}{{#isDouble}}{{{dataType}}} {{/isDouble}}{{#isFloat}}{{{dataType}}} {{/isFloat}}{{#isBoolean}}{{dataType}} *{{/isBoolean}}{{#isEnum}}{{#isString}}{{projectName}}_{{operationId}}_{{baseName}}_e {{/isString}}{{/isEnum}}{{^isEnum}}{{#isString}}{{{dataType}}} *{{/isString}}{{/isEnum}}{{#isByteArray}}{{{dataType}}} *{{/isByteArray}}{{#isDate}}{{{dataType}}} {{/isDate}}{{#isDateTime}}{{{dataType}}} {{/isDateTime}}{{#isFile}}{{{dataType}}} {{/isFile}}{{#isFreeFormObject}}{{dataType}}_t *{{/isFreeFormObject}}{{/isPrimitiveType}}{{^isArray}}{{^isPrimitiveType}}{{#isModel}}{{#isEnum}}{{datatypeWithEnum}}_e {{/isEnum}}{{^isEnum}}{{{dataType}}}_t *{{/isEnum}}{{/isModel}}{{^isModel}}{{#isEnum}}{{datatypeWithEnum}}_e {{/isEnum}}{{/isModel}}{{#isUuid}}{{dataType}} *{{/isUuid}}{{#isEmail}}{{dataType}} {{/isEmail}}{{/isPrimitiveType}}{{/isArray}}{{#isContainer}}{{#isArray}}{{dataType}}_t *{{/isArray}}{{#isMap}}{{dataType}} {{/isMap}}{{/isContainer}}{{{paramName}}}{{/allParams}});
3737

3838

modules/openapi-generator/src/test/resources/2_0/c/petstore.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,19 @@ paths:
254254
- 'write:pets'
255255
- 'read:pets'
256256
/pet/picture:
257+
get:
258+
tags:
259+
- pet
260+
summary: Get a random picture of someone else's pet
261+
description: ''
262+
operationId: getPicture
263+
parameters: []
264+
responses:
265+
'200':
266+
description: successful operation
267+
schema:
268+
type: string
269+
format: binary
257270
post:
258271
tags:
259272
- pet
@@ -335,6 +348,19 @@ paths:
335348
- petstore_auth:
336349
- 'write:pets'
337350
- 'read:pets'
351+
/store/daysWithoutIncident:
352+
get:
353+
tags:
354+
- pet
355+
summary: Number of days since the last time a pet maimed someone at the store
356+
description: ''
357+
operationId: getDaysWithoutIncident
358+
parameters: []
359+
responses:
360+
'200':
361+
description: successful operation
362+
schema:
363+
type: integer
338364
/store/inventory:
339365
get:
340366
tags:

samples/client/others/c/bearerAuth/api/DefaultAPI.c

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,17 @@ DefaultAPI_privateGet(apiClient_t *apiClient)
2626
list_t *localVarContentType = NULL;
2727
char *localVarBodyParameters = NULL;
2828

29+
// clear the error code from the previous api call
30+
apiClient->response_code = 0;
31+
2932
// create the path
3033
long sizeOfPath = strlen("/private")+1;
3134
char *localVarPath = malloc(sizeOfPath);
3235
snprintf(localVarPath, sizeOfPath, "/private");
3336

3437

3538

39+
3640
list_addElement(localVarHeaderType,"application/json"); //produces
3741
apiClient_invoke(apiClient,
3842
localVarPath,
@@ -49,11 +53,14 @@ DefaultAPI_privateGet(apiClient_t *apiClient)
4953
// printf("%s\n","A JSON object with private information");
5054
//}
5155
//nonprimitive not container
52-
cJSON *DefaultAPIlocalVarJSON = cJSON_Parse(apiClient->dataReceived);
53-
object_t *elementToReturn = object_parseFromJSON(DefaultAPIlocalVarJSON);
54-
cJSON_Delete(DefaultAPIlocalVarJSON);
55-
if(elementToReturn == NULL) {
56-
// return 0;
56+
object_t *elementToReturn = NULL;
57+
if(apiClient->response_code >= 200 && apiClient->response_code < 300) {
58+
cJSON *DefaultAPIlocalVarJSON = cJSON_Parse(apiClient->dataReceived);
59+
elementToReturn = object_parseFromJSON(DefaultAPIlocalVarJSON);
60+
cJSON_Delete(DefaultAPIlocalVarJSON);
61+
if(elementToReturn == NULL) {
62+
// return 0;
63+
}
5764
}
5865

5966
//return type
@@ -89,13 +96,17 @@ DefaultAPI_publicGet(apiClient_t *apiClient)
8996
list_t *localVarContentType = NULL;
9097
char *localVarBodyParameters = NULL;
9198

99+
// clear the error code from the previous api call
100+
apiClient->response_code = 0;
101+
92102
// create the path
93103
long sizeOfPath = strlen("/public")+1;
94104
char *localVarPath = malloc(sizeOfPath);
95105
snprintf(localVarPath, sizeOfPath, "/public");
96106

97107

98108

109+
99110
list_addElement(localVarHeaderType,"application/json"); //produces
100111
apiClient_invoke(apiClient,
101112
localVarPath,
@@ -112,11 +123,14 @@ DefaultAPI_publicGet(apiClient_t *apiClient)
112123
// printf("%s\n","A JSON object with public information");
113124
//}
114125
//nonprimitive not container
115-
cJSON *DefaultAPIlocalVarJSON = cJSON_Parse(apiClient->dataReceived);
116-
object_t *elementToReturn = object_parseFromJSON(DefaultAPIlocalVarJSON);
117-
cJSON_Delete(DefaultAPIlocalVarJSON);
118-
if(elementToReturn == NULL) {
119-
// return 0;
126+
object_t *elementToReturn = NULL;
127+
if(apiClient->response_code >= 200 && apiClient->response_code < 300) {
128+
cJSON *DefaultAPIlocalVarJSON = cJSON_Parse(apiClient->dataReceived);
129+
elementToReturn = object_parseFromJSON(DefaultAPIlocalVarJSON);
130+
cJSON_Delete(DefaultAPIlocalVarJSON);
131+
if(elementToReturn == NULL) {
132+
// return 0;
133+
}
120134
}
121135

122136
//return type
@@ -152,13 +166,17 @@ DefaultAPI_usersGet(apiClient_t *apiClient)
152166
list_t *localVarContentType = NULL;
153167
char *localVarBodyParameters = NULL;
154168

169+
// clear the error code from the previous api call
170+
apiClient->response_code = 0;
171+
155172
// create the path
156173
long sizeOfPath = strlen("/users")+1;
157174
char *localVarPath = malloc(sizeOfPath);
158175
snprintf(localVarPath, sizeOfPath, "/users");
159176

160177

161178

179+
162180
list_addElement(localVarHeaderType,"application/json"); //produces
163181
apiClient_invoke(apiClient,
164182
localVarPath,
@@ -175,14 +193,17 @@ DefaultAPI_usersGet(apiClient_t *apiClient)
175193
// printf("%s\n","A JSON array of user names");
176194
//}
177195
//primitive return type not simple
178-
cJSON *localVarJSON = cJSON_Parse(apiClient->dataReceived);
179-
cJSON *VarJSON;
180-
list_t *elementToReturn = list_createList();
181-
cJSON_ArrayForEach(VarJSON, localVarJSON){
182-
keyValuePair_t *keyPair = keyValuePair_create(strdup(VarJSON->string), cJSON_Print(VarJSON));
183-
list_addElement(elementToReturn, keyPair);
196+
list_t *elementToReturn = NULL;
197+
if(apiClient->response_code >= 200 && apiClient->response_code < 300) {
198+
cJSON *localVarJSON = cJSON_Parse(apiClient->dataReceived);
199+
cJSON *VarJSON;
200+
elementToReturn = list_createList();
201+
cJSON_ArrayForEach(VarJSON, localVarJSON){
202+
keyValuePair_t *keyPair = keyValuePair_create(strdup(VarJSON->string), cJSON_Print(VarJSON));
203+
list_addElement(elementToReturn, keyPair);
204+
}
205+
cJSON_Delete(localVarJSON);
184206
}
185-
cJSON_Delete(localVarJSON);
186207

187208
if (apiClient->dataReceived) {
188209
free(apiClient->dataReceived);

samples/client/petstore/c-useJsonUnformatted/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ Category | Method | HTTP request | Description
6969
*PetAPI* | [**PetAPI_deletePet**](docs/PetAPI.md#PetAPI_deletePet) | **DELETE** /pet/{petId} | Deletes a pet
7070
*PetAPI* | [**PetAPI_findPetsByStatus**](docs/PetAPI.md#PetAPI_findPetsByStatus) | **GET** /pet/findByStatus | Finds Pets by status
7171
*PetAPI* | [**PetAPI_findPetsByTags**](docs/PetAPI.md#PetAPI_findPetsByTags) | **GET** /pet/findByTags | Finds Pets by tags
72+
*PetAPI* | [**PetAPI_getDaysWithoutIncident**](docs/PetAPI.md#PetAPI_getDaysWithoutIncident) | **GET** /store/daysWithoutIncident | Number of days since the last time a pet maimed someone at the store
7273
*PetAPI* | [**PetAPI_getPetById**](docs/PetAPI.md#PetAPI_getPetById) | **GET** /pet/{petId} | Find pet by ID
74+
*PetAPI* | [**PetAPI_getPicture**](docs/PetAPI.md#PetAPI_getPicture) | **GET** /pet/picture | Get a random picture of someone else's pet
7375
*PetAPI* | [**PetAPI_isPetAvailable**](docs/PetAPI.md#PetAPI_isPetAvailable) | **POST** /pet/{petId}/isAvailable | Is this pet still available?
7476
*PetAPI* | [**PetAPI_sharePicture**](docs/PetAPI.md#PetAPI_sharePicture) | **POST** /pet/picture | Send a picture of your happy pet
7577
*PetAPI* | [**PetAPI_specialtyPet**](docs/PetAPI.md#PetAPI_specialtyPet) | **GET** /pet/specialty | Specialty of the shop

0 commit comments

Comments
 (0)