Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(oas3): validate xml and x-www-form-urlencoded request body #9705

Open
wants to merge 1 commit into
base: issue-9673
Choose a base branch
from

Conversation

glowcloud
Copy link
Contributor

Refs #9673

throw new Error("Parameter string value must be valid XML")
}

const childNodes = Array.from(node.childNodes)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might need to get rid of nodes with only whitespace characters here, as at this point our result is this:

{
    "0": "\n",
    "1": "\t",
    "id": "10",
    "name": "doggie",
    "category": {
        "0": "\n",
        "1": "\t",
        "2": "\t",
        "id": "1",
        "name": "Dogs"
    }
}

The validation for this will pass but perhaps it might create issues later on.

const traversedChildren = childNodes.map((child) => traverseXML(child))
result[name] = traversedChildren.reduce((paramObj, child) => {
Object.entries(child).forEach(([key, value]) => {
paramObj[key] = value
Copy link
Contributor Author

@glowcloud glowcloud Mar 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine if the type of our parameter is an object but if we have an array, ex.

	<photoUrls>
		<photoUrl>a</photoUrl>
		<photoUrl>b</photoUrl>
		<photoUrl>c</photoUrl>
	</photoUrls>

the JSON result for it will be

{
  "photoUrls": {
      "photoUrl": "c"
  }
}

and that's the only thing we'll be validating.

Perhaps we could do something like this

  let isArray = false
  Object.entries(child).forEach(([key, value]) => {
    if (paramObj[key] === undefined) {
      paramObj[key] = value
    } else if (isArray) {
      paramObj[key].push(value)
    } else {
      paramObj[key] = [paramObj[key], value]
      isArray = true
    }
  })
  if (isArray) {
    paramObj = Object.values(paramObj)[0]
  }

In this case, arrays of length 0 or 1 would still be seen as an object.

@glowcloud glowcloud self-assigned this Mar 18, 2024
@glowcloud glowcloud requested a review from char0n March 18, 2024 09:09
// more than one child node - the parameter is an object or an array
const traversedChildren = childNodes.map((child) => traverseXML(child))
result[name] = traversedChildren.reduce((paramObj, child) => {
Object.entries(child).forEach(([key, value]) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned in a comment

We might need to get rid of nodes with only whitespace characters

Perhaps we could just add if (typeof child !== "string") here, as traversedChildren will look something like this:

[
    "\n\t\t",
    {
        "id": "1"
    },
    "\n\t\t",
    {
        "name": "Dogs"
    },
    "\n\t"
]

It seems like the actual parameters should be { key: value } objects.

return undefined
}

export const parseXML = (xml) => {
Copy link
Contributor Author

@glowcloud glowcloud Mar 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the name of this function, perhaps it should be xmlToJson to better reflect what it does.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant