Fix inconsitent numeric object key (#4851)

This commit is contained in:
Mees Delzenne 2024-09-20 17:18:46 +02:00 committed by GitHub
parent 8cca86028b
commit eff4936dc3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 15 deletions

View file

@ -79,15 +79,12 @@ pub fn escape_ident(s: &str) -> Cow<'_, str> {
#[inline] #[inline]
pub fn escape_normal<'a>(s: &'a str, l: char, r: char, e: &str) -> Cow<'a, str> { pub fn escape_normal<'a>(s: &'a str, l: char, r: char, e: &str) -> Cow<'a, str> {
// Loop over each character // Is there no need to escape the value?
for x in s.bytes() { if s.bytes().all(|x| x.is_ascii_alphanumeric() || x == b'_') {
// Check if character is allowed return Cow::Borrowed(s);
if !(x.is_ascii_alphanumeric() || x == b'_') {
return Cow::Owned(format!("{l}{}{r}", s.replace(r, e)));
}
} }
// Output the value // Output the value
Cow::Borrowed(s) Cow::Owned(format!("{l}{}{r}", s.replace(r, e)))
} }
pub fn escape_reserved_keyword(s: &str) -> Option<String> { pub fn escape_reserved_keyword(s: &str) -> Option<String> {

View file

@ -3,9 +3,10 @@ use std::collections::BTreeMap;
use reblessive::Stk; use reblessive::Stk;
use crate::{ use crate::{
sql::{Block, Geometry, Number, Object, Strand, Value}, sql::{Block, Geometry, Object, Strand, Value},
syn::{ syn::{
error::bail, error::bail,
lexer::compound,
parser::{enter_object_recursion, mac::expected, ParseResult, Parser}, parser::{enter_object_recursion, mac::expected, ParseResult, Parser},
token::{t, Glued, Span, TokenKind}, token::{t, Glued, Span, TokenKind},
}, },
@ -602,10 +603,8 @@ impl Parser<'_> {
match token.kind { match token.kind {
x if Self::kind_is_keyword_like(x) => { x if Self::kind_is_keyword_like(x) => {
self.pop_peek(); self.pop_peek();
let str = self.lexer.reader.span(token.span); let str = self.lexer.span_str(token.span);
// Lexer should ensure that the token is valid utf-8 Ok(str.to_string())
let str = std::str::from_utf8(str).unwrap().to_owned();
Ok(str)
} }
TokenKind::Identifier => { TokenKind::Identifier => {
self.pop_peek(); self.pop_peek();
@ -616,9 +615,16 @@ impl Parser<'_> {
let str = self.next_token_value::<Strand>()?.0; let str = self.next_token_value::<Strand>()?.0;
Ok(str) Ok(str)
} }
TokenKind::Digits | TokenKind::Glued(Glued::Number) => { TokenKind::Digits => {
let number = self.next_token_value::<Number>()?.to_string(); self.pop_peek();
Ok(number) let span = self.lexer.lex_compound(token, compound::number)?.span;
let str = self.lexer.span_str(span);
Ok(str.to_string())
}
TokenKind::Glued(Glued::Number) => {
self.pop_peek();
let str = self.lexer.span_str(token.span);
Ok(str.to_string())
} }
_ => unexpected!(self, token, "an object key"), _ => unexpected!(self, token, "an object key"),
} }

View file

@ -38,6 +38,16 @@ fn parse_coordinate() {
assert_eq!(x.y(), -18.0); assert_eq!(x.y(), -18.0);
} }
#[test]
fn parse_numeric_object_key() {
let v = test_parse!(parse_value_table, "{ 00: 0 }").unwrap();
let Value::Object(object) = v else {
panic!("not an object");
};
assert!(object.len() == 1);
assert_eq!(object.get("00").cloned(), Some(Value::Number(Number::Int(0))));
}
#[test] #[test]
fn parse_like_operator() { fn parse_like_operator() {
test_parse!(parse_value_field, "a ~ b").unwrap(); test_parse!(parse_value_field, "a ~ b").unwrap();