mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 17:44:08 +00:00
Fix #5318: known answers false for keys no dictionary holds
`known` raised a typecheck for any key that can't be a key here (an array, a dictionary, a real with a fraction). The PLRM allows any object but null as a key, and since `put` refuses such keys, no dictionary holds one: `known` now answers false, and null still raises the typecheck. Ghostscript's eps2write prolog looks each inline-image value up in a dictionary of abbreviations, and an image with two filters has an array there.
This commit is contained in:
@@ -1050,10 +1050,10 @@ impl<'a> Interp<'a> {
|
||||
self.insert(&d, k, Some(v))?;
|
||||
}
|
||||
Known => {
|
||||
let k = self.pop()?.key().ok_or(PsError::Ps("typecheck", String::new()))?;
|
||||
let k = self.pop()?;
|
||||
let d = self.pop_dict()?;
|
||||
let known = d.borrow().contains_key(&k);
|
||||
self.push(Obj::Bool(known))?;
|
||||
let found = known(&d, &k)?;
|
||||
self.push(Obj::Bool(found))?;
|
||||
}
|
||||
Where => {
|
||||
let k = self.pop()?.key().ok_or(PsError::Ps("typecheck", String::new()))?;
|
||||
@@ -1418,6 +1418,16 @@ fn index(k: &Obj) -> Res<usize> {
|
||||
}
|
||||
}
|
||||
|
||||
/// `known`: a key may be any object but null (PLRM 3rd ed.), and one that can't be a key here (an
|
||||
/// array, a dictionary, a real with a fraction) is in no dictionary, since `put` refuses it.
|
||||
fn known(d: &DictRef, k: &Obj) -> Res<bool> {
|
||||
match k.key() {
|
||||
Some(key) => Ok(d.borrow().contains_key(&key)),
|
||||
None if matches!(k, Obj::Null) => ps_err("typecheck", "known"),
|
||||
None => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
/// `eq`: numbers by value, strings and names by text, composites by identity.
|
||||
fn equal(a: &Obj, b: &Obj) -> bool {
|
||||
match (a, b) {
|
||||
|
||||
@@ -996,6 +996,17 @@ fn the_standard_dictionaries_are_dictionaries_in_systemdict() {
|
||||
check("SharedFontDirectory type /dicttype eq");
|
||||
}
|
||||
|
||||
/// A key may be any object but null (PLRM 3rd ed.), so `known` answers for every other key.
|
||||
/// Ghostscript's `eps2write` looks an inline image's filter up in a dictionary of abbreviations,
|
||||
/// and the filter may be an array of them.
|
||||
#[test]
|
||||
fn known_answers_false_for_keys_no_dictionary_holds() {
|
||||
check("<< /A85 /ASCII85Decode >> [ /A85 /LZW ] known not");
|
||||
check("1 dict 1 dict known not 1 dict 1.5 known not and 1 dict mark known not and");
|
||||
check("<< /A85 /ASCII85Decode >> /A85 known << 1 2 >> 1.0 known and");
|
||||
check("{ 1 dict null known } stopped");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dictstack_and_internaldict_answer() {
|
||||
check("10 array dictstack length countdictstack eq");
|
||||
|
||||
Reference in New Issue
Block a user