xmlschemas.c 812 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176
  1. /*
  2. * schemas.c : implementation of the XML Schema handling and
  3. * schema validity checking
  4. *
  5. * See Copyright for the status of this software.
  6. *
  7. * Daniel Veillard <veillard@redhat.com>
  8. */
  9. /*
  10. * TODO:
  11. * - when types are redefined in includes, check that all
  12. * types in the redef list are equal
  13. * -> need a type equality operation.
  14. * - if we don't intend to use the schema for schemas, we
  15. * need to validate all schema attributes (ref, type, name)
  16. * against their types.
  17. * - Eliminate item creation for: ??
  18. *
  19. * URGENT TODO:
  20. * - For xsi-driven schema acquisition, augment the IDCs after every
  21. * acquisition episode (xmlSchemaAugmentIDC).
  22. *
  23. * NOTES:
  24. * - Eliminated item creation for: <restriction>, <extension>,
  25. * <simpleContent>, <complexContent>, <list>, <union>
  26. *
  27. * PROBLEMS:
  28. * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
  29. * IDC XPath expression and chameleon includes: the targetNamespace is changed, so
  30. * XPath will have trouble to resolve to this namespace, since not known.
  31. *
  32. *
  33. * CONSTRAINTS:
  34. *
  35. * Schema Component Constraint:
  36. * All Group Limited (cos-all-limited)
  37. * Status: complete
  38. * (1.2)
  39. * In xmlSchemaGroupDefReferenceTermFixup() and
  40. * (2)
  41. * In xmlSchemaParseModelGroup()
  42. * TODO: Actually this should go to component-level checks,
  43. * but is done here due to performance. Move it to an other layer
  44. * is schema construction via an API is implemented.
  45. */
  46. /* To avoid EBCDIC trouble when parsing on zOS */
  47. #if defined(__MVS__)
  48. #pragma convert("ISO8859-1")
  49. #endif
  50. #define IN_LIBXML
  51. #include "libxml.h"
  52. #ifdef LIBXML_SCHEMAS_ENABLED
  53. #include <string.h>
  54. #include <libxml/xmlmemory.h>
  55. #include <libxml/parser.h>
  56. #include <libxml/parserInternals.h>
  57. #include <libxml/hash.h>
  58. #include <libxml/uri.h>
  59. #include <libxml/xmlschemas.h>
  60. #include <libxml/schemasInternals.h>
  61. #include <libxml/xmlschemastypes.h>
  62. #include <libxml/xmlautomata.h>
  63. #include <libxml/xmlregexp.h>
  64. #include <libxml/dict.h>
  65. #include <libxml/encoding.h>
  66. #include <libxml/xmlIO.h>
  67. #ifdef LIBXML_PATTERN_ENABLED
  68. #include <libxml/pattern.h>
  69. #endif
  70. #ifdef LIBXML_READER_ENABLED
  71. #include <libxml/xmlreader.h>
  72. #endif
  73. /* #define DEBUG 1 */
  74. /* #define DEBUG_CONTENT 1 */
  75. /* #define DEBUG_TYPE 1 */
  76. /* #define DEBUG_CONTENT_REGEXP 1 */
  77. /* #define DEBUG_AUTOMATA 1 */
  78. /* #define DEBUG_IDC */
  79. /* #define DEBUG_IDC_NODE_TABLE */
  80. /* #define WXS_ELEM_DECL_CONS_ENABLED */
  81. #ifdef DEBUG_IDC
  82. #ifndef DEBUG_IDC_NODE_TABLE
  83. #define DEBUG_IDC_NODE_TABLE
  84. #endif
  85. #endif
  86. /* #define ENABLE_PARTICLE_RESTRICTION 1 */
  87. #define ENABLE_REDEFINE
  88. /* #define ENABLE_NAMED_LOCALS */
  89. /* #define ENABLE_IDC_NODE_TABLES_TEST */
  90. #define DUMP_CONTENT_MODEL
  91. #ifdef LIBXML_READER_ENABLED
  92. /* #define XML_SCHEMA_READER_ENABLED */
  93. #endif
  94. #define UNBOUNDED (1 << 30)
  95. #define TODO \
  96. xmlGenericError(xmlGenericErrorContext, \
  97. "Unimplemented block at %s:%d\n", \
  98. __FILE__, __LINE__);
  99. #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
  100. /*
  101. * The XML Schemas namespaces
  102. */
  103. static const xmlChar *xmlSchemaNs = (const xmlChar *)
  104. "http://www.w3.org/2001/XMLSchema";
  105. static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
  106. "http://www.w3.org/2001/XMLSchema-instance";
  107. static const xmlChar *xmlNamespaceNs = (const xmlChar *)
  108. "http://www.w3.org/2000/xmlns/";
  109. /*
  110. * Come casting macros.
  111. */
  112. #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
  113. #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
  114. #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
  115. #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
  116. #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
  117. #define WXS_PTC_CAST (xmlSchemaParticlePtr)
  118. #define WXS_TYPE_CAST (xmlSchemaTypePtr)
  119. #define WXS_ELEM_CAST (xmlSchemaElementPtr)
  120. #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
  121. #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
  122. #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
  123. #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
  124. #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
  125. #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
  126. #define WXS_IDC_CAST (xmlSchemaIDCPtr)
  127. #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
  128. #define WXS_LIST_CAST (xmlSchemaItemListPtr)
  129. /*
  130. * Macros to query common properties of components.
  131. */
  132. #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
  133. #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
  134. /*
  135. * Macros for element declarations.
  136. */
  137. #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
  138. #define WXS_SUBST_HEAD(item) (item)->refDecl
  139. /*
  140. * Macros for attribute declarations.
  141. */
  142. #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
  143. /*
  144. * Macros for attribute uses.
  145. */
  146. #define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
  147. #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
  148. #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
  149. #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
  150. /*
  151. * Macros for attribute groups.
  152. */
  153. #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
  154. #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
  155. /*
  156. * Macros for particles.
  157. */
  158. #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
  159. #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
  160. #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
  161. #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
  162. /*
  163. * Macros for model groups definitions.
  164. */
  165. #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
  166. /*
  167. * Macros for model groups.
  168. */
  169. #define WXS_IS_MODEL_GROUP(i) \
  170. (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
  171. ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
  172. ((i)->type == XML_SCHEMA_TYPE_ALL))
  173. #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
  174. /*
  175. * Macros for schema buckets.
  176. */
  177. #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
  178. ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
  179. #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
  180. ((t) == XML_SCHEMA_SCHEMA_IMPORT))
  181. #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
  182. #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
  183. /*
  184. * Macros for complex/simple types.
  185. */
  186. #define WXS_IS_ANYTYPE(i) \
  187. (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
  188. ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
  189. #define WXS_IS_COMPLEX(i) \
  190. (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
  191. ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
  192. #define WXS_IS_SIMPLE(item) \
  193. ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
  194. ((item->type == XML_SCHEMA_TYPE_BASIC) && \
  195. (item->builtInType != XML_SCHEMAS_ANYTYPE)))
  196. #define WXS_IS_ANY_SIMPLE_TYPE(i) \
  197. (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
  198. ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
  199. #define WXS_IS_RESTRICTION(t) \
  200. ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
  201. #define WXS_IS_EXTENSION(t) \
  202. ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
  203. #define WXS_IS_TYPE_NOT_FIXED(i) \
  204. (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
  205. (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
  206. #define WXS_IS_TYPE_NOT_FIXED_1(item) \
  207. (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
  208. (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
  209. #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
  210. #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
  211. /*
  212. * Macros for exclusively for complex types.
  213. */
  214. #define WXS_HAS_COMPLEX_CONTENT(item) \
  215. ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
  216. (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
  217. (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
  218. #define WXS_HAS_SIMPLE_CONTENT(item) \
  219. ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
  220. (item->contentType == XML_SCHEMA_CONTENT_BASIC))
  221. #define WXS_HAS_MIXED_CONTENT(item) \
  222. (item->contentType == XML_SCHEMA_CONTENT_MIXED)
  223. #define WXS_EMPTIABLE(t) \
  224. (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
  225. #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
  226. #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
  227. #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
  228. /*
  229. * Macros for exclusively for simple types.
  230. */
  231. #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
  232. #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
  233. #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
  234. #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
  235. /*
  236. * Misc parser context macros.
  237. */
  238. #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
  239. #define WXS_HAS_BUCKETS(ctx) \
  240. ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
  241. (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
  242. #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
  243. #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
  244. #define WXS_SCHEMA(ctx) (ctx)->schema
  245. #define WXS_ADD_LOCAL(ctx, item) \
  246. xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
  247. #define WXS_ADD_GLOBAL(ctx, item) \
  248. xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
  249. #define WXS_ADD_PENDING(ctx, item) \
  250. xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
  251. /*
  252. * xmlSchemaItemList macros.
  253. */
  254. #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
  255. /*
  256. * Misc macros.
  257. */
  258. #define IS_SCHEMA(node, type) \
  259. ((node != NULL) && (node->ns != NULL) && \
  260. (xmlStrEqual(node->name, (const xmlChar *) type)) && \
  261. (xmlStrEqual(node->ns->href, xmlSchemaNs)))
  262. #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
  263. /*
  264. * Since we put the default/fixed values into the dict, we can
  265. * use pointer comparison for those values.
  266. * REMOVED: (xmlStrEqual((v1), (v2)))
  267. */
  268. #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
  269. #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
  270. #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
  271. #define HFAILURE if (res == -1) goto exit_failure;
  272. #define HERROR if (res != 0) goto exit_error;
  273. #define HSTOP(ctx) if ((ctx)->stop) goto exit;
  274. /*
  275. * Some flags used for various schema constraints.
  276. */
  277. #define SUBSET_RESTRICTION 1<<0
  278. #define SUBSET_EXTENSION 1<<1
  279. #define SUBSET_SUBSTITUTION 1<<2
  280. #define SUBSET_LIST 1<<3
  281. #define SUBSET_UNION 1<<4
  282. typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
  283. typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
  284. typedef struct _xmlSchemaItemList xmlSchemaItemList;
  285. typedef xmlSchemaItemList *xmlSchemaItemListPtr;
  286. struct _xmlSchemaItemList {
  287. void **items; /* used for dynamic addition of schemata */
  288. int nbItems; /* used for dynamic addition of schemata */
  289. int sizeItems; /* used for dynamic addition of schemata */
  290. };
  291. #define XML_SCHEMA_CTXT_PARSER 1
  292. #define XML_SCHEMA_CTXT_VALIDATOR 2
  293. typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
  294. typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
  295. struct _xmlSchemaAbstractCtxt {
  296. int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
  297. void *dummy; /* Fix alignment issues */
  298. };
  299. typedef struct _xmlSchemaBucket xmlSchemaBucket;
  300. typedef xmlSchemaBucket *xmlSchemaBucketPtr;
  301. #define XML_SCHEMA_SCHEMA_MAIN 0
  302. #define XML_SCHEMA_SCHEMA_IMPORT 1
  303. #define XML_SCHEMA_SCHEMA_INCLUDE 2
  304. #define XML_SCHEMA_SCHEMA_REDEFINE 3
  305. /**
  306. * xmlSchemaSchemaRelation:
  307. *
  308. * Used to create a graph of schema relationships.
  309. */
  310. typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
  311. typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
  312. struct _xmlSchemaSchemaRelation {
  313. xmlSchemaSchemaRelationPtr next;
  314. int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
  315. const xmlChar *importNamespace;
  316. xmlSchemaBucketPtr bucket;
  317. };
  318. #define XML_SCHEMA_BUCKET_MARKED 1<<0
  319. #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
  320. struct _xmlSchemaBucket {
  321. int type;
  322. int flags;
  323. const xmlChar *schemaLocation;
  324. const xmlChar *origTargetNamespace;
  325. const xmlChar *targetNamespace;
  326. xmlDocPtr doc;
  327. xmlSchemaSchemaRelationPtr relations;
  328. int located;
  329. int parsed;
  330. int imported;
  331. int preserveDoc;
  332. xmlSchemaItemListPtr globals; /* Global components. */
  333. xmlSchemaItemListPtr locals; /* Local components. */
  334. };
  335. /**
  336. * xmlSchemaImport:
  337. * (extends xmlSchemaBucket)
  338. *
  339. * Reflects a schema. Holds some information
  340. * about the schema and its toplevel components. Duplicate
  341. * toplevel components are not checked at this level.
  342. */
  343. typedef struct _xmlSchemaImport xmlSchemaImport;
  344. typedef xmlSchemaImport *xmlSchemaImportPtr;
  345. struct _xmlSchemaImport {
  346. int type; /* Main OR import OR include. */
  347. int flags;
  348. const xmlChar *schemaLocation; /* The URI of the schema document. */
  349. /* For chameleon includes, @origTargetNamespace will be NULL */
  350. const xmlChar *origTargetNamespace;
  351. /*
  352. * For chameleon includes, @targetNamespace will be the
  353. * targetNamespace of the including schema.
  354. */
  355. const xmlChar *targetNamespace;
  356. xmlDocPtr doc; /* The schema node-tree. */
  357. /* @relations will hold any included/imported/redefined schemas. */
  358. xmlSchemaSchemaRelationPtr relations;
  359. int located;
  360. int parsed;
  361. int imported;
  362. int preserveDoc;
  363. xmlSchemaItemListPtr globals;
  364. xmlSchemaItemListPtr locals;
  365. /* The imported schema. */
  366. xmlSchemaPtr schema;
  367. };
  368. /*
  369. * (extends xmlSchemaBucket)
  370. */
  371. typedef struct _xmlSchemaInclude xmlSchemaInclude;
  372. typedef xmlSchemaInclude *xmlSchemaIncludePtr;
  373. struct _xmlSchemaInclude {
  374. int type;
  375. int flags;
  376. const xmlChar *schemaLocation;
  377. const xmlChar *origTargetNamespace;
  378. const xmlChar *targetNamespace;
  379. xmlDocPtr doc;
  380. xmlSchemaSchemaRelationPtr relations;
  381. int located;
  382. int parsed;
  383. int imported;
  384. int preserveDoc;
  385. xmlSchemaItemListPtr globals; /* Global components. */
  386. xmlSchemaItemListPtr locals; /* Local components. */
  387. /* The owning main or import schema bucket. */
  388. xmlSchemaImportPtr ownerImport;
  389. };
  390. /**
  391. * xmlSchemaBasicItem:
  392. *
  393. * The abstract base type for schema components.
  394. */
  395. typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
  396. typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
  397. struct _xmlSchemaBasicItem {
  398. xmlSchemaTypeType type;
  399. void *dummy; /* Fix alignment issues */
  400. };
  401. /**
  402. * xmlSchemaAnnotItem:
  403. *
  404. * The abstract base type for annotated schema components.
  405. * (Extends xmlSchemaBasicItem)
  406. */
  407. typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
  408. typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
  409. struct _xmlSchemaAnnotItem {
  410. xmlSchemaTypeType type;
  411. xmlSchemaAnnotPtr annot;
  412. };
  413. /**
  414. * xmlSchemaTreeItem:
  415. *
  416. * The abstract base type for tree-like structured schema components.
  417. * (Extends xmlSchemaAnnotItem)
  418. */
  419. typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
  420. typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
  421. struct _xmlSchemaTreeItem {
  422. xmlSchemaTypeType type;
  423. xmlSchemaAnnotPtr annot;
  424. xmlSchemaTreeItemPtr next;
  425. xmlSchemaTreeItemPtr children;
  426. };
  427. #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
  428. /**
  429. * xmlSchemaAttributeUsePtr:
  430. *
  431. * The abstract base type for tree-like structured schema components.
  432. * (Extends xmlSchemaTreeItem)
  433. */
  434. typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
  435. typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
  436. struct _xmlSchemaAttributeUse {
  437. xmlSchemaTypeType type;
  438. xmlSchemaAnnotPtr annot;
  439. xmlSchemaAttributeUsePtr next; /* The next attr. use. */
  440. /*
  441. * The attr. decl. OR a QName-ref. to an attr. decl. OR
  442. * a QName-ref. to an attribute group definition.
  443. */
  444. xmlSchemaAttributePtr attrDecl;
  445. int flags;
  446. xmlNodePtr node;
  447. int occurs; /* required, optional */
  448. const xmlChar * defValue;
  449. xmlSchemaValPtr defVal;
  450. };
  451. /**
  452. * xmlSchemaAttributeUseProhibPtr:
  453. *
  454. * A helper component to reflect attribute prohibitions.
  455. * (Extends xmlSchemaBasicItem)
  456. */
  457. typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
  458. typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
  459. struct _xmlSchemaAttributeUseProhib {
  460. xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
  461. xmlNodePtr node;
  462. const xmlChar *name;
  463. const xmlChar *targetNamespace;
  464. int isRef;
  465. };
  466. /**
  467. * xmlSchemaRedef:
  468. */
  469. typedef struct _xmlSchemaRedef xmlSchemaRedef;
  470. typedef xmlSchemaRedef *xmlSchemaRedefPtr;
  471. struct _xmlSchemaRedef {
  472. xmlSchemaRedefPtr next;
  473. xmlSchemaBasicItemPtr item; /* The redefining component. */
  474. xmlSchemaBasicItemPtr reference; /* The referencing component. */
  475. xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
  476. const xmlChar *refName; /* The name of the to-be-redefined component. */
  477. const xmlChar *refTargetNs; /* The target namespace of the
  478. to-be-redefined comp. */
  479. xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
  480. };
  481. /**
  482. * xmlSchemaConstructionCtxt:
  483. */
  484. typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
  485. typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
  486. struct _xmlSchemaConstructionCtxt {
  487. xmlSchemaPtr mainSchema; /* The main schema. */
  488. xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
  489. xmlDictPtr dict;
  490. xmlSchemaItemListPtr buckets; /* List of schema buckets. */
  491. /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
  492. xmlSchemaBucketPtr bucket; /* The current schema bucket */
  493. xmlSchemaItemListPtr pending; /* All Components of all schemas that
  494. need to be fixed. */
  495. xmlHashTablePtr substGroups;
  496. xmlSchemaRedefPtr redefs;
  497. xmlSchemaRedefPtr lastRedef;
  498. };
  499. #define XML_SCHEMAS_PARSE_ERROR 1
  500. #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
  501. struct _xmlSchemaParserCtxt {
  502. int type;
  503. void *errCtxt; /* user specific error context */
  504. xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
  505. xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
  506. int err;
  507. int nberrors;
  508. xmlStructuredErrorFunc serror;
  509. xmlSchemaConstructionCtxtPtr constructor;
  510. int ownsConstructor; /* TODO: Move this to parser *flags*. */
  511. /* xmlSchemaPtr topschema; */
  512. /* xmlHashTablePtr namespaces; */
  513. xmlSchemaPtr schema; /* The main schema in use */
  514. int counter;
  515. const xmlChar *URL;
  516. xmlDocPtr doc;
  517. int preserve; /* Whether the doc should be freed */
  518. const char *buffer;
  519. int size;
  520. /*
  521. * Used to build complex element content models
  522. */
  523. xmlAutomataPtr am;
  524. xmlAutomataStatePtr start;
  525. xmlAutomataStatePtr end;
  526. xmlAutomataStatePtr state;
  527. xmlDictPtr dict; /* dictionary for interned string names */
  528. xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
  529. int options;
  530. xmlSchemaValidCtxtPtr vctxt;
  531. int isS4S;
  532. int isRedefine;
  533. int xsiAssemble;
  534. int stop; /* If the parser should stop; i.e. a critical error. */
  535. const xmlChar *targetNamespace;
  536. xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
  537. xmlSchemaRedefPtr redef; /* Used for redefinitions. */
  538. int redefCounter; /* Used for redefinitions. */
  539. xmlSchemaItemListPtr attrProhibs;
  540. };
  541. /**
  542. * xmlSchemaQNameRef:
  543. *
  544. * A component reference item (not a schema component)
  545. * (Extends xmlSchemaBasicItem)
  546. */
  547. typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
  548. typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
  549. struct _xmlSchemaQNameRef {
  550. xmlSchemaTypeType type;
  551. xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
  552. xmlSchemaTypeType itemType;
  553. const xmlChar *name;
  554. const xmlChar *targetNamespace;
  555. xmlNodePtr node;
  556. };
  557. /**
  558. * xmlSchemaParticle:
  559. *
  560. * A particle component.
  561. * (Extends xmlSchemaTreeItem)
  562. */
  563. typedef struct _xmlSchemaParticle xmlSchemaParticle;
  564. typedef xmlSchemaParticle *xmlSchemaParticlePtr;
  565. struct _xmlSchemaParticle {
  566. xmlSchemaTypeType type;
  567. xmlSchemaAnnotPtr annot;
  568. xmlSchemaTreeItemPtr next; /* next particle */
  569. xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
  570. a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
  571. etc.) */
  572. int minOccurs;
  573. int maxOccurs;
  574. xmlNodePtr node;
  575. };
  576. /**
  577. * xmlSchemaModelGroup:
  578. *
  579. * A model group component.
  580. * (Extends xmlSchemaTreeItem)
  581. */
  582. typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
  583. typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
  584. struct _xmlSchemaModelGroup {
  585. xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
  586. xmlSchemaAnnotPtr annot;
  587. xmlSchemaTreeItemPtr next; /* not used */
  588. xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
  589. xmlNodePtr node;
  590. };
  591. #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
  592. #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
  593. /**
  594. * xmlSchemaModelGroupDef:
  595. *
  596. * A model group definition component.
  597. * (Extends xmlSchemaTreeItem)
  598. */
  599. typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
  600. typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
  601. struct _xmlSchemaModelGroupDef {
  602. xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
  603. xmlSchemaAnnotPtr annot;
  604. xmlSchemaTreeItemPtr next; /* not used */
  605. xmlSchemaTreeItemPtr children; /* the "model group" */
  606. const xmlChar *name;
  607. const xmlChar *targetNamespace;
  608. xmlNodePtr node;
  609. int flags;
  610. };
  611. typedef struct _xmlSchemaIDC xmlSchemaIDC;
  612. typedef xmlSchemaIDC *xmlSchemaIDCPtr;
  613. /**
  614. * xmlSchemaIDCSelect:
  615. *
  616. * The identity-constraint "field" and "selector" item, holding the
  617. * XPath expression.
  618. */
  619. typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
  620. typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
  621. struct _xmlSchemaIDCSelect {
  622. xmlSchemaIDCSelectPtr next;
  623. xmlSchemaIDCPtr idc;
  624. int index; /* an index position if significant for IDC key-sequences */
  625. const xmlChar *xpath; /* the XPath expression */
  626. void *xpathComp; /* the compiled XPath expression */
  627. };
  628. /**
  629. * xmlSchemaIDC:
  630. *
  631. * The identity-constraint definition component.
  632. * (Extends xmlSchemaAnnotItem)
  633. */
  634. struct _xmlSchemaIDC {
  635. xmlSchemaTypeType type;
  636. xmlSchemaAnnotPtr annot;
  637. xmlSchemaIDCPtr next;
  638. xmlNodePtr node;
  639. const xmlChar *name;
  640. const xmlChar *targetNamespace;
  641. xmlSchemaIDCSelectPtr selector;
  642. xmlSchemaIDCSelectPtr fields;
  643. int nbFields;
  644. xmlSchemaQNameRefPtr ref;
  645. };
  646. /**
  647. * xmlSchemaIDCAug:
  648. *
  649. * The augmented IDC information used for validation.
  650. */
  651. typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
  652. typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
  653. struct _xmlSchemaIDCAug {
  654. xmlSchemaIDCAugPtr next; /* next in a list */
  655. xmlSchemaIDCPtr def; /* the IDC definition */
  656. int keyrefDepth; /* the lowest tree level to which IDC
  657. tables need to be bubbled upwards */
  658. };
  659. /**
  660. * xmlSchemaPSVIIDCKeySequence:
  661. *
  662. * The key sequence of a node table item.
  663. */
  664. typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
  665. typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
  666. struct _xmlSchemaPSVIIDCKey {
  667. xmlSchemaTypePtr type;
  668. xmlSchemaValPtr val;
  669. };
  670. /**
  671. * xmlSchemaPSVIIDCNode:
  672. *
  673. * The node table item of a node table.
  674. */
  675. typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
  676. typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
  677. struct _xmlSchemaPSVIIDCNode {
  678. xmlNodePtr node;
  679. xmlSchemaPSVIIDCKeyPtr *keys;
  680. int nodeLine;
  681. int nodeQNameID;
  682. };
  683. /**
  684. * xmlSchemaPSVIIDCBinding:
  685. *
  686. * The identity-constraint binding item of the [identity-constraint table].
  687. */
  688. typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
  689. typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
  690. struct _xmlSchemaPSVIIDCBinding {
  691. xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
  692. xmlSchemaIDCPtr definition; /* the IDC definition */
  693. xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
  694. int nbNodes; /* number of entries in the node table */
  695. int sizeNodes; /* size of the node table */
  696. xmlSchemaItemListPtr dupls;
  697. };
  698. #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
  699. #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
  700. #define XPATH_STATE_OBJ_MATCHES -2
  701. #define XPATH_STATE_OBJ_BLOCKED -3
  702. typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
  703. typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
  704. /**
  705. * xmlSchemaIDCStateObj:
  706. *
  707. * The state object used to evaluate XPath expressions.
  708. */
  709. typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
  710. typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
  711. struct _xmlSchemaIDCStateObj {
  712. int type;
  713. xmlSchemaIDCStateObjPtr next; /* next if in a list */
  714. int depth; /* depth of creation */
  715. int *history; /* list of (depth, state-id) tuples */
  716. int nbHistory;
  717. int sizeHistory;
  718. xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
  719. matcher */
  720. xmlSchemaIDCSelectPtr sel;
  721. void *xpathCtxt;
  722. };
  723. #define IDC_MATCHER 0
  724. /**
  725. * xmlSchemaIDCMatcher:
  726. *
  727. * Used to evaluate IDC selectors (and fields).
  728. */
  729. struct _xmlSchemaIDCMatcher {
  730. int type;
  731. int depth; /* the tree depth at creation time */
  732. xmlSchemaIDCMatcherPtr next; /* next in the list */
  733. xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
  734. xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
  735. int idcType;
  736. xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
  737. elements */
  738. int sizeKeySeqs;
  739. xmlSchemaItemListPtr targets; /* list of target-node
  740. (xmlSchemaPSVIIDCNodePtr) entries */
  741. xmlHashTablePtr htab;
  742. };
  743. /*
  744. * Element info flags.
  745. */
  746. #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0
  747. #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
  748. #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2
  749. #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3
  750. #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4
  751. #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5
  752. #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6
  753. #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7
  754. #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8
  755. #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9
  756. #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10
  757. /**
  758. * xmlSchemaNodeInfo:
  759. *
  760. * Holds information of an element node.
  761. */
  762. struct _xmlSchemaNodeInfo {
  763. int nodeType;
  764. xmlNodePtr node;
  765. int nodeLine;
  766. const xmlChar *localName;
  767. const xmlChar *nsName;
  768. const xmlChar *value;
  769. xmlSchemaValPtr val; /* the pre-computed value if any */
  770. xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  771. int flags; /* combination of node info flags */
  772. int valNeeded;
  773. int normVal;
  774. xmlSchemaElementPtr decl; /* the element/attribute declaration */
  775. int depth;
  776. xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
  777. for the scope element*/
  778. xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
  779. element */
  780. xmlRegExecCtxtPtr regexCtxt;
  781. const xmlChar **nsBindings; /* Namespace bindings on this element */
  782. int nbNsBindings;
  783. int sizeNsBindings;
  784. int hasKeyrefs;
  785. int appliedXPath; /* Indicates that an XPath has been applied. */
  786. };
  787. #define XML_SCHEMAS_ATTR_UNKNOWN 1
  788. #define XML_SCHEMAS_ATTR_ASSESSED 2
  789. #define XML_SCHEMAS_ATTR_PROHIBITED 3
  790. #define XML_SCHEMAS_ATTR_ERR_MISSING 4
  791. #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
  792. #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
  793. #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
  794. #define XML_SCHEMAS_ATTR_DEFAULT 8
  795. #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
  796. #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
  797. #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
  798. #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
  799. #define XML_SCHEMAS_ATTR_WILD_SKIP 13
  800. #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
  801. #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
  802. #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
  803. #define XML_SCHEMAS_ATTR_META 17
  804. /*
  805. * @metaType values of xmlSchemaAttrInfo.
  806. */
  807. #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
  808. #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
  809. #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
  810. #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
  811. #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
  812. typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
  813. typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
  814. struct _xmlSchemaAttrInfo {
  815. int nodeType;
  816. xmlNodePtr node;
  817. int nodeLine;
  818. const xmlChar *localName;
  819. const xmlChar *nsName;
  820. const xmlChar *value;
  821. xmlSchemaValPtr val; /* the pre-computed value if any */
  822. xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  823. int flags; /* combination of node info flags */
  824. xmlSchemaAttributePtr decl; /* the attribute declaration */
  825. xmlSchemaAttributeUsePtr use; /* the attribute use */
  826. int state;
  827. int metaType;
  828. const xmlChar *vcValue; /* the value constraint value */
  829. xmlSchemaNodeInfoPtr parent;
  830. };
  831. #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
  832. /**
  833. * xmlSchemaValidCtxt:
  834. *
  835. * A Schemas validation context
  836. */
  837. struct _xmlSchemaValidCtxt {
  838. int type;
  839. void *errCtxt; /* user specific data block */
  840. xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
  841. xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
  842. xmlStructuredErrorFunc serror;
  843. xmlSchemaPtr schema; /* The schema in use */
  844. xmlDocPtr doc;
  845. xmlParserInputBufferPtr input;
  846. xmlCharEncoding enc;
  847. xmlSAXHandlerPtr sax;
  848. xmlParserCtxtPtr parserCtxt;
  849. void *user_data; /* TODO: What is this for? */
  850. char *filename;
  851. int err;
  852. int nberrors;
  853. xmlNodePtr node;
  854. xmlNodePtr cur;
  855. /* xmlSchemaTypePtr type; */
  856. xmlRegExecCtxtPtr regexp;
  857. xmlSchemaValPtr value;
  858. int valueWS;
  859. int options;
  860. xmlNodePtr validationRoot;
  861. xmlSchemaParserCtxtPtr pctxt;
  862. int xsiAssemble;
  863. int depth;
  864. xmlSchemaNodeInfoPtr *elemInfos; /* array of element information */
  865. int sizeElemInfos;
  866. xmlSchemaNodeInfoPtr inode; /* the current element information */
  867. xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC information */
  868. xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
  869. xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
  870. xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
  871. xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
  872. int nbIdcNodes;
  873. int sizeIdcNodes;
  874. xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
  875. int nbIdcKeys;
  876. int sizeIdcKeys;
  877. int flags;
  878. xmlDictPtr dict;
  879. #ifdef LIBXML_READER_ENABLED
  880. xmlTextReaderPtr reader;
  881. #endif
  882. xmlSchemaAttrInfoPtr *attrInfos;
  883. int nbAttrInfos;
  884. int sizeAttrInfos;
  885. int skipDepth;
  886. xmlSchemaItemListPtr nodeQNames;
  887. int hasKeyrefs;
  888. int createIDCNodeTables;
  889. int psviExposeIDCNodeTables;
  890. /* Locator for error reporting in streaming mode */
  891. xmlSchemaValidityLocatorFunc locFunc;
  892. void *locCtxt;
  893. };
  894. /**
  895. * xmlSchemaSubstGroup:
  896. *
  897. *
  898. */
  899. typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
  900. typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
  901. struct _xmlSchemaSubstGroup {
  902. xmlSchemaElementPtr head;
  903. xmlSchemaItemListPtr members;
  904. };
  905. /**
  906. * xmlIDCHashEntry:
  907. *
  908. * an entry in hash tables to quickly look up keys/uniques
  909. */
  910. typedef struct _xmlIDCHashEntry xmlIDCHashEntry;
  911. typedef xmlIDCHashEntry *xmlIDCHashEntryPtr;
  912. struct _xmlIDCHashEntry {
  913. xmlIDCHashEntryPtr next; /* next item with same hash */
  914. int index; /* index into associated item list */
  915. };
  916. /************************************************************************
  917. * *
  918. * Some predeclarations *
  919. * *
  920. ************************************************************************/
  921. static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
  922. xmlSchemaPtr schema,
  923. xmlNodePtr node);
  924. static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
  925. xmlSchemaPtr schema,
  926. xmlNodePtr node);
  927. static int
  928. xmlSchemaTypeFixup(xmlSchemaTypePtr type,
  929. xmlSchemaAbstractCtxtPtr ctxt);
  930. static const xmlChar *
  931. xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
  932. static int
  933. xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  934. xmlNodePtr node);
  935. static int
  936. xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
  937. xmlSchemaParserCtxtPtr ctxt);
  938. static void
  939. xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
  940. static xmlSchemaWhitespaceValueType
  941. xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
  942. static xmlSchemaTreeItemPtr
  943. xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  944. xmlNodePtr node, xmlSchemaTypeType type,
  945. int withParticle);
  946. static const xmlChar *
  947. xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
  948. static xmlSchemaTypeLinkPtr
  949. xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
  950. static void
  951. xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
  952. const char *funcName,
  953. const char *message) LIBXML_ATTR_FORMAT(3,0);
  954. static int
  955. xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
  956. xmlSchemaTypePtr type,
  957. xmlSchemaTypePtr baseType,
  958. int subset);
  959. static void
  960. xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
  961. xmlSchemaParserCtxtPtr ctxt);
  962. static void
  963. xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
  964. static xmlSchemaQNameRefPtr
  965. xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
  966. xmlSchemaPtr schema,
  967. xmlNodePtr node);
  968. /************************************************************************
  969. * *
  970. * Helper functions *
  971. * *
  972. ************************************************************************/
  973. /**
  974. * xmlSchemaItemTypeToStr:
  975. * @type: the type of the schema item
  976. *
  977. * Returns the component name of a schema item.
  978. */
  979. static const xmlChar *
  980. xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
  981. {
  982. switch (type) {
  983. case XML_SCHEMA_TYPE_BASIC:
  984. return(BAD_CAST "simple type definition");
  985. case XML_SCHEMA_TYPE_SIMPLE:
  986. return(BAD_CAST "simple type definition");
  987. case XML_SCHEMA_TYPE_COMPLEX:
  988. return(BAD_CAST "complex type definition");
  989. case XML_SCHEMA_TYPE_ELEMENT:
  990. return(BAD_CAST "element declaration");
  991. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  992. return(BAD_CAST "attribute use");
  993. case XML_SCHEMA_TYPE_ATTRIBUTE:
  994. return(BAD_CAST "attribute declaration");
  995. case XML_SCHEMA_TYPE_GROUP:
  996. return(BAD_CAST "model group definition");
  997. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  998. return(BAD_CAST "attribute group definition");
  999. case XML_SCHEMA_TYPE_NOTATION:
  1000. return(BAD_CAST "notation declaration");
  1001. case XML_SCHEMA_TYPE_SEQUENCE:
  1002. return(BAD_CAST "model group (sequence)");
  1003. case XML_SCHEMA_TYPE_CHOICE:
  1004. return(BAD_CAST "model group (choice)");
  1005. case XML_SCHEMA_TYPE_ALL:
  1006. return(BAD_CAST "model group (all)");
  1007. case XML_SCHEMA_TYPE_PARTICLE:
  1008. return(BAD_CAST "particle");
  1009. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1010. return(BAD_CAST "unique identity-constraint");
  1011. /* return(BAD_CAST "IDC (unique)"); */
  1012. case XML_SCHEMA_TYPE_IDC_KEY:
  1013. return(BAD_CAST "key identity-constraint");
  1014. /* return(BAD_CAST "IDC (key)"); */
  1015. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1016. return(BAD_CAST "keyref identity-constraint");
  1017. /* return(BAD_CAST "IDC (keyref)"); */
  1018. case XML_SCHEMA_TYPE_ANY:
  1019. return(BAD_CAST "wildcard (any)");
  1020. case XML_SCHEMA_EXTRA_QNAMEREF:
  1021. return(BAD_CAST "[helper component] QName reference");
  1022. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  1023. return(BAD_CAST "[helper component] attribute use prohibition");
  1024. default:
  1025. return(BAD_CAST "Not a schema component");
  1026. }
  1027. }
  1028. /**
  1029. * xmlSchemaGetComponentTypeStr:
  1030. * @type: the type of the schema item
  1031. *
  1032. * Returns the component name of a schema item.
  1033. */
  1034. static const xmlChar *
  1035. xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
  1036. {
  1037. switch (item->type) {
  1038. case XML_SCHEMA_TYPE_BASIC:
  1039. if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
  1040. return(BAD_CAST "complex type definition");
  1041. else
  1042. return(BAD_CAST "simple type definition");
  1043. default:
  1044. return(xmlSchemaItemTypeToStr(item->type));
  1045. }
  1046. }
  1047. /**
  1048. * xmlSchemaGetComponentNode:
  1049. * @item: a schema component
  1050. *
  1051. * Returns node associated with the schema component.
  1052. * NOTE that such a node need not be available; plus, a component's
  1053. * node need not to reflect the component directly, since there is no
  1054. * one-to-one relationship between the XML Schema representation and
  1055. * the component representation.
  1056. */
  1057. static xmlNodePtr
  1058. xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
  1059. {
  1060. switch (item->type) {
  1061. case XML_SCHEMA_TYPE_ELEMENT:
  1062. return (((xmlSchemaElementPtr) item)->node);
  1063. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1064. return (((xmlSchemaAttributePtr) item)->node);
  1065. case XML_SCHEMA_TYPE_COMPLEX:
  1066. case XML_SCHEMA_TYPE_SIMPLE:
  1067. return (((xmlSchemaTypePtr) item)->node);
  1068. case XML_SCHEMA_TYPE_ANY:
  1069. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1070. return (((xmlSchemaWildcardPtr) item)->node);
  1071. case XML_SCHEMA_TYPE_PARTICLE:
  1072. return (((xmlSchemaParticlePtr) item)->node);
  1073. case XML_SCHEMA_TYPE_SEQUENCE:
  1074. case XML_SCHEMA_TYPE_CHOICE:
  1075. case XML_SCHEMA_TYPE_ALL:
  1076. return (((xmlSchemaModelGroupPtr) item)->node);
  1077. case XML_SCHEMA_TYPE_GROUP:
  1078. return (((xmlSchemaModelGroupDefPtr) item)->node);
  1079. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1080. return (((xmlSchemaAttributeGroupPtr) item)->node);
  1081. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1082. case XML_SCHEMA_TYPE_IDC_KEY:
  1083. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1084. return (((xmlSchemaIDCPtr) item)->node);
  1085. case XML_SCHEMA_EXTRA_QNAMEREF:
  1086. return(((xmlSchemaQNameRefPtr) item)->node);
  1087. /* TODO: What to do with NOTATIONs?
  1088. case XML_SCHEMA_TYPE_NOTATION:
  1089. return (((xmlSchemaNotationPtr) item)->node);
  1090. */
  1091. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1092. return (((xmlSchemaAttributeUsePtr) item)->node);
  1093. default:
  1094. return (NULL);
  1095. }
  1096. }
  1097. #if 0
  1098. /**
  1099. * xmlSchemaGetNextComponent:
  1100. * @item: a schema component
  1101. *
  1102. * Returns the next sibling of the schema component.
  1103. */
  1104. static xmlSchemaBasicItemPtr
  1105. xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
  1106. {
  1107. switch (item->type) {
  1108. case XML_SCHEMA_TYPE_ELEMENT:
  1109. return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
  1110. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1111. return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
  1112. case XML_SCHEMA_TYPE_COMPLEX:
  1113. case XML_SCHEMA_TYPE_SIMPLE:
  1114. return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
  1115. case XML_SCHEMA_TYPE_ANY:
  1116. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1117. return (NULL);
  1118. case XML_SCHEMA_TYPE_PARTICLE:
  1119. return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
  1120. case XML_SCHEMA_TYPE_SEQUENCE:
  1121. case XML_SCHEMA_TYPE_CHOICE:
  1122. case XML_SCHEMA_TYPE_ALL:
  1123. return (NULL);
  1124. case XML_SCHEMA_TYPE_GROUP:
  1125. return (NULL);
  1126. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1127. return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
  1128. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1129. case XML_SCHEMA_TYPE_IDC_KEY:
  1130. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1131. return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
  1132. default:
  1133. return (NULL);
  1134. }
  1135. }
  1136. #endif
  1137. /**
  1138. * xmlSchemaFormatQName:
  1139. * @buf: the string buffer
  1140. * @namespaceName: the namespace name
  1141. * @localName: the local name
  1142. *
  1143. * Returns the given QName in the format "{namespaceName}localName" or
  1144. * just "localName" if @namespaceName is NULL.
  1145. *
  1146. * Returns the localName if @namespaceName is NULL, a formatted
  1147. * string otherwise.
  1148. */
  1149. static const xmlChar*
  1150. xmlSchemaFormatQName(xmlChar **buf,
  1151. const xmlChar *namespaceName,
  1152. const xmlChar *localName)
  1153. {
  1154. FREE_AND_NULL(*buf)
  1155. if (namespaceName != NULL) {
  1156. *buf = xmlStrdup(BAD_CAST "{");
  1157. *buf = xmlStrcat(*buf, namespaceName);
  1158. *buf = xmlStrcat(*buf, BAD_CAST "}");
  1159. }
  1160. if (localName != NULL) {
  1161. if (namespaceName == NULL)
  1162. return(localName);
  1163. *buf = xmlStrcat(*buf, localName);
  1164. } else {
  1165. *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
  1166. }
  1167. return ((const xmlChar *) *buf);
  1168. }
  1169. static const xmlChar*
  1170. xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
  1171. {
  1172. if (ns != NULL)
  1173. return (xmlSchemaFormatQName(buf, ns->href, localName));
  1174. else
  1175. return (xmlSchemaFormatQName(buf, NULL, localName));
  1176. }
  1177. static const xmlChar *
  1178. xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
  1179. {
  1180. if (item == NULL) {
  1181. return (NULL);
  1182. }
  1183. switch (item->type) {
  1184. case XML_SCHEMA_TYPE_ELEMENT:
  1185. return (((xmlSchemaElementPtr) item)->name);
  1186. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1187. return (((xmlSchemaAttributePtr) item)->name);
  1188. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1189. return (((xmlSchemaAttributeGroupPtr) item)->name);
  1190. case XML_SCHEMA_TYPE_BASIC:
  1191. case XML_SCHEMA_TYPE_SIMPLE:
  1192. case XML_SCHEMA_TYPE_COMPLEX:
  1193. return (((xmlSchemaTypePtr) item)->name);
  1194. case XML_SCHEMA_TYPE_GROUP:
  1195. return (((xmlSchemaModelGroupDefPtr) item)->name);
  1196. case XML_SCHEMA_TYPE_IDC_KEY:
  1197. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1198. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1199. return (((xmlSchemaIDCPtr) item)->name);
  1200. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1201. if (WXS_ATTRUSE_DECL(item) != NULL) {
  1202. return(xmlSchemaGetComponentName(
  1203. WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
  1204. } else
  1205. return(NULL);
  1206. case XML_SCHEMA_EXTRA_QNAMEREF:
  1207. return (((xmlSchemaQNameRefPtr) item)->name);
  1208. case XML_SCHEMA_TYPE_NOTATION:
  1209. return (((xmlSchemaNotationPtr) item)->name);
  1210. default:
  1211. /*
  1212. * Other components cannot have names.
  1213. */
  1214. break;
  1215. }
  1216. return (NULL);
  1217. }
  1218. #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
  1219. #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
  1220. /*
  1221. static const xmlChar *
  1222. xmlSchemaGetQNameRefName(void *ref)
  1223. {
  1224. return(((xmlSchemaQNameRefPtr) ref)->name);
  1225. }
  1226. static const xmlChar *
  1227. xmlSchemaGetQNameRefTargetNs(void *ref)
  1228. {
  1229. return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
  1230. }
  1231. */
  1232. static const xmlChar *
  1233. xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
  1234. {
  1235. if (item == NULL) {
  1236. return (NULL);
  1237. }
  1238. switch (item->type) {
  1239. case XML_SCHEMA_TYPE_ELEMENT:
  1240. return (((xmlSchemaElementPtr) item)->targetNamespace);
  1241. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1242. return (((xmlSchemaAttributePtr) item)->targetNamespace);
  1243. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1244. return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
  1245. case XML_SCHEMA_TYPE_BASIC:
  1246. return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
  1247. case XML_SCHEMA_TYPE_SIMPLE:
  1248. case XML_SCHEMA_TYPE_COMPLEX:
  1249. return (((xmlSchemaTypePtr) item)->targetNamespace);
  1250. case XML_SCHEMA_TYPE_GROUP:
  1251. return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
  1252. case XML_SCHEMA_TYPE_IDC_KEY:
  1253. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1254. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1255. return (((xmlSchemaIDCPtr) item)->targetNamespace);
  1256. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1257. if (WXS_ATTRUSE_DECL(item) != NULL) {
  1258. return(xmlSchemaGetComponentTargetNs(
  1259. WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
  1260. }
  1261. /* TODO: Will returning NULL break something? */
  1262. break;
  1263. case XML_SCHEMA_EXTRA_QNAMEREF:
  1264. return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
  1265. case XML_SCHEMA_TYPE_NOTATION:
  1266. return (((xmlSchemaNotationPtr) item)->targetNamespace);
  1267. default:
  1268. /*
  1269. * Other components cannot have names.
  1270. */
  1271. break;
  1272. }
  1273. return (NULL);
  1274. }
  1275. static const xmlChar*
  1276. xmlSchemaGetComponentQName(xmlChar **buf,
  1277. void *item)
  1278. {
  1279. return (xmlSchemaFormatQName(buf,
  1280. xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
  1281. xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
  1282. }
  1283. static const xmlChar*
  1284. xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
  1285. {
  1286. xmlChar *str = NULL;
  1287. *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
  1288. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1289. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
  1290. (xmlSchemaBasicItemPtr) item));
  1291. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1292. FREE_AND_NULL(str);
  1293. return(*buf);
  1294. }
  1295. static const xmlChar*
  1296. xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
  1297. {
  1298. return(xmlSchemaGetComponentDesignation(buf, idc));
  1299. }
  1300. /**
  1301. * xmlSchemaWildcardPCToString:
  1302. * @pc: the type of processContents
  1303. *
  1304. * Returns a string representation of the type of
  1305. * processContents.
  1306. */
  1307. static const xmlChar *
  1308. xmlSchemaWildcardPCToString(int pc)
  1309. {
  1310. switch (pc) {
  1311. case XML_SCHEMAS_ANY_SKIP:
  1312. return (BAD_CAST "skip");
  1313. case XML_SCHEMAS_ANY_LAX:
  1314. return (BAD_CAST "lax");
  1315. case XML_SCHEMAS_ANY_STRICT:
  1316. return (BAD_CAST "strict");
  1317. default:
  1318. return (BAD_CAST "invalid process contents");
  1319. }
  1320. }
  1321. /**
  1322. * xmlSchemaGetCanonValueWhtspExt:
  1323. * @val: the precomputed value
  1324. * @retValue: the returned value
  1325. * @ws: the whitespace type of the value
  1326. * @for_hash: non-zero if this is supposed to generate a string for hashing
  1327. *
  1328. * Get a the canonical representation of the value.
  1329. * The caller has to free the returned retValue.
  1330. *
  1331. * Returns 0 if the value could be built and -1 in case of
  1332. * API errors or if the value type is not supported yet.
  1333. */
  1334. static int
  1335. xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val,
  1336. xmlSchemaWhitespaceValueType ws,
  1337. xmlChar **retValue,
  1338. int for_hash)
  1339. {
  1340. int list;
  1341. xmlSchemaValType valType;
  1342. const xmlChar *value, *value2 = NULL;
  1343. if ((retValue == NULL) || (val == NULL))
  1344. return (-1);
  1345. list = xmlSchemaValueGetNext(val) ? 1 : 0;
  1346. *retValue = NULL;
  1347. do {
  1348. value = NULL;
  1349. valType = xmlSchemaGetValType(val);
  1350. switch (valType) {
  1351. case XML_SCHEMAS_STRING:
  1352. case XML_SCHEMAS_NORMSTRING:
  1353. case XML_SCHEMAS_ANYSIMPLETYPE:
  1354. value = xmlSchemaValueGetAsString(val);
  1355. if (value != NULL) {
  1356. if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
  1357. value2 = xmlSchemaCollapseString(value);
  1358. else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
  1359. value2 = xmlSchemaWhiteSpaceReplace(value);
  1360. if (value2 != NULL)
  1361. value = value2;
  1362. }
  1363. break;
  1364. default:
  1365. if (xmlSchemaGetCanonValue(val, &value2) == -1) {
  1366. if (value2 != NULL)
  1367. xmlFree((xmlChar *) value2);
  1368. goto internal_error;
  1369. }
  1370. if (for_hash && valType == XML_SCHEMAS_DECIMAL) {
  1371. /* We can mostly use the canonical value for hashing,
  1372. except in the case of decimal. There the canonical
  1373. representation requires a trailing '.0' even for
  1374. non-fractional numbers, but for the derived integer
  1375. types it forbids any decimal point. Nevertheless they
  1376. compare equal if the value is equal. We need to generate
  1377. the same hash value for this to work, and it's easiest
  1378. to just cut off the useless '.0' suffix for the
  1379. decimal type. */
  1380. int len = xmlStrlen(value2);
  1381. if (len > 2 && value2[len-1] == '0' && value2[len-2] == '.')
  1382. ((xmlChar*)value2)[len-2] = 0;
  1383. }
  1384. value = value2;
  1385. }
  1386. if (*retValue == NULL)
  1387. if (value == NULL) {
  1388. if (! list)
  1389. *retValue = xmlStrdup(BAD_CAST "");
  1390. } else
  1391. *retValue = xmlStrdup(value);
  1392. else if (value != NULL) {
  1393. /* List. */
  1394. *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
  1395. *retValue = xmlStrcat((xmlChar *) *retValue, value);
  1396. }
  1397. FREE_AND_NULL(value2)
  1398. val = xmlSchemaValueGetNext(val);
  1399. } while (val != NULL);
  1400. return (0);
  1401. internal_error:
  1402. if (*retValue != NULL)
  1403. xmlFree((xmlChar *) (*retValue));
  1404. if (value2 != NULL)
  1405. xmlFree((xmlChar *) value2);
  1406. return (-1);
  1407. }
  1408. static int
  1409. xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
  1410. xmlSchemaWhitespaceValueType ws,
  1411. xmlChar **retValue)
  1412. {
  1413. return xmlSchemaGetCanonValueWhtspExt_1(val, ws, retValue, 0);
  1414. }
  1415. static int
  1416. xmlSchemaGetCanonValueHash(xmlSchemaValPtr val,
  1417. xmlChar **retValue)
  1418. {
  1419. return xmlSchemaGetCanonValueWhtspExt_1(val, XML_SCHEMA_WHITESPACE_COLLAPSE,
  1420. retValue, 1);
  1421. }
  1422. /**
  1423. * xmlSchemaFormatItemForReport:
  1424. * @buf: the string buffer
  1425. * @itemDes: the designation of the item
  1426. * @itemName: the name of the item
  1427. * @item: the item as an object
  1428. * @itemNode: the node of the item
  1429. * @local: the local name
  1430. * @parsing: if the function is used during the parse
  1431. *
  1432. * Returns a representation of the given item used
  1433. * for error reports.
  1434. *
  1435. * The following order is used to build the resulting
  1436. * designation if the arguments are not NULL:
  1437. * 1a. If itemDes not NULL -> itemDes
  1438. * 1b. If (itemDes not NULL) and (itemName not NULL)
  1439. * -> itemDes + itemName
  1440. * 2. If the preceding was NULL and (item not NULL) -> item
  1441. * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
  1442. *
  1443. * If the itemNode is an attribute node, the name of the attribute
  1444. * will be appended to the result.
  1445. *
  1446. * Returns the formatted string and sets @buf to the resulting value.
  1447. */
  1448. static xmlChar*
  1449. xmlSchemaFormatItemForReport(xmlChar **buf,
  1450. const xmlChar *itemDes,
  1451. xmlSchemaBasicItemPtr item,
  1452. xmlNodePtr itemNode)
  1453. {
  1454. xmlChar *str = NULL;
  1455. int named = 1;
  1456. if (*buf != NULL) {
  1457. xmlFree(*buf);
  1458. *buf = NULL;
  1459. }
  1460. if (itemDes != NULL) {
  1461. *buf = xmlStrdup(itemDes);
  1462. } else if (item != NULL) {
  1463. switch (item->type) {
  1464. case XML_SCHEMA_TYPE_BASIC: {
  1465. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1466. if (WXS_IS_ATOMIC(type))
  1467. *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
  1468. else if (WXS_IS_LIST(type))
  1469. *buf = xmlStrdup(BAD_CAST "list type 'xs:");
  1470. else if (WXS_IS_UNION(type))
  1471. *buf = xmlStrdup(BAD_CAST "union type 'xs:");
  1472. else
  1473. *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
  1474. *buf = xmlStrcat(*buf, type->name);
  1475. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1476. }
  1477. break;
  1478. case XML_SCHEMA_TYPE_SIMPLE: {
  1479. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1480. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1481. *buf = xmlStrdup(BAD_CAST"");
  1482. } else {
  1483. *buf = xmlStrdup(BAD_CAST "local ");
  1484. }
  1485. if (WXS_IS_ATOMIC(type))
  1486. *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
  1487. else if (WXS_IS_LIST(type))
  1488. *buf = xmlStrcat(*buf, BAD_CAST "list type");
  1489. else if (WXS_IS_UNION(type))
  1490. *buf = xmlStrcat(*buf, BAD_CAST "union type");
  1491. else
  1492. *buf = xmlStrcat(*buf, BAD_CAST "simple type");
  1493. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1494. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1495. *buf = xmlStrcat(*buf, type->name);
  1496. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1497. }
  1498. }
  1499. break;
  1500. case XML_SCHEMA_TYPE_COMPLEX: {
  1501. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1502. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
  1503. *buf = xmlStrdup(BAD_CAST "");
  1504. else
  1505. *buf = xmlStrdup(BAD_CAST "local ");
  1506. *buf = xmlStrcat(*buf, BAD_CAST "complex type");
  1507. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1508. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1509. *buf = xmlStrcat(*buf, type->name);
  1510. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1511. }
  1512. }
  1513. break;
  1514. case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
  1515. xmlSchemaAttributeUsePtr ause;
  1516. ause = WXS_ATTR_USE_CAST item;
  1517. *buf = xmlStrdup(BAD_CAST "attribute use ");
  1518. if (WXS_ATTRUSE_DECL(ause) != NULL) {
  1519. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1520. *buf = xmlStrcat(*buf,
  1521. xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
  1522. FREE_AND_NULL(str)
  1523. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1524. } else {
  1525. *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
  1526. }
  1527. }
  1528. break;
  1529. case XML_SCHEMA_TYPE_ATTRIBUTE: {
  1530. xmlSchemaAttributePtr attr;
  1531. attr = (xmlSchemaAttributePtr) item;
  1532. *buf = xmlStrdup(BAD_CAST "attribute decl.");
  1533. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1534. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1535. attr->targetNamespace, attr->name));
  1536. FREE_AND_NULL(str)
  1537. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1538. }
  1539. break;
  1540. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1541. xmlSchemaGetComponentDesignation(buf, item);
  1542. break;
  1543. case XML_SCHEMA_TYPE_ELEMENT: {
  1544. xmlSchemaElementPtr elem;
  1545. elem = (xmlSchemaElementPtr) item;
  1546. *buf = xmlStrdup(BAD_CAST "element decl.");
  1547. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1548. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1549. elem->targetNamespace, elem->name));
  1550. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1551. }
  1552. break;
  1553. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1554. case XML_SCHEMA_TYPE_IDC_KEY:
  1555. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1556. if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
  1557. *buf = xmlStrdup(BAD_CAST "unique '");
  1558. else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
  1559. *buf = xmlStrdup(BAD_CAST "key '");
  1560. else
  1561. *buf = xmlStrdup(BAD_CAST "keyRef '");
  1562. *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
  1563. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1564. break;
  1565. case XML_SCHEMA_TYPE_ANY:
  1566. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1567. *buf = xmlStrdup(xmlSchemaWildcardPCToString(
  1568. ((xmlSchemaWildcardPtr) item)->processContents));
  1569. *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
  1570. break;
  1571. case XML_SCHEMA_FACET_MININCLUSIVE:
  1572. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  1573. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  1574. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  1575. case XML_SCHEMA_FACET_TOTALDIGITS:
  1576. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  1577. case XML_SCHEMA_FACET_PATTERN:
  1578. case XML_SCHEMA_FACET_ENUMERATION:
  1579. case XML_SCHEMA_FACET_WHITESPACE:
  1580. case XML_SCHEMA_FACET_LENGTH:
  1581. case XML_SCHEMA_FACET_MAXLENGTH:
  1582. case XML_SCHEMA_FACET_MINLENGTH:
  1583. *buf = xmlStrdup(BAD_CAST "facet '");
  1584. *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
  1585. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1586. break;
  1587. case XML_SCHEMA_TYPE_GROUP: {
  1588. *buf = xmlStrdup(BAD_CAST "model group def.");
  1589. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1590. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
  1591. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1592. FREE_AND_NULL(str)
  1593. }
  1594. break;
  1595. case XML_SCHEMA_TYPE_SEQUENCE:
  1596. case XML_SCHEMA_TYPE_CHOICE:
  1597. case XML_SCHEMA_TYPE_ALL:
  1598. case XML_SCHEMA_TYPE_PARTICLE:
  1599. *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
  1600. break;
  1601. case XML_SCHEMA_TYPE_NOTATION: {
  1602. *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
  1603. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1604. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
  1605. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1606. FREE_AND_NULL(str);
  1607. }
  1608. /* Falls through. */
  1609. default:
  1610. named = 0;
  1611. }
  1612. } else
  1613. named = 0;
  1614. if ((named == 0) && (itemNode != NULL)) {
  1615. xmlNodePtr elem;
  1616. if (itemNode->type == XML_ATTRIBUTE_NODE)
  1617. elem = itemNode->parent;
  1618. else
  1619. elem = itemNode;
  1620. *buf = xmlStrdup(BAD_CAST "Element '");
  1621. if (elem->ns != NULL) {
  1622. *buf = xmlStrcat(*buf,
  1623. xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
  1624. FREE_AND_NULL(str)
  1625. } else
  1626. *buf = xmlStrcat(*buf, elem->name);
  1627. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1628. }
  1629. if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
  1630. *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
  1631. if (itemNode->ns != NULL) {
  1632. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1633. itemNode->ns->href, itemNode->name));
  1634. FREE_AND_NULL(str)
  1635. } else
  1636. *buf = xmlStrcat(*buf, itemNode->name);
  1637. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1638. }
  1639. FREE_AND_NULL(str)
  1640. return (xmlEscapeFormatString(buf));
  1641. }
  1642. /**
  1643. * xmlSchemaFormatFacetEnumSet:
  1644. * @buf: the string buffer
  1645. * @type: the type holding the enumeration facets
  1646. *
  1647. * Builds a string consisting of all enumeration elements.
  1648. *
  1649. * Returns a string of all enumeration elements.
  1650. */
  1651. static const xmlChar *
  1652. xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
  1653. xmlChar **buf, xmlSchemaTypePtr type)
  1654. {
  1655. xmlSchemaFacetPtr facet;
  1656. xmlSchemaWhitespaceValueType ws;
  1657. xmlChar *value = NULL;
  1658. int res, found = 0;
  1659. if (*buf != NULL)
  1660. xmlFree(*buf);
  1661. *buf = NULL;
  1662. do {
  1663. /*
  1664. * Use the whitespace type of the base type.
  1665. */
  1666. ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
  1667. for (facet = type->facets; facet != NULL; facet = facet->next) {
  1668. if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
  1669. continue;
  1670. found = 1;
  1671. res = xmlSchemaGetCanonValueWhtspExt(facet->val,
  1672. ws, &value);
  1673. if (res == -1) {
  1674. xmlSchemaInternalErr(actxt,
  1675. "xmlSchemaFormatFacetEnumSet",
  1676. "compute the canonical lexical representation");
  1677. if (*buf != NULL)
  1678. xmlFree(*buf);
  1679. *buf = NULL;
  1680. return (NULL);
  1681. }
  1682. if (*buf == NULL)
  1683. *buf = xmlStrdup(BAD_CAST "'");
  1684. else
  1685. *buf = xmlStrcat(*buf, BAD_CAST ", '");
  1686. *buf = xmlStrcat(*buf, BAD_CAST value);
  1687. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1688. if (value != NULL) {
  1689. xmlFree((xmlChar *)value);
  1690. value = NULL;
  1691. }
  1692. }
  1693. /*
  1694. * The enumeration facet of a type restricts the enumeration
  1695. * facet of the ancestor type; i.e., such restricted enumerations
  1696. * do not belong to the set of the given type. Thus we break
  1697. * on the first found enumeration.
  1698. */
  1699. if (found)
  1700. break;
  1701. type = type->baseType;
  1702. } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
  1703. return ((const xmlChar *) *buf);
  1704. }
  1705. /************************************************************************
  1706. * *
  1707. * Error functions *
  1708. * *
  1709. ************************************************************************/
  1710. #if 0
  1711. static void
  1712. xmlSchemaErrMemory(const char *msg)
  1713. {
  1714. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
  1715. msg);
  1716. }
  1717. #endif
  1718. static void
  1719. xmlSchemaPSimpleErr(const char *msg)
  1720. {
  1721. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
  1722. msg);
  1723. }
  1724. /**
  1725. * xmlSchemaPErrMemory:
  1726. * @node: a context node
  1727. * @extra: extra information
  1728. *
  1729. * Handle an out of memory condition
  1730. */
  1731. static void
  1732. xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
  1733. const char *extra, xmlNodePtr node)
  1734. {
  1735. if (ctxt != NULL)
  1736. ctxt->nberrors++;
  1737. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
  1738. extra);
  1739. }
  1740. /**
  1741. * xmlSchemaPErr:
  1742. * @ctxt: the parsing context
  1743. * @node: the context node
  1744. * @error: the error code
  1745. * @msg: the error message
  1746. * @str1: extra data
  1747. * @str2: extra data
  1748. *
  1749. * Handle a parser error
  1750. */
  1751. static void LIBXML_ATTR_FORMAT(4,0)
  1752. xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
  1753. const char *msg, const xmlChar * str1, const xmlChar * str2)
  1754. {
  1755. xmlGenericErrorFunc channel = NULL;
  1756. xmlStructuredErrorFunc schannel = NULL;
  1757. void *data = NULL;
  1758. if (ctxt != NULL) {
  1759. ctxt->nberrors++;
  1760. ctxt->err = error;
  1761. channel = ctxt->error;
  1762. data = ctxt->errCtxt;
  1763. schannel = ctxt->serror;
  1764. }
  1765. __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
  1766. error, XML_ERR_ERROR, NULL, 0,
  1767. (const char *) str1, (const char *) str2, NULL, 0, 0,
  1768. msg, str1, str2);
  1769. }
  1770. /**
  1771. * xmlSchemaPErr2:
  1772. * @ctxt: the parsing context
  1773. * @node: the context node
  1774. * @node: the current child
  1775. * @error: the error code
  1776. * @msg: the error message
  1777. * @str1: extra data
  1778. * @str2: extra data
  1779. *
  1780. * Handle a parser error
  1781. */
  1782. static void LIBXML_ATTR_FORMAT(5,0)
  1783. xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  1784. xmlNodePtr child, int error,
  1785. const char *msg, const xmlChar * str1, const xmlChar * str2)
  1786. {
  1787. if (child != NULL)
  1788. xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
  1789. else
  1790. xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
  1791. }
  1792. /**
  1793. * xmlSchemaPErrExt:
  1794. * @ctxt: the parsing context
  1795. * @node: the context node
  1796. * @error: the error code
  1797. * @strData1: extra data
  1798. * @strData2: extra data
  1799. * @strData3: extra data
  1800. * @msg: the message
  1801. * @str1: extra parameter for the message display
  1802. * @str2: extra parameter for the message display
  1803. * @str3: extra parameter for the message display
  1804. * @str4: extra parameter for the message display
  1805. * @str5: extra parameter for the message display
  1806. *
  1807. * Handle a parser error
  1808. */
  1809. static void LIBXML_ATTR_FORMAT(7,0)
  1810. xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
  1811. const xmlChar * strData1, const xmlChar * strData2,
  1812. const xmlChar * strData3, const char *msg, const xmlChar * str1,
  1813. const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
  1814. const xmlChar * str5)
  1815. {
  1816. xmlGenericErrorFunc channel = NULL;
  1817. xmlStructuredErrorFunc schannel = NULL;
  1818. void *data = NULL;
  1819. if (ctxt != NULL) {
  1820. ctxt->nberrors++;
  1821. ctxt->err = error;
  1822. channel = ctxt->error;
  1823. data = ctxt->errCtxt;
  1824. schannel = ctxt->serror;
  1825. }
  1826. __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
  1827. error, XML_ERR_ERROR, NULL, 0,
  1828. (const char *) strData1, (const char *) strData2,
  1829. (const char *) strData3, 0, 0, msg, str1, str2,
  1830. str3, str4, str5);
  1831. }
  1832. /************************************************************************
  1833. * *
  1834. * Allround error functions *
  1835. * *
  1836. ************************************************************************/
  1837. /**
  1838. * xmlSchemaVTypeErrMemory:
  1839. * @node: a context node
  1840. * @extra: extra information
  1841. *
  1842. * Handle an out of memory condition
  1843. */
  1844. static void
  1845. xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
  1846. const char *extra, xmlNodePtr node)
  1847. {
  1848. if (ctxt != NULL) {
  1849. ctxt->nberrors++;
  1850. ctxt->err = XML_SCHEMAV_INTERNAL;
  1851. }
  1852. __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
  1853. extra);
  1854. }
  1855. static void LIBXML_ATTR_FORMAT(2,0)
  1856. xmlSchemaPSimpleInternalErr(xmlNodePtr node,
  1857. const char *msg, const xmlChar *str)
  1858. {
  1859. __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
  1860. msg, (const char *) str);
  1861. }
  1862. #define WXS_ERROR_TYPE_ERROR 1
  1863. #define WXS_ERROR_TYPE_WARNING 2
  1864. /**
  1865. * xmlSchemaErr4Line:
  1866. * @ctxt: the validation context
  1867. * @errorLevel: the error level
  1868. * @error: the error code
  1869. * @node: the context node
  1870. * @line: the line number
  1871. * @msg: the error message
  1872. * @str1: extra data
  1873. * @str2: extra data
  1874. * @str3: extra data
  1875. * @str4: extra data
  1876. *
  1877. * Handle a validation error
  1878. */
  1879. static void LIBXML_ATTR_FORMAT(6,0)
  1880. xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
  1881. xmlErrorLevel errorLevel,
  1882. int error, xmlNodePtr node, int line, const char *msg,
  1883. const xmlChar *str1, const xmlChar *str2,
  1884. const xmlChar *str3, const xmlChar *str4)
  1885. {
  1886. xmlStructuredErrorFunc schannel = NULL;
  1887. xmlGenericErrorFunc channel = NULL;
  1888. void *data = NULL;
  1889. if (ctxt != NULL) {
  1890. if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  1891. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
  1892. const char *file = NULL;
  1893. int col = 0;
  1894. if (errorLevel != XML_ERR_WARNING) {
  1895. vctxt->nberrors++;
  1896. vctxt->err = error;
  1897. channel = vctxt->error;
  1898. } else {
  1899. channel = vctxt->warning;
  1900. }
  1901. schannel = vctxt->serror;
  1902. data = vctxt->errCtxt;
  1903. /*
  1904. * Error node. If we specify a line number, then
  1905. * do not channel any node to the error function.
  1906. */
  1907. if (line == 0) {
  1908. if ((node == NULL) &&
  1909. (vctxt->depth >= 0) &&
  1910. (vctxt->inode != NULL)) {
  1911. node = vctxt->inode->node;
  1912. }
  1913. /*
  1914. * Get filename and line if no node-tree.
  1915. */
  1916. if ((node == NULL) &&
  1917. (vctxt->parserCtxt != NULL) &&
  1918. (vctxt->parserCtxt->input != NULL)) {
  1919. file = vctxt->parserCtxt->input->filename;
  1920. line = vctxt->parserCtxt->input->line;
  1921. col = vctxt->parserCtxt->input->col;
  1922. }
  1923. } else {
  1924. /*
  1925. * Override the given node's (if any) position
  1926. * and channel only the given line number.
  1927. */
  1928. node = NULL;
  1929. /*
  1930. * Get filename.
  1931. */
  1932. if (vctxt->doc != NULL)
  1933. file = (const char *) vctxt->doc->URL;
  1934. else if ((vctxt->parserCtxt != NULL) &&
  1935. (vctxt->parserCtxt->input != NULL))
  1936. file = vctxt->parserCtxt->input->filename;
  1937. }
  1938. if (vctxt->locFunc != NULL) {
  1939. if ((file == NULL) || (line == 0)) {
  1940. unsigned long l;
  1941. const char *f;
  1942. vctxt->locFunc(vctxt->locCtxt, &f, &l);
  1943. if (file == NULL)
  1944. file = f;
  1945. if (line == 0)
  1946. line = (int) l;
  1947. }
  1948. }
  1949. if ((file == NULL) && (vctxt->filename != NULL))
  1950. file = vctxt->filename;
  1951. __xmlRaiseError(schannel, channel, data, ctxt,
  1952. node, XML_FROM_SCHEMASV,
  1953. error, errorLevel, file, line,
  1954. (const char *) str1, (const char *) str2,
  1955. (const char *) str3, 0, col, msg, str1, str2, str3, str4);
  1956. } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
  1957. xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
  1958. if (errorLevel != XML_ERR_WARNING) {
  1959. pctxt->nberrors++;
  1960. pctxt->err = error;
  1961. channel = pctxt->error;
  1962. } else {
  1963. channel = pctxt->warning;
  1964. }
  1965. schannel = pctxt->serror;
  1966. data = pctxt->errCtxt;
  1967. __xmlRaiseError(schannel, channel, data, ctxt,
  1968. node, XML_FROM_SCHEMASP, error,
  1969. errorLevel, NULL, 0,
  1970. (const char *) str1, (const char *) str2,
  1971. (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
  1972. } else {
  1973. TODO
  1974. }
  1975. }
  1976. }
  1977. /**
  1978. * xmlSchemaErr3:
  1979. * @ctxt: the validation context
  1980. * @node: the context node
  1981. * @error: the error code
  1982. * @msg: the error message
  1983. * @str1: extra data
  1984. * @str2: extra data
  1985. * @str3: extra data
  1986. *
  1987. * Handle a validation error
  1988. */
  1989. static void LIBXML_ATTR_FORMAT(4,0)
  1990. xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
  1991. int error, xmlNodePtr node, const char *msg,
  1992. const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
  1993. {
  1994. xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
  1995. msg, str1, str2, str3, NULL);
  1996. }
  1997. static void LIBXML_ATTR_FORMAT(4,0)
  1998. xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
  1999. int error, xmlNodePtr node, const char *msg,
  2000. const xmlChar *str1, const xmlChar *str2,
  2001. const xmlChar *str3, const xmlChar *str4)
  2002. {
  2003. xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
  2004. msg, str1, str2, str3, str4);
  2005. }
  2006. static void LIBXML_ATTR_FORMAT(4,0)
  2007. xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
  2008. int error, xmlNodePtr node, const char *msg,
  2009. const xmlChar *str1, const xmlChar *str2)
  2010. {
  2011. xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
  2012. }
  2013. static xmlChar *
  2014. xmlSchemaFormatNodeForError(xmlChar ** msg,
  2015. xmlSchemaAbstractCtxtPtr actxt,
  2016. xmlNodePtr node)
  2017. {
  2018. xmlChar *str = NULL;
  2019. *msg = NULL;
  2020. if ((node != NULL) &&
  2021. (node->type != XML_ELEMENT_NODE) &&
  2022. (node->type != XML_ATTRIBUTE_NODE))
  2023. {
  2024. /*
  2025. * Don't try to format other nodes than element and
  2026. * attribute nodes.
  2027. * Play safe and return an empty string.
  2028. */
  2029. *msg = xmlStrdup(BAD_CAST "");
  2030. return(*msg);
  2031. }
  2032. if (node != NULL) {
  2033. /*
  2034. * Work on tree nodes.
  2035. */
  2036. if (node->type == XML_ATTRIBUTE_NODE) {
  2037. xmlNodePtr elem = node->parent;
  2038. *msg = xmlStrdup(BAD_CAST "Element '");
  2039. if (elem->ns != NULL)
  2040. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2041. elem->ns->href, elem->name));
  2042. else
  2043. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2044. NULL, elem->name));
  2045. FREE_AND_NULL(str);
  2046. *msg = xmlStrcat(*msg, BAD_CAST "', ");
  2047. *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
  2048. } else {
  2049. *msg = xmlStrdup(BAD_CAST "Element '");
  2050. }
  2051. if (node->ns != NULL)
  2052. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2053. node->ns->href, node->name));
  2054. else
  2055. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2056. NULL, node->name));
  2057. FREE_AND_NULL(str);
  2058. *msg = xmlStrcat(*msg, BAD_CAST "': ");
  2059. } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  2060. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
  2061. /*
  2062. * Work on node infos.
  2063. */
  2064. if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
  2065. xmlSchemaNodeInfoPtr ielem =
  2066. vctxt->elemInfos[vctxt->depth];
  2067. *msg = xmlStrdup(BAD_CAST "Element '");
  2068. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2069. ielem->nsName, ielem->localName));
  2070. FREE_AND_NULL(str);
  2071. *msg = xmlStrcat(*msg, BAD_CAST "', ");
  2072. *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
  2073. } else {
  2074. *msg = xmlStrdup(BAD_CAST "Element '");
  2075. }
  2076. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2077. vctxt->inode->nsName, vctxt->inode->localName));
  2078. FREE_AND_NULL(str);
  2079. *msg = xmlStrcat(*msg, BAD_CAST "': ");
  2080. } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
  2081. /*
  2082. * Hmm, no node while parsing?
  2083. * Return an empty string, in case NULL will break something.
  2084. */
  2085. *msg = xmlStrdup(BAD_CAST "");
  2086. } else {
  2087. TODO
  2088. return (NULL);
  2089. }
  2090. /*
  2091. * xmlSchemaFormatItemForReport() also returns an escaped format
  2092. * string, so do this before calling it below (in the future).
  2093. */
  2094. xmlEscapeFormatString(msg);
  2095. /*
  2096. * VAL TODO: The output of the given schema component is currently
  2097. * disabled.
  2098. */
  2099. #if 0
  2100. if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
  2101. *msg = xmlStrcat(*msg, BAD_CAST " [");
  2102. *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
  2103. NULL, type, NULL, 0));
  2104. FREE_AND_NULL(str)
  2105. *msg = xmlStrcat(*msg, BAD_CAST "]");
  2106. }
  2107. #endif
  2108. return (*msg);
  2109. }
  2110. static void LIBXML_ATTR_FORMAT(3,0)
  2111. xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
  2112. const char *funcName,
  2113. const char *message,
  2114. const xmlChar *str1,
  2115. const xmlChar *str2)
  2116. {
  2117. xmlChar *msg = NULL;
  2118. if (actxt == NULL)
  2119. return;
  2120. msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
  2121. msg = xmlStrcat(msg, BAD_CAST message);
  2122. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2123. if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
  2124. xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
  2125. (const char *) msg, (const xmlChar *) funcName, str1, str2);
  2126. else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
  2127. xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
  2128. (const char *) msg, (const xmlChar *) funcName, str1, str2);
  2129. FREE_AND_NULL(msg)
  2130. }
  2131. static void LIBXML_ATTR_FORMAT(3,0)
  2132. xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
  2133. const char *funcName,
  2134. const char *message)
  2135. {
  2136. xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
  2137. }
  2138. #if 0
  2139. static void LIBXML_ATTR_FORMAT(3,0)
  2140. xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
  2141. const char *funcName,
  2142. const char *message,
  2143. const xmlChar *str1,
  2144. const xmlChar *str2)
  2145. {
  2146. xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
  2147. str1, str2);
  2148. }
  2149. #endif
  2150. static void LIBXML_ATTR_FORMAT(5,0)
  2151. xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
  2152. xmlParserErrors error,
  2153. xmlNodePtr node,
  2154. xmlSchemaBasicItemPtr item,
  2155. const char *message,
  2156. const xmlChar *str1, const xmlChar *str2,
  2157. const xmlChar *str3, const xmlChar *str4)
  2158. {
  2159. xmlChar *msg = NULL;
  2160. if ((node == NULL) && (item != NULL) &&
  2161. (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
  2162. node = WXS_ITEM_NODE(item);
  2163. xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
  2164. msg = xmlStrcat(msg, BAD_CAST ": ");
  2165. } else
  2166. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2167. msg = xmlStrcat(msg, (const xmlChar *) message);
  2168. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2169. xmlSchemaErr4(actxt, error, node,
  2170. (const char *) msg, str1, str2, str3, str4);
  2171. FREE_AND_NULL(msg)
  2172. }
  2173. static void LIBXML_ATTR_FORMAT(5,0)
  2174. xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
  2175. xmlParserErrors error,
  2176. xmlNodePtr node,
  2177. xmlSchemaBasicItemPtr item,
  2178. const char *message,
  2179. const xmlChar *str1,
  2180. const xmlChar *str2)
  2181. {
  2182. xmlSchemaCustomErr4(actxt, error, node, item,
  2183. message, str1, str2, NULL, NULL);
  2184. }
  2185. static void LIBXML_ATTR_FORMAT(5,0)
  2186. xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
  2187. xmlParserErrors error,
  2188. xmlNodePtr node,
  2189. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2190. const char *message,
  2191. const xmlChar *str1,
  2192. const xmlChar *str2,
  2193. const xmlChar *str3)
  2194. {
  2195. xmlChar *msg = NULL;
  2196. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2197. msg = xmlStrcat(msg, (const xmlChar *) message);
  2198. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2199. /* URGENT TODO: Set the error code to something sane. */
  2200. xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
  2201. (const char *) msg, str1, str2, str3, NULL);
  2202. FREE_AND_NULL(msg)
  2203. }
  2204. static void LIBXML_ATTR_FORMAT(5,0)
  2205. xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
  2206. xmlParserErrors error,
  2207. xmlSchemaPSVIIDCNodePtr idcNode,
  2208. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2209. const char *message,
  2210. const xmlChar *str1,
  2211. const xmlChar *str2)
  2212. {
  2213. xmlChar *msg = NULL, *qname = NULL;
  2214. msg = xmlStrdup(BAD_CAST "Element '%s': ");
  2215. msg = xmlStrcat(msg, (const xmlChar *) message);
  2216. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2217. xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
  2218. error, NULL, idcNode->nodeLine, (const char *) msg,
  2219. xmlSchemaFormatQName(&qname,
  2220. vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
  2221. vctxt->nodeQNames->items[idcNode->nodeQNameID]),
  2222. str1, str2, NULL);
  2223. FREE_AND_NULL(qname);
  2224. FREE_AND_NULL(msg);
  2225. }
  2226. static int
  2227. xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
  2228. xmlNodePtr node)
  2229. {
  2230. if (node != NULL)
  2231. return (node->type);
  2232. if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
  2233. (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
  2234. return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
  2235. return (-1);
  2236. }
  2237. static int
  2238. xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
  2239. {
  2240. switch (item->type) {
  2241. case XML_SCHEMA_TYPE_COMPLEX:
  2242. case XML_SCHEMA_TYPE_SIMPLE:
  2243. if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
  2244. return(1);
  2245. break;
  2246. case XML_SCHEMA_TYPE_GROUP:
  2247. return (1);
  2248. case XML_SCHEMA_TYPE_ELEMENT:
  2249. if ( ((xmlSchemaElementPtr) item)->flags &
  2250. XML_SCHEMAS_ELEM_GLOBAL)
  2251. return(1);
  2252. break;
  2253. case XML_SCHEMA_TYPE_ATTRIBUTE:
  2254. if ( ((xmlSchemaAttributePtr) item)->flags &
  2255. XML_SCHEMAS_ATTR_GLOBAL)
  2256. return(1);
  2257. break;
  2258. /* Note that attribute groups are always global. */
  2259. default:
  2260. return(1);
  2261. }
  2262. return (0);
  2263. }
  2264. static void
  2265. xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
  2266. xmlParserErrors error,
  2267. xmlNodePtr node,
  2268. const xmlChar *value,
  2269. xmlSchemaTypePtr type,
  2270. int displayValue)
  2271. {
  2272. xmlChar *msg = NULL;
  2273. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2274. if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
  2275. XML_ATTRIBUTE_NODE))
  2276. msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
  2277. else
  2278. msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
  2279. "value of ");
  2280. if (! xmlSchemaIsGlobalItem(type))
  2281. msg = xmlStrcat(msg, BAD_CAST "the local ");
  2282. else
  2283. msg = xmlStrcat(msg, BAD_CAST "the ");
  2284. if (WXS_IS_ATOMIC(type))
  2285. msg = xmlStrcat(msg, BAD_CAST "atomic type");
  2286. else if (WXS_IS_LIST(type))
  2287. msg = xmlStrcat(msg, BAD_CAST "list type");
  2288. else if (WXS_IS_UNION(type))
  2289. msg = xmlStrcat(msg, BAD_CAST "union type");
  2290. if (xmlSchemaIsGlobalItem(type)) {
  2291. xmlChar *str = NULL;
  2292. msg = xmlStrcat(msg, BAD_CAST " '");
  2293. if (type->builtInType != 0) {
  2294. msg = xmlStrcat(msg, BAD_CAST "xs:");
  2295. str = xmlStrdup(type->name);
  2296. } else {
  2297. const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
  2298. if (!str)
  2299. str = xmlStrdup(qName);
  2300. }
  2301. msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
  2302. msg = xmlStrcat(msg, BAD_CAST "'");
  2303. FREE_AND_NULL(str);
  2304. }
  2305. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2306. if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
  2307. XML_ATTRIBUTE_NODE))
  2308. xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
  2309. else
  2310. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2311. FREE_AND_NULL(msg)
  2312. }
  2313. static const xmlChar *
  2314. xmlSchemaFormatErrorNodeQName(xmlChar ** str,
  2315. xmlSchemaNodeInfoPtr ni,
  2316. xmlNodePtr node)
  2317. {
  2318. if (node != NULL) {
  2319. if (node->ns != NULL)
  2320. return (xmlSchemaFormatQName(str, node->ns->href, node->name));
  2321. else
  2322. return (xmlSchemaFormatQName(str, NULL, node->name));
  2323. } else if (ni != NULL)
  2324. return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
  2325. return (NULL);
  2326. }
  2327. static void
  2328. xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
  2329. xmlParserErrors error,
  2330. xmlSchemaAttrInfoPtr ni,
  2331. xmlNodePtr node)
  2332. {
  2333. xmlChar *msg = NULL, *str = NULL;
  2334. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2335. msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
  2336. xmlSchemaErr(actxt, error, node, (const char *) msg,
  2337. xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
  2338. NULL);
  2339. FREE_AND_NULL(str)
  2340. FREE_AND_NULL(msg)
  2341. }
  2342. static void LIBXML_ATTR_FORMAT(5,0)
  2343. xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
  2344. xmlParserErrors error,
  2345. xmlNodePtr node,
  2346. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2347. const char *message,
  2348. int nbval,
  2349. int nbneg,
  2350. xmlChar **values)
  2351. {
  2352. xmlChar *str = NULL, *msg = NULL;
  2353. xmlChar *localName, *nsName;
  2354. const xmlChar *cur, *end;
  2355. int i;
  2356. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2357. msg = xmlStrcat(msg, (const xmlChar *) message);
  2358. msg = xmlStrcat(msg, BAD_CAST ".");
  2359. /*
  2360. * Note that is does not make sense to report that we have a
  2361. * wildcard here, since the wildcard might be unfolded into
  2362. * multiple transitions.
  2363. */
  2364. if (nbval + nbneg > 0) {
  2365. if (nbval + nbneg > 1) {
  2366. str = xmlStrdup(BAD_CAST " Expected is one of ( ");
  2367. } else
  2368. str = xmlStrdup(BAD_CAST " Expected is ( ");
  2369. nsName = NULL;
  2370. for (i = 0; i < nbval + nbneg; i++) {
  2371. cur = values[i];
  2372. if (cur == NULL)
  2373. continue;
  2374. if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
  2375. (cur[3] == ' ')) {
  2376. cur += 4;
  2377. str = xmlStrcat(str, BAD_CAST "##other");
  2378. }
  2379. /*
  2380. * Get the local name.
  2381. */
  2382. localName = NULL;
  2383. end = cur;
  2384. if (*end == '*') {
  2385. localName = xmlStrdup(BAD_CAST "*");
  2386. end++;
  2387. } else {
  2388. while ((*end != 0) && (*end != '|'))
  2389. end++;
  2390. localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
  2391. }
  2392. if (*end != 0) {
  2393. end++;
  2394. /*
  2395. * Skip "*|*" if they come with negated expressions, since
  2396. * they represent the same negated wildcard.
  2397. */
  2398. if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
  2399. /*
  2400. * Get the namespace name.
  2401. */
  2402. cur = end;
  2403. if (*end == '*') {
  2404. nsName = xmlStrdup(BAD_CAST "{*}");
  2405. } else {
  2406. while (*end != 0)
  2407. end++;
  2408. if (i >= nbval)
  2409. nsName = xmlStrdup(BAD_CAST "{##other:");
  2410. else
  2411. nsName = xmlStrdup(BAD_CAST "{");
  2412. nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
  2413. nsName = xmlStrcat(nsName, BAD_CAST "}");
  2414. }
  2415. str = xmlStrcat(str, BAD_CAST nsName);
  2416. FREE_AND_NULL(nsName)
  2417. } else {
  2418. FREE_AND_NULL(localName);
  2419. continue;
  2420. }
  2421. }
  2422. str = xmlStrcat(str, BAD_CAST localName);
  2423. FREE_AND_NULL(localName);
  2424. if (i < nbval + nbneg -1)
  2425. str = xmlStrcat(str, BAD_CAST ", ");
  2426. }
  2427. str = xmlStrcat(str, BAD_CAST " ).\n");
  2428. msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
  2429. FREE_AND_NULL(str)
  2430. } else
  2431. msg = xmlStrcat(msg, BAD_CAST "\n");
  2432. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2433. xmlFree(msg);
  2434. }
  2435. static void LIBXML_ATTR_FORMAT(8,0)
  2436. xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
  2437. xmlParserErrors error,
  2438. xmlNodePtr node,
  2439. const xmlChar *value,
  2440. unsigned long length,
  2441. xmlSchemaTypePtr type,
  2442. xmlSchemaFacetPtr facet,
  2443. const char *message,
  2444. const xmlChar *str1,
  2445. const xmlChar *str2)
  2446. {
  2447. xmlChar *str = NULL, *msg = NULL;
  2448. xmlSchemaTypeType facetType;
  2449. int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
  2450. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2451. if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
  2452. facetType = XML_SCHEMA_FACET_ENUMERATION;
  2453. /*
  2454. * If enumerations are validated, one must not expect the
  2455. * facet to be given.
  2456. */
  2457. } else
  2458. facetType = facet->type;
  2459. msg = xmlStrcat(msg, BAD_CAST "[");
  2460. msg = xmlStrcat(msg, BAD_CAST "facet '");
  2461. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
  2462. msg = xmlStrcat(msg, BAD_CAST "'] ");
  2463. if (message == NULL) {
  2464. /*
  2465. * Use a default message.
  2466. */
  2467. if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
  2468. (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
  2469. (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
  2470. char len[25], actLen[25];
  2471. /* FIXME, TODO: What is the max expected string length of the
  2472. * this value?
  2473. */
  2474. if (nodeType == XML_ATTRIBUTE_NODE)
  2475. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
  2476. else
  2477. msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
  2478. snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
  2479. snprintf(actLen, 24, "%lu", length);
  2480. if (facetType == XML_SCHEMA_FACET_LENGTH)
  2481. msg = xmlStrcat(msg,
  2482. BAD_CAST "this differs from the allowed length of '%s'.\n");
  2483. else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
  2484. msg = xmlStrcat(msg,
  2485. BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
  2486. else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
  2487. msg = xmlStrcat(msg,
  2488. BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
  2489. if (nodeType == XML_ATTRIBUTE_NODE)
  2490. xmlSchemaErr3(actxt, error, node, (const char *) msg,
  2491. value, (const xmlChar *) actLen, (const xmlChar *) len);
  2492. else
  2493. xmlSchemaErr(actxt, error, node, (const char *) msg,
  2494. (const xmlChar *) actLen, (const xmlChar *) len);
  2495. } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
  2496. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
  2497. "of the set {%s}.\n");
  2498. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2499. xmlSchemaFormatFacetEnumSet(actxt, &str, type));
  2500. } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
  2501. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
  2502. "by the pattern '%s'.\n");
  2503. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2504. facet->value);
  2505. } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
  2506. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
  2507. "minimum value allowed ('%s').\n");
  2508. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2509. facet->value);
  2510. } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
  2511. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
  2512. "maximum value allowed ('%s').\n");
  2513. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2514. facet->value);
  2515. } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
  2516. msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
  2517. "'%s'.\n");
  2518. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2519. facet->value);
  2520. } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
  2521. msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
  2522. "'%s'.\n");
  2523. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2524. facet->value);
  2525. } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
  2526. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
  2527. "digits than are allowed ('%s').\n");
  2528. xmlSchemaErr(actxt, error, node, (const char*) msg, value,
  2529. facet->value);
  2530. } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
  2531. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
  2532. "digits than are allowed ('%s').\n");
  2533. xmlSchemaErr(actxt, error, node, (const char*) msg, value,
  2534. facet->value);
  2535. } else if (nodeType == XML_ATTRIBUTE_NODE) {
  2536. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
  2537. xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
  2538. } else {
  2539. msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
  2540. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2541. }
  2542. } else {
  2543. msg = xmlStrcat(msg, (const xmlChar *) message);
  2544. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2545. xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
  2546. }
  2547. FREE_AND_NULL(str)
  2548. xmlFree(msg);
  2549. }
  2550. #define VERROR(err, type, msg) \
  2551. xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
  2552. #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
  2553. #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
  2554. #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
  2555. #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
  2556. /**
  2557. * xmlSchemaPMissingAttrErr:
  2558. * @ctxt: the schema validation context
  2559. * @ownerItem: the owner as a schema object
  2560. * @ownerElem: the owner as an element node
  2561. * @node: the parent element node of the missing attribute node
  2562. * @type: the corresponding type of the attribute node
  2563. *
  2564. * Reports an illegal attribute.
  2565. */
  2566. static void
  2567. xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2568. xmlParserErrors error,
  2569. xmlSchemaBasicItemPtr ownerItem,
  2570. xmlNodePtr ownerElem,
  2571. const char *name,
  2572. const char *message)
  2573. {
  2574. xmlChar *des = NULL;
  2575. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2576. if (message != NULL)
  2577. xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
  2578. else
  2579. xmlSchemaPErr(ctxt, ownerElem, error,
  2580. "%s: The attribute '%s' is required but missing.\n",
  2581. BAD_CAST des, BAD_CAST name);
  2582. FREE_AND_NULL(des);
  2583. }
  2584. /**
  2585. * xmlSchemaPResCompAttrErr:
  2586. * @ctxt: the schema validation context
  2587. * @error: the error code
  2588. * @ownerItem: the owner as a schema object
  2589. * @ownerElem: the owner as an element node
  2590. * @name: the name of the attribute holding the QName
  2591. * @refName: the referenced local name
  2592. * @refURI: the referenced namespace URI
  2593. * @message: optional message
  2594. *
  2595. * Used to report QName attribute values that failed to resolve
  2596. * to schema components.
  2597. */
  2598. static void
  2599. xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2600. xmlParserErrors error,
  2601. xmlSchemaBasicItemPtr ownerItem,
  2602. xmlNodePtr ownerElem,
  2603. const char *name,
  2604. const xmlChar *refName,
  2605. const xmlChar *refURI,
  2606. xmlSchemaTypeType refType,
  2607. const char *refTypeStr)
  2608. {
  2609. xmlChar *des = NULL, *strA = NULL;
  2610. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2611. if (refTypeStr == NULL)
  2612. refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
  2613. xmlSchemaPErrExt(ctxt, ownerElem, error,
  2614. NULL, NULL, NULL,
  2615. "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
  2616. "%s.\n", BAD_CAST des, BAD_CAST name,
  2617. xmlSchemaFormatQName(&strA, refURI, refName),
  2618. BAD_CAST refTypeStr, NULL);
  2619. FREE_AND_NULL(des)
  2620. FREE_AND_NULL(strA)
  2621. }
  2622. /**
  2623. * xmlSchemaPCustomAttrErr:
  2624. * @ctxt: the schema parser context
  2625. * @error: the error code
  2626. * @ownerDes: the designation of the owner
  2627. * @ownerItem: the owner as a schema object
  2628. * @attr: the illegal attribute node
  2629. *
  2630. * Reports an illegal attribute during the parse.
  2631. */
  2632. static void
  2633. xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2634. xmlParserErrors error,
  2635. xmlChar **ownerDes,
  2636. xmlSchemaBasicItemPtr ownerItem,
  2637. xmlAttrPtr attr,
  2638. const char *msg)
  2639. {
  2640. xmlChar *des = NULL;
  2641. if (ownerDes == NULL)
  2642. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
  2643. else if (*ownerDes == NULL) {
  2644. xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
  2645. des = *ownerDes;
  2646. } else
  2647. des = *ownerDes;
  2648. if (attr == NULL) {
  2649. xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
  2650. "%s, attribute '%s': %s.\n",
  2651. BAD_CAST des, (const xmlChar *) "Unknown",
  2652. (const xmlChar *) msg, NULL, NULL);
  2653. } else {
  2654. xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
  2655. "%s, attribute '%s': %s.\n",
  2656. BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
  2657. }
  2658. if (ownerDes == NULL)
  2659. FREE_AND_NULL(des);
  2660. }
  2661. /**
  2662. * xmlSchemaPIllegalAttrErr:
  2663. * @ctxt: the schema parser context
  2664. * @error: the error code
  2665. * @ownerItem: the attribute's owner item
  2666. * @attr: the illegal attribute node
  2667. *
  2668. * Reports an illegal attribute during the parse.
  2669. */
  2670. static void
  2671. xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2672. xmlParserErrors error,
  2673. xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
  2674. xmlAttrPtr attr)
  2675. {
  2676. xmlChar *strA = NULL, *strB = NULL;
  2677. xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
  2678. xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
  2679. "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
  2680. xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
  2681. NULL, NULL);
  2682. FREE_AND_NULL(strA);
  2683. FREE_AND_NULL(strB);
  2684. }
  2685. /**
  2686. * xmlSchemaPCustomErr:
  2687. * @ctxt: the schema parser context
  2688. * @error: the error code
  2689. * @itemDes: the designation of the schema item
  2690. * @item: the schema item
  2691. * @itemElem: the node of the schema item
  2692. * @message: the error message
  2693. * @str1: an optional param for the error message
  2694. * @str2: an optional param for the error message
  2695. * @str3: an optional param for the error message
  2696. *
  2697. * Reports an error during parsing.
  2698. */
  2699. static void LIBXML_ATTR_FORMAT(5,0)
  2700. xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
  2701. xmlParserErrors error,
  2702. xmlSchemaBasicItemPtr item,
  2703. xmlNodePtr itemElem,
  2704. const char *message,
  2705. const xmlChar *str1,
  2706. const xmlChar *str2,
  2707. const xmlChar *str3)
  2708. {
  2709. xmlChar *des = NULL, *msg = NULL;
  2710. xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
  2711. msg = xmlStrdup(BAD_CAST "%s: ");
  2712. msg = xmlStrcat(msg, (const xmlChar *) message);
  2713. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2714. if ((itemElem == NULL) && (item != NULL))
  2715. itemElem = WXS_ITEM_NODE(item);
  2716. xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
  2717. (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
  2718. FREE_AND_NULL(des);
  2719. FREE_AND_NULL(msg);
  2720. }
  2721. /**
  2722. * xmlSchemaPCustomErr:
  2723. * @ctxt: the schema parser context
  2724. * @error: the error code
  2725. * @itemDes: the designation of the schema item
  2726. * @item: the schema item
  2727. * @itemElem: the node of the schema item
  2728. * @message: the error message
  2729. * @str1: the optional param for the error message
  2730. *
  2731. * Reports an error during parsing.
  2732. */
  2733. static void LIBXML_ATTR_FORMAT(5,0)
  2734. xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
  2735. xmlParserErrors error,
  2736. xmlSchemaBasicItemPtr item,
  2737. xmlNodePtr itemElem,
  2738. const char *message,
  2739. const xmlChar *str1)
  2740. {
  2741. xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
  2742. str1, NULL, NULL);
  2743. }
  2744. /**
  2745. * xmlSchemaPAttrUseErr:
  2746. * @ctxt: the schema parser context
  2747. * @error: the error code
  2748. * @itemDes: the designation of the schema type
  2749. * @item: the schema type
  2750. * @itemElem: the node of the schema type
  2751. * @attr: the invalid schema attribute
  2752. * @message: the error message
  2753. * @str1: the optional param for the error message
  2754. *
  2755. * Reports an attribute use error during parsing.
  2756. */
  2757. static void LIBXML_ATTR_FORMAT(6,0)
  2758. xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
  2759. xmlParserErrors error,
  2760. xmlNodePtr node,
  2761. xmlSchemaBasicItemPtr ownerItem,
  2762. const xmlSchemaAttributeUsePtr attruse,
  2763. const char *message,
  2764. const xmlChar *str1, const xmlChar *str2,
  2765. const xmlChar *str3,const xmlChar *str4)
  2766. {
  2767. xmlChar *str = NULL, *msg = NULL;
  2768. xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
  2769. msg = xmlStrcat(msg, BAD_CAST ", ");
  2770. msg = xmlStrcat(msg,
  2771. BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
  2772. WXS_BASIC_CAST attruse, NULL));
  2773. FREE_AND_NULL(str);
  2774. msg = xmlStrcat(msg, BAD_CAST ": ");
  2775. msg = xmlStrcat(msg, (const xmlChar *) message);
  2776. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2777. xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
  2778. (const char *) msg, str1, str2, str3, str4);
  2779. xmlFree(msg);
  2780. }
  2781. /**
  2782. * xmlSchemaPIllegalFacetAtomicErr:
  2783. * @ctxt: the schema parser context
  2784. * @error: the error code
  2785. * @type: the schema type
  2786. * @baseType: the base type of type
  2787. * @facet: the illegal facet
  2788. *
  2789. * Reports an illegal facet for atomic simple types.
  2790. */
  2791. static void
  2792. xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
  2793. xmlParserErrors error,
  2794. xmlSchemaTypePtr type,
  2795. xmlSchemaTypePtr baseType,
  2796. xmlSchemaFacetPtr facet)
  2797. {
  2798. xmlChar *des = NULL, *strT = NULL;
  2799. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
  2800. xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
  2801. "%s: The facet '%s' is not allowed on types derived from the "
  2802. "type %s.\n",
  2803. BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
  2804. xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
  2805. NULL, NULL);
  2806. FREE_AND_NULL(des);
  2807. FREE_AND_NULL(strT);
  2808. }
  2809. /**
  2810. * xmlSchemaPIllegalFacetListUnionErr:
  2811. * @ctxt: the schema parser context
  2812. * @error: the error code
  2813. * @itemDes: the designation of the schema item involved
  2814. * @item: the schema item involved
  2815. * @facet: the illegal facet
  2816. *
  2817. * Reports an illegal facet for <list> and <union>.
  2818. */
  2819. static void
  2820. xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
  2821. xmlParserErrors error,
  2822. xmlSchemaTypePtr type,
  2823. xmlSchemaFacetPtr facet)
  2824. {
  2825. xmlChar *des = NULL;
  2826. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
  2827. type->node);
  2828. xmlSchemaPErr(ctxt, type->node, error,
  2829. "%s: The facet '%s' is not allowed.\n",
  2830. BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
  2831. FREE_AND_NULL(des);
  2832. }
  2833. /**
  2834. * xmlSchemaPMutualExclAttrErr:
  2835. * @ctxt: the schema validation context
  2836. * @error: the error code
  2837. * @elemDes: the designation of the parent element node
  2838. * @attr: the bad attribute node
  2839. * @type: the corresponding type of the attribute node
  2840. *
  2841. * Reports an illegal attribute.
  2842. */
  2843. static void
  2844. xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2845. xmlParserErrors error,
  2846. xmlSchemaBasicItemPtr ownerItem,
  2847. xmlAttrPtr attr,
  2848. const char *name1,
  2849. const char *name2)
  2850. {
  2851. xmlChar *des = NULL;
  2852. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
  2853. xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
  2854. "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
  2855. BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
  2856. FREE_AND_NULL(des);
  2857. }
  2858. /**
  2859. * xmlSchemaPSimpleTypeErr:
  2860. * @ctxt: the schema validation context
  2861. * @error: the error code
  2862. * @type: the type specifier
  2863. * @ownerItem: the schema object if existent
  2864. * @node: the validated node
  2865. * @value: the validated value
  2866. *
  2867. * Reports a simple type validation error.
  2868. * TODO: Should this report the value of an element as well?
  2869. */
  2870. static void LIBXML_ATTR_FORMAT(8,0)
  2871. xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
  2872. xmlParserErrors error,
  2873. xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
  2874. xmlNodePtr node,
  2875. xmlSchemaTypePtr type,
  2876. const char *expected,
  2877. const xmlChar *value,
  2878. const char *message,
  2879. const xmlChar *str1,
  2880. const xmlChar *str2)
  2881. {
  2882. xmlChar *msg = NULL;
  2883. xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
  2884. if (message == NULL) {
  2885. /*
  2886. * Use default messages.
  2887. */
  2888. if (type != NULL) {
  2889. if (node->type == XML_ATTRIBUTE_NODE)
  2890. msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
  2891. else
  2892. msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
  2893. "valid value of ");
  2894. if (! xmlSchemaIsGlobalItem(type))
  2895. msg = xmlStrcat(msg, BAD_CAST "the local ");
  2896. else
  2897. msg = xmlStrcat(msg, BAD_CAST "the ");
  2898. if (WXS_IS_ATOMIC(type))
  2899. msg = xmlStrcat(msg, BAD_CAST "atomic type");
  2900. else if (WXS_IS_LIST(type))
  2901. msg = xmlStrcat(msg, BAD_CAST "list type");
  2902. else if (WXS_IS_UNION(type))
  2903. msg = xmlStrcat(msg, BAD_CAST "union type");
  2904. if (xmlSchemaIsGlobalItem(type)) {
  2905. xmlChar *str = NULL;
  2906. msg = xmlStrcat(msg, BAD_CAST " '");
  2907. if (type->builtInType != 0) {
  2908. msg = xmlStrcat(msg, BAD_CAST "xs:");
  2909. str = xmlStrdup(type->name);
  2910. } else {
  2911. const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
  2912. if (!str)
  2913. str = xmlStrdup(qName);
  2914. }
  2915. msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
  2916. msg = xmlStrcat(msg, BAD_CAST "'.");
  2917. FREE_AND_NULL(str);
  2918. }
  2919. } else {
  2920. if (node->type == XML_ATTRIBUTE_NODE)
  2921. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
  2922. else
  2923. msg = xmlStrcat(msg, BAD_CAST "The character content is not "
  2924. "valid.");
  2925. }
  2926. if (expected) {
  2927. xmlChar *expectedEscaped = xmlCharStrdup(expected);
  2928. msg = xmlStrcat(msg, BAD_CAST " Expected is '");
  2929. msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
  2930. FREE_AND_NULL(expectedEscaped);
  2931. msg = xmlStrcat(msg, BAD_CAST "'.\n");
  2932. } else
  2933. msg = xmlStrcat(msg, BAD_CAST "\n");
  2934. if (node->type == XML_ATTRIBUTE_NODE)
  2935. xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
  2936. else
  2937. xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
  2938. } else {
  2939. msg = xmlStrcat(msg, BAD_CAST message);
  2940. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2941. xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
  2942. (const char*) msg, str1, str2, NULL, NULL, NULL);
  2943. }
  2944. /* Cleanup. */
  2945. FREE_AND_NULL(msg)
  2946. }
  2947. /**
  2948. * xmlSchemaPContentErr:
  2949. * @ctxt: the schema parser context
  2950. * @error: the error code
  2951. * @ownerItem: the owner item of the holder of the content
  2952. * @ownerElem: the node of the holder of the content
  2953. * @child: the invalid child node
  2954. * @message: the optional error message
  2955. * @content: the optional string describing the correct content
  2956. *
  2957. * Reports an error concerning the content of a schema element.
  2958. */
  2959. static void
  2960. xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
  2961. xmlParserErrors error,
  2962. xmlSchemaBasicItemPtr ownerItem,
  2963. xmlNodePtr ownerElem,
  2964. xmlNodePtr child,
  2965. const char *message,
  2966. const char *content)
  2967. {
  2968. xmlChar *des = NULL;
  2969. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2970. if (message != NULL)
  2971. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2972. "%s: %s.\n",
  2973. BAD_CAST des, BAD_CAST message);
  2974. else {
  2975. if (content != NULL) {
  2976. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2977. "%s: The content is not valid. Expected is %s.\n",
  2978. BAD_CAST des, BAD_CAST content);
  2979. } else {
  2980. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2981. "%s: The content is not valid.\n",
  2982. BAD_CAST des, NULL);
  2983. }
  2984. }
  2985. FREE_AND_NULL(des)
  2986. }
  2987. /************************************************************************
  2988. * *
  2989. * Streamable error functions *
  2990. * *
  2991. ************************************************************************/
  2992. /************************************************************************
  2993. * *
  2994. * Validation helper functions *
  2995. * *
  2996. ************************************************************************/
  2997. /************************************************************************
  2998. * *
  2999. * Allocation functions *
  3000. * *
  3001. ************************************************************************/
  3002. /**
  3003. * xmlSchemaNewSchemaForParserCtxt:
  3004. * @ctxt: a schema validation context
  3005. *
  3006. * Allocate a new Schema structure.
  3007. *
  3008. * Returns the newly allocated structure or NULL in case or error
  3009. */
  3010. static xmlSchemaPtr
  3011. xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
  3012. {
  3013. xmlSchemaPtr ret;
  3014. ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
  3015. if (ret == NULL) {
  3016. xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
  3017. return (NULL);
  3018. }
  3019. memset(ret, 0, sizeof(xmlSchema));
  3020. ret->dict = ctxt->dict;
  3021. xmlDictReference(ret->dict);
  3022. return (ret);
  3023. }
  3024. /**
  3025. * xmlSchemaNewFacet:
  3026. *
  3027. * Allocate a new Facet structure.
  3028. *
  3029. * Returns the newly allocated structure or NULL in case or error
  3030. */
  3031. xmlSchemaFacetPtr
  3032. xmlSchemaNewFacet(void)
  3033. {
  3034. xmlSchemaFacetPtr ret;
  3035. ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
  3036. if (ret == NULL) {
  3037. return (NULL);
  3038. }
  3039. memset(ret, 0, sizeof(xmlSchemaFacet));
  3040. return (ret);
  3041. }
  3042. /**
  3043. * xmlSchemaNewAnnot:
  3044. * @ctxt: a schema validation context
  3045. * @node: a node
  3046. *
  3047. * Allocate a new annotation structure.
  3048. *
  3049. * Returns the newly allocated structure or NULL in case or error
  3050. */
  3051. static xmlSchemaAnnotPtr
  3052. xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
  3053. {
  3054. xmlSchemaAnnotPtr ret;
  3055. ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
  3056. if (ret == NULL) {
  3057. xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
  3058. return (NULL);
  3059. }
  3060. memset(ret, 0, sizeof(xmlSchemaAnnot));
  3061. ret->content = node;
  3062. return (ret);
  3063. }
  3064. static xmlSchemaItemListPtr
  3065. xmlSchemaItemListCreate(void)
  3066. {
  3067. xmlSchemaItemListPtr ret;
  3068. ret = xmlMalloc(sizeof(xmlSchemaItemList));
  3069. if (ret == NULL) {
  3070. xmlSchemaPErrMemory(NULL,
  3071. "allocating an item list structure", NULL);
  3072. return (NULL);
  3073. }
  3074. memset(ret, 0, sizeof(xmlSchemaItemList));
  3075. return (ret);
  3076. }
  3077. static void
  3078. xmlSchemaItemListClear(xmlSchemaItemListPtr list)
  3079. {
  3080. if (list->items != NULL) {
  3081. xmlFree(list->items);
  3082. list->items = NULL;
  3083. }
  3084. list->nbItems = 0;
  3085. list->sizeItems = 0;
  3086. }
  3087. static int
  3088. xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
  3089. {
  3090. if (list->items == NULL) {
  3091. list->items = (void **) xmlMalloc(
  3092. 20 * sizeof(void *));
  3093. if (list->items == NULL) {
  3094. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3095. return(-1);
  3096. }
  3097. list->sizeItems = 20;
  3098. } else if (list->sizeItems <= list->nbItems) {
  3099. list->sizeItems *= 2;
  3100. list->items = (void **) xmlRealloc(list->items,
  3101. list->sizeItems * sizeof(void *));
  3102. if (list->items == NULL) {
  3103. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3104. list->sizeItems = 0;
  3105. return(-1);
  3106. }
  3107. }
  3108. list->items[list->nbItems++] = item;
  3109. return(0);
  3110. }
  3111. static int
  3112. xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
  3113. int initialSize,
  3114. void *item)
  3115. {
  3116. if (list->items == NULL) {
  3117. if (initialSize <= 0)
  3118. initialSize = 1;
  3119. list->items = (void **) xmlMalloc(
  3120. initialSize * sizeof(void *));
  3121. if (list->items == NULL) {
  3122. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3123. return(-1);
  3124. }
  3125. list->sizeItems = initialSize;
  3126. } else if (list->sizeItems <= list->nbItems) {
  3127. list->sizeItems *= 2;
  3128. list->items = (void **) xmlRealloc(list->items,
  3129. list->sizeItems * sizeof(void *));
  3130. if (list->items == NULL) {
  3131. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3132. list->sizeItems = 0;
  3133. return(-1);
  3134. }
  3135. }
  3136. list->items[list->nbItems++] = item;
  3137. return(0);
  3138. }
  3139. static int
  3140. xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
  3141. {
  3142. if (list->items == NULL) {
  3143. list->items = (void **) xmlMalloc(
  3144. 20 * sizeof(void *));
  3145. if (list->items == NULL) {
  3146. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3147. return(-1);
  3148. }
  3149. list->sizeItems = 20;
  3150. } else if (list->sizeItems <= list->nbItems) {
  3151. list->sizeItems *= 2;
  3152. list->items = (void **) xmlRealloc(list->items,
  3153. list->sizeItems * sizeof(void *));
  3154. if (list->items == NULL) {
  3155. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3156. list->sizeItems = 0;
  3157. return(-1);
  3158. }
  3159. }
  3160. /*
  3161. * Just append if the index is greater/equal than the item count.
  3162. */
  3163. if (idx >= list->nbItems) {
  3164. list->items[list->nbItems++] = item;
  3165. } else {
  3166. int i;
  3167. for (i = list->nbItems; i > idx; i--)
  3168. list->items[i] = list->items[i-1];
  3169. list->items[idx] = item;
  3170. list->nbItems++;
  3171. }
  3172. return(0);
  3173. }
  3174. #if 0 /* enable if ever needed */
  3175. static int
  3176. xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
  3177. int initialSize,
  3178. void *item,
  3179. int idx)
  3180. {
  3181. if (list->items == NULL) {
  3182. if (initialSize <= 0)
  3183. initialSize = 1;
  3184. list->items = (void **) xmlMalloc(
  3185. initialSize * sizeof(void *));
  3186. if (list->items == NULL) {
  3187. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3188. return(-1);
  3189. }
  3190. list->sizeItems = initialSize;
  3191. } else if (list->sizeItems <= list->nbItems) {
  3192. list->sizeItems *= 2;
  3193. list->items = (void **) xmlRealloc(list->items,
  3194. list->sizeItems * sizeof(void *));
  3195. if (list->items == NULL) {
  3196. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3197. list->sizeItems = 0;
  3198. return(-1);
  3199. }
  3200. }
  3201. /*
  3202. * Just append if the index is greater/equal than the item count.
  3203. */
  3204. if (idx >= list->nbItems) {
  3205. list->items[list->nbItems++] = item;
  3206. } else {
  3207. int i;
  3208. for (i = list->nbItems; i > idx; i--)
  3209. list->items[i] = list->items[i-1];
  3210. list->items[idx] = item;
  3211. list->nbItems++;
  3212. }
  3213. return(0);
  3214. }
  3215. #endif
  3216. static int
  3217. xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
  3218. {
  3219. int i;
  3220. if ((list->items == NULL) || (idx >= list->nbItems)) {
  3221. xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
  3222. "index error.\n");
  3223. return(-1);
  3224. }
  3225. if (list->nbItems == 1) {
  3226. /* TODO: Really free the list? */
  3227. xmlFree(list->items);
  3228. list->items = NULL;
  3229. list->nbItems = 0;
  3230. list->sizeItems = 0;
  3231. } else if (list->nbItems -1 == idx) {
  3232. list->nbItems--;
  3233. } else {
  3234. for (i = idx; i < list->nbItems -1; i++)
  3235. list->items[i] = list->items[i+1];
  3236. list->nbItems--;
  3237. }
  3238. return(0);
  3239. }
  3240. /**
  3241. * xmlSchemaItemListFree:
  3242. * @annot: a schema type structure
  3243. *
  3244. * Deallocate a annotation structure
  3245. */
  3246. static void
  3247. xmlSchemaItemListFree(xmlSchemaItemListPtr list)
  3248. {
  3249. if (list == NULL)
  3250. return;
  3251. if (list->items != NULL)
  3252. xmlFree(list->items);
  3253. xmlFree(list);
  3254. }
  3255. static void
  3256. xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
  3257. {
  3258. if (bucket == NULL)
  3259. return;
  3260. if (bucket->globals != NULL) {
  3261. xmlSchemaComponentListFree(bucket->globals);
  3262. xmlSchemaItemListFree(bucket->globals);
  3263. }
  3264. if (bucket->locals != NULL) {
  3265. xmlSchemaComponentListFree(bucket->locals);
  3266. xmlSchemaItemListFree(bucket->locals);
  3267. }
  3268. if (bucket->relations != NULL) {
  3269. xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
  3270. do {
  3271. prev = cur;
  3272. cur = cur->next;
  3273. xmlFree(prev);
  3274. } while (cur != NULL);
  3275. }
  3276. if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
  3277. xmlFreeDoc(bucket->doc);
  3278. }
  3279. if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
  3280. if (WXS_IMPBUCKET(bucket)->schema != NULL)
  3281. xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
  3282. }
  3283. xmlFree(bucket);
  3284. }
  3285. static void
  3286. xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
  3287. {
  3288. xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
  3289. }
  3290. static xmlSchemaBucketPtr
  3291. xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
  3292. int type, const xmlChar *targetNamespace)
  3293. {
  3294. xmlSchemaBucketPtr ret;
  3295. int size;
  3296. xmlSchemaPtr mainSchema;
  3297. if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
  3298. PERROR_INT("xmlSchemaBucketCreate",
  3299. "no main schema on constructor");
  3300. return(NULL);
  3301. }
  3302. mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
  3303. /* Create the schema bucket. */
  3304. if (WXS_IS_BUCKET_INCREDEF(type))
  3305. size = sizeof(xmlSchemaInclude);
  3306. else
  3307. size = sizeof(xmlSchemaImport);
  3308. ret = (xmlSchemaBucketPtr) xmlMalloc(size);
  3309. if (ret == NULL) {
  3310. xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
  3311. return(NULL);
  3312. }
  3313. memset(ret, 0, size);
  3314. ret->targetNamespace = targetNamespace;
  3315. ret->type = type;
  3316. ret->globals = xmlSchemaItemListCreate();
  3317. if (ret->globals == NULL) {
  3318. xmlFree(ret);
  3319. return(NULL);
  3320. }
  3321. ret->locals = xmlSchemaItemListCreate();
  3322. if (ret->locals == NULL) {
  3323. xmlFree(ret);
  3324. return(NULL);
  3325. }
  3326. /*
  3327. * The following will assure that only the first bucket is marked as
  3328. * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
  3329. * For each following import buckets an xmlSchema will be created.
  3330. * An xmlSchema will be created for every distinct targetNamespace.
  3331. * We assign the targetNamespace to the schemata here.
  3332. */
  3333. if (! WXS_HAS_BUCKETS(pctxt)) {
  3334. if (WXS_IS_BUCKET_INCREDEF(type)) {
  3335. PERROR_INT("xmlSchemaBucketCreate",
  3336. "first bucket but it's an include or redefine");
  3337. xmlSchemaBucketFree(ret);
  3338. return(NULL);
  3339. }
  3340. /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
  3341. ret->type = XML_SCHEMA_SCHEMA_MAIN;
  3342. /* Point to the *main* schema. */
  3343. WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
  3344. WXS_IMPBUCKET(ret)->schema = mainSchema;
  3345. /*
  3346. * Ensure that the main schema gets a targetNamespace.
  3347. */
  3348. mainSchema->targetNamespace = targetNamespace;
  3349. } else {
  3350. if (type == XML_SCHEMA_SCHEMA_MAIN) {
  3351. PERROR_INT("xmlSchemaBucketCreate",
  3352. "main bucket but it's not the first one");
  3353. xmlSchemaBucketFree(ret);
  3354. return(NULL);
  3355. } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
  3356. /*
  3357. * Create a schema for imports and assign the
  3358. * targetNamespace.
  3359. */
  3360. WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
  3361. if (WXS_IMPBUCKET(ret)->schema == NULL) {
  3362. xmlSchemaBucketFree(ret);
  3363. return(NULL);
  3364. }
  3365. WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
  3366. }
  3367. }
  3368. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  3369. int res;
  3370. /*
  3371. * Imports go into the "schemasImports" slot of the main *schema*.
  3372. * Note that we create an import entry for the main schema as well; i.e.,
  3373. * even if there's only one schema, we'll get an import.
  3374. */
  3375. if (mainSchema->schemasImports == NULL) {
  3376. mainSchema->schemasImports = xmlHashCreateDict(5,
  3377. WXS_CONSTRUCTOR(pctxt)->dict);
  3378. if (mainSchema->schemasImports == NULL) {
  3379. xmlSchemaBucketFree(ret);
  3380. return(NULL);
  3381. }
  3382. }
  3383. if (targetNamespace == NULL)
  3384. res = xmlHashAddEntry(mainSchema->schemasImports,
  3385. XML_SCHEMAS_NO_NAMESPACE, ret);
  3386. else
  3387. res = xmlHashAddEntry(mainSchema->schemasImports,
  3388. targetNamespace, ret);
  3389. if (res != 0) {
  3390. PERROR_INT("xmlSchemaBucketCreate",
  3391. "failed to add the schema bucket to the hash");
  3392. xmlSchemaBucketFree(ret);
  3393. return(NULL);
  3394. }
  3395. } else {
  3396. /* Set the @ownerImport of an include bucket. */
  3397. if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
  3398. WXS_INCBUCKET(ret)->ownerImport =
  3399. WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
  3400. else
  3401. WXS_INCBUCKET(ret)->ownerImport =
  3402. WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
  3403. /* Includes got into the "includes" slot of the *main* schema. */
  3404. if (mainSchema->includes == NULL) {
  3405. mainSchema->includes = xmlSchemaItemListCreate();
  3406. if (mainSchema->includes == NULL) {
  3407. xmlSchemaBucketFree(ret);
  3408. return(NULL);
  3409. }
  3410. }
  3411. xmlSchemaItemListAdd(mainSchema->includes, ret);
  3412. }
  3413. /*
  3414. * Add to list of all buckets; this is used for lookup
  3415. * during schema construction time only.
  3416. */
  3417. if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
  3418. return(NULL);
  3419. return(ret);
  3420. }
  3421. static int
  3422. xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
  3423. {
  3424. if (*list == NULL) {
  3425. *list = xmlSchemaItemListCreate();
  3426. if (*list == NULL)
  3427. return(-1);
  3428. }
  3429. xmlSchemaItemListAddSize(*list, initialSize, item);
  3430. return(0);
  3431. }
  3432. /**
  3433. * xmlSchemaFreeAnnot:
  3434. * @annot: a schema type structure
  3435. *
  3436. * Deallocate a annotation structure
  3437. */
  3438. static void
  3439. xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
  3440. {
  3441. if (annot == NULL)
  3442. return;
  3443. if (annot->next == NULL) {
  3444. xmlFree(annot);
  3445. } else {
  3446. xmlSchemaAnnotPtr prev;
  3447. do {
  3448. prev = annot;
  3449. annot = annot->next;
  3450. xmlFree(prev);
  3451. } while (annot != NULL);
  3452. }
  3453. }
  3454. /**
  3455. * xmlSchemaFreeNotation:
  3456. * @schema: a schema notation structure
  3457. *
  3458. * Deallocate a Schema Notation structure.
  3459. */
  3460. static void
  3461. xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
  3462. {
  3463. if (nota == NULL)
  3464. return;
  3465. xmlFree(nota);
  3466. }
  3467. /**
  3468. * xmlSchemaFreeAttribute:
  3469. * @attr: an attribute declaration
  3470. *
  3471. * Deallocates an attribute declaration structure.
  3472. */
  3473. static void
  3474. xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
  3475. {
  3476. if (attr == NULL)
  3477. return;
  3478. if (attr->annot != NULL)
  3479. xmlSchemaFreeAnnot(attr->annot);
  3480. if (attr->defVal != NULL)
  3481. xmlSchemaFreeValue(attr->defVal);
  3482. xmlFree(attr);
  3483. }
  3484. /**
  3485. * xmlSchemaFreeAttributeUse:
  3486. * @use: an attribute use
  3487. *
  3488. * Deallocates an attribute use structure.
  3489. */
  3490. static void
  3491. xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
  3492. {
  3493. if (use == NULL)
  3494. return;
  3495. if (use->annot != NULL)
  3496. xmlSchemaFreeAnnot(use->annot);
  3497. if (use->defVal != NULL)
  3498. xmlSchemaFreeValue(use->defVal);
  3499. xmlFree(use);
  3500. }
  3501. /**
  3502. * xmlSchemaFreeAttributeUseProhib:
  3503. * @prohib: an attribute use prohibition
  3504. *
  3505. * Deallocates an attribute use structure.
  3506. */
  3507. static void
  3508. xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
  3509. {
  3510. if (prohib == NULL)
  3511. return;
  3512. xmlFree(prohib);
  3513. }
  3514. /**
  3515. * xmlSchemaFreeWildcardNsSet:
  3516. * set: a schema wildcard namespace
  3517. *
  3518. * Deallocates a list of wildcard constraint structures.
  3519. */
  3520. static void
  3521. xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
  3522. {
  3523. xmlSchemaWildcardNsPtr next;
  3524. while (set != NULL) {
  3525. next = set->next;
  3526. xmlFree(set);
  3527. set = next;
  3528. }
  3529. }
  3530. /**
  3531. * xmlSchemaFreeWildcard:
  3532. * @wildcard: a wildcard structure
  3533. *
  3534. * Deallocates a wildcard structure.
  3535. */
  3536. void
  3537. xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
  3538. {
  3539. if (wildcard == NULL)
  3540. return;
  3541. if (wildcard->annot != NULL)
  3542. xmlSchemaFreeAnnot(wildcard->annot);
  3543. if (wildcard->nsSet != NULL)
  3544. xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
  3545. if (wildcard->negNsSet != NULL)
  3546. xmlFree(wildcard->negNsSet);
  3547. xmlFree(wildcard);
  3548. }
  3549. /**
  3550. * xmlSchemaFreeAttributeGroup:
  3551. * @schema: a schema attribute group structure
  3552. *
  3553. * Deallocate a Schema Attribute Group structure.
  3554. */
  3555. static void
  3556. xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
  3557. {
  3558. if (attrGr == NULL)
  3559. return;
  3560. if (attrGr->annot != NULL)
  3561. xmlSchemaFreeAnnot(attrGr->annot);
  3562. if (attrGr->attrUses != NULL)
  3563. xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
  3564. xmlFree(attrGr);
  3565. }
  3566. /**
  3567. * xmlSchemaFreeQNameRef:
  3568. * @item: a QName reference structure
  3569. *
  3570. * Deallocatea a QName reference structure.
  3571. */
  3572. static void
  3573. xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
  3574. {
  3575. xmlFree(item);
  3576. }
  3577. /**
  3578. * xmlSchemaFreeTypeLinkList:
  3579. * @alink: a type link
  3580. *
  3581. * Deallocate a list of types.
  3582. */
  3583. static void
  3584. xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
  3585. {
  3586. xmlSchemaTypeLinkPtr next;
  3587. while (link != NULL) {
  3588. next = link->next;
  3589. xmlFree(link);
  3590. link = next;
  3591. }
  3592. }
  3593. static void
  3594. xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
  3595. {
  3596. xmlSchemaIDCStateObjPtr next;
  3597. while (sto != NULL) {
  3598. next = sto->next;
  3599. if (sto->history != NULL)
  3600. xmlFree(sto->history);
  3601. if (sto->xpathCtxt != NULL)
  3602. xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
  3603. xmlFree(sto);
  3604. sto = next;
  3605. }
  3606. }
  3607. /**
  3608. * xmlSchemaFreeIDC:
  3609. * @idc: a identity-constraint definition
  3610. *
  3611. * Deallocates an identity-constraint definition.
  3612. */
  3613. static void
  3614. xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
  3615. {
  3616. xmlSchemaIDCSelectPtr cur, prev;
  3617. if (idcDef == NULL)
  3618. return;
  3619. if (idcDef->annot != NULL)
  3620. xmlSchemaFreeAnnot(idcDef->annot);
  3621. /* Selector */
  3622. if (idcDef->selector != NULL) {
  3623. if (idcDef->selector->xpathComp != NULL)
  3624. xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
  3625. xmlFree(idcDef->selector);
  3626. }
  3627. /* Fields */
  3628. if (idcDef->fields != NULL) {
  3629. cur = idcDef->fields;
  3630. do {
  3631. prev = cur;
  3632. cur = cur->next;
  3633. if (prev->xpathComp != NULL)
  3634. xmlFreePattern((xmlPatternPtr) prev->xpathComp);
  3635. xmlFree(prev);
  3636. } while (cur != NULL);
  3637. }
  3638. xmlFree(idcDef);
  3639. }
  3640. /**
  3641. * xmlSchemaFreeElement:
  3642. * @schema: a schema element structure
  3643. *
  3644. * Deallocate a Schema Element structure.
  3645. */
  3646. static void
  3647. xmlSchemaFreeElement(xmlSchemaElementPtr elem)
  3648. {
  3649. if (elem == NULL)
  3650. return;
  3651. if (elem->annot != NULL)
  3652. xmlSchemaFreeAnnot(elem->annot);
  3653. if (elem->contModel != NULL)
  3654. xmlRegFreeRegexp(elem->contModel);
  3655. if (elem->defVal != NULL)
  3656. xmlSchemaFreeValue(elem->defVal);
  3657. xmlFree(elem);
  3658. }
  3659. /**
  3660. * xmlSchemaFreeFacet:
  3661. * @facet: a schema facet structure
  3662. *
  3663. * Deallocate a Schema Facet structure.
  3664. */
  3665. void
  3666. xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
  3667. {
  3668. if (facet == NULL)
  3669. return;
  3670. if (facet->val != NULL)
  3671. xmlSchemaFreeValue(facet->val);
  3672. if (facet->regexp != NULL)
  3673. xmlRegFreeRegexp(facet->regexp);
  3674. if (facet->annot != NULL)
  3675. xmlSchemaFreeAnnot(facet->annot);
  3676. xmlFree(facet);
  3677. }
  3678. /**
  3679. * xmlSchemaFreeType:
  3680. * @type: a schema type structure
  3681. *
  3682. * Deallocate a Schema Type structure.
  3683. */
  3684. void
  3685. xmlSchemaFreeType(xmlSchemaTypePtr type)
  3686. {
  3687. if (type == NULL)
  3688. return;
  3689. if (type->annot != NULL)
  3690. xmlSchemaFreeAnnot(type->annot);
  3691. if (type->facets != NULL) {
  3692. xmlSchemaFacetPtr facet, next;
  3693. facet = type->facets;
  3694. while (facet != NULL) {
  3695. next = facet->next;
  3696. xmlSchemaFreeFacet(facet);
  3697. facet = next;
  3698. }
  3699. }
  3700. if (type->attrUses != NULL)
  3701. xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
  3702. if (type->memberTypes != NULL)
  3703. xmlSchemaFreeTypeLinkList(type->memberTypes);
  3704. if (type->facetSet != NULL) {
  3705. xmlSchemaFacetLinkPtr next, link;
  3706. link = type->facetSet;
  3707. do {
  3708. next = link->next;
  3709. xmlFree(link);
  3710. link = next;
  3711. } while (link != NULL);
  3712. }
  3713. if (type->contModel != NULL)
  3714. xmlRegFreeRegexp(type->contModel);
  3715. xmlFree(type);
  3716. }
  3717. /**
  3718. * xmlSchemaFreeModelGroupDef:
  3719. * @item: a schema model group definition
  3720. *
  3721. * Deallocates a schema model group definition.
  3722. */
  3723. static void
  3724. xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
  3725. {
  3726. if (item->annot != NULL)
  3727. xmlSchemaFreeAnnot(item->annot);
  3728. xmlFree(item);
  3729. }
  3730. /**
  3731. * xmlSchemaFreeModelGroup:
  3732. * @item: a schema model group
  3733. *
  3734. * Deallocates a schema model group structure.
  3735. */
  3736. static void
  3737. xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
  3738. {
  3739. if (item->annot != NULL)
  3740. xmlSchemaFreeAnnot(item->annot);
  3741. xmlFree(item);
  3742. }
  3743. static void
  3744. xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
  3745. {
  3746. if ((list == NULL) || (list->nbItems == 0))
  3747. return;
  3748. {
  3749. xmlSchemaTreeItemPtr item;
  3750. xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
  3751. int i;
  3752. for (i = 0; i < list->nbItems; i++) {
  3753. item = items[i];
  3754. if (item == NULL)
  3755. continue;
  3756. switch (item->type) {
  3757. case XML_SCHEMA_TYPE_SIMPLE:
  3758. case XML_SCHEMA_TYPE_COMPLEX:
  3759. xmlSchemaFreeType((xmlSchemaTypePtr) item);
  3760. break;
  3761. case XML_SCHEMA_TYPE_ATTRIBUTE:
  3762. xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
  3763. break;
  3764. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  3765. xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
  3766. break;
  3767. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  3768. xmlSchemaFreeAttributeUseProhib(
  3769. (xmlSchemaAttributeUseProhibPtr) item);
  3770. break;
  3771. case XML_SCHEMA_TYPE_ELEMENT:
  3772. xmlSchemaFreeElement((xmlSchemaElementPtr) item);
  3773. break;
  3774. case XML_SCHEMA_TYPE_PARTICLE:
  3775. if (item->annot != NULL)
  3776. xmlSchemaFreeAnnot(item->annot);
  3777. xmlFree(item);
  3778. break;
  3779. case XML_SCHEMA_TYPE_SEQUENCE:
  3780. case XML_SCHEMA_TYPE_CHOICE:
  3781. case XML_SCHEMA_TYPE_ALL:
  3782. xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
  3783. break;
  3784. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  3785. xmlSchemaFreeAttributeGroup(
  3786. (xmlSchemaAttributeGroupPtr) item);
  3787. break;
  3788. case XML_SCHEMA_TYPE_GROUP:
  3789. xmlSchemaFreeModelGroupDef(
  3790. (xmlSchemaModelGroupDefPtr) item);
  3791. break;
  3792. case XML_SCHEMA_TYPE_ANY:
  3793. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  3794. xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
  3795. break;
  3796. case XML_SCHEMA_TYPE_IDC_KEY:
  3797. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  3798. case XML_SCHEMA_TYPE_IDC_KEYREF:
  3799. xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
  3800. break;
  3801. case XML_SCHEMA_TYPE_NOTATION:
  3802. xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
  3803. break;
  3804. case XML_SCHEMA_EXTRA_QNAMEREF:
  3805. xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
  3806. break;
  3807. default: {
  3808. /* TODO: This should never be hit. */
  3809. xmlSchemaPSimpleInternalErr(NULL,
  3810. "Internal error: xmlSchemaComponentListFree, "
  3811. "unexpected component type '%s'\n",
  3812. (const xmlChar *) WXS_ITEM_TYPE_NAME(item));
  3813. }
  3814. break;
  3815. }
  3816. }
  3817. list->nbItems = 0;
  3818. }
  3819. }
  3820. /**
  3821. * xmlSchemaFree:
  3822. * @schema: a schema structure
  3823. *
  3824. * Deallocate a Schema structure.
  3825. */
  3826. void
  3827. xmlSchemaFree(xmlSchemaPtr schema)
  3828. {
  3829. if (schema == NULL)
  3830. return;
  3831. /* @volatiles is not used anymore :-/ */
  3832. if (schema->volatiles != NULL)
  3833. TODO
  3834. /*
  3835. * Note that those slots are not responsible for freeing
  3836. * schema components anymore; this will now be done by
  3837. * the schema buckets.
  3838. */
  3839. if (schema->notaDecl != NULL)
  3840. xmlHashFree(schema->notaDecl, NULL);
  3841. if (schema->attrDecl != NULL)
  3842. xmlHashFree(schema->attrDecl, NULL);
  3843. if (schema->attrgrpDecl != NULL)
  3844. xmlHashFree(schema->attrgrpDecl, NULL);
  3845. if (schema->elemDecl != NULL)
  3846. xmlHashFree(schema->elemDecl, NULL);
  3847. if (schema->typeDecl != NULL)
  3848. xmlHashFree(schema->typeDecl, NULL);
  3849. if (schema->groupDecl != NULL)
  3850. xmlHashFree(schema->groupDecl, NULL);
  3851. if (schema->idcDef != NULL)
  3852. xmlHashFree(schema->idcDef, NULL);
  3853. if (schema->schemasImports != NULL)
  3854. xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
  3855. if (schema->includes != NULL) {
  3856. xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
  3857. int i;
  3858. for (i = 0; i < list->nbItems; i++) {
  3859. xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
  3860. }
  3861. xmlSchemaItemListFree(list);
  3862. }
  3863. if (schema->annot != NULL)
  3864. xmlSchemaFreeAnnot(schema->annot);
  3865. /* Never free the doc here, since this will be done by the buckets. */
  3866. xmlDictFree(schema->dict);
  3867. xmlFree(schema);
  3868. }
  3869. /************************************************************************
  3870. * *
  3871. * Debug functions *
  3872. * *
  3873. ************************************************************************/
  3874. #ifdef LIBXML_OUTPUT_ENABLED
  3875. static void
  3876. xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
  3877. /**
  3878. * xmlSchemaElementDump:
  3879. * @elem: an element
  3880. * @output: the file output
  3881. *
  3882. * Dump the element
  3883. */
  3884. static void
  3885. xmlSchemaElementDump(void *payload, void *data,
  3886. const xmlChar * name ATTRIBUTE_UNUSED,
  3887. const xmlChar * namespace ATTRIBUTE_UNUSED,
  3888. const xmlChar * context ATTRIBUTE_UNUSED)
  3889. {
  3890. xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
  3891. FILE *output = (FILE *) data;
  3892. if (elem == NULL)
  3893. return;
  3894. fprintf(output, "Element");
  3895. if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
  3896. fprintf(output, " (global)");
  3897. fprintf(output, ": '%s' ", elem->name);
  3898. if (namespace != NULL)
  3899. fprintf(output, "ns '%s'", namespace);
  3900. fprintf(output, "\n");
  3901. #if 0
  3902. if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
  3903. fprintf(output, " min %d ", elem->minOccurs);
  3904. if (elem->maxOccurs >= UNBOUNDED)
  3905. fprintf(output, "max: unbounded\n");
  3906. else if (elem->maxOccurs != 1)
  3907. fprintf(output, "max: %d\n", elem->maxOccurs);
  3908. else
  3909. fprintf(output, "\n");
  3910. }
  3911. #endif
  3912. /*
  3913. * Misc other properties.
  3914. */
  3915. if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
  3916. (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
  3917. (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
  3918. (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
  3919. fprintf(output, " props: ");
  3920. if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
  3921. fprintf(output, "[fixed] ");
  3922. if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
  3923. fprintf(output, "[default] ");
  3924. if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
  3925. fprintf(output, "[abstract] ");
  3926. if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
  3927. fprintf(output, "[nillable] ");
  3928. fprintf(output, "\n");
  3929. }
  3930. /*
  3931. * Default/fixed value.
  3932. */
  3933. if (elem->value != NULL)
  3934. fprintf(output, " value: '%s'\n", elem->value);
  3935. /*
  3936. * Type.
  3937. */
  3938. if (elem->namedType != NULL) {
  3939. fprintf(output, " type: '%s' ", elem->namedType);
  3940. if (elem->namedTypeNs != NULL)
  3941. fprintf(output, "ns '%s'\n", elem->namedTypeNs);
  3942. else
  3943. fprintf(output, "\n");
  3944. } else if (elem->subtypes != NULL) {
  3945. /*
  3946. * Dump local types.
  3947. */
  3948. xmlSchemaTypeDump(elem->subtypes, output);
  3949. }
  3950. /*
  3951. * Substitution group.
  3952. */
  3953. if (elem->substGroup != NULL) {
  3954. fprintf(output, " substitutionGroup: '%s' ", elem->substGroup);
  3955. if (elem->substGroupNs != NULL)
  3956. fprintf(output, "ns '%s'\n", elem->substGroupNs);
  3957. else
  3958. fprintf(output, "\n");
  3959. }
  3960. }
  3961. /**
  3962. * xmlSchemaAnnotDump:
  3963. * @output: the file output
  3964. * @annot: a annotation
  3965. *
  3966. * Dump the annotation
  3967. */
  3968. static void
  3969. xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
  3970. {
  3971. xmlChar *content;
  3972. if (annot == NULL)
  3973. return;
  3974. content = xmlNodeGetContent(annot->content);
  3975. if (content != NULL) {
  3976. fprintf(output, " Annot: %s\n", content);
  3977. xmlFree(content);
  3978. } else
  3979. fprintf(output, " Annot: empty\n");
  3980. }
  3981. /**
  3982. * xmlSchemaContentModelDump:
  3983. * @particle: the schema particle
  3984. * @output: the file output
  3985. * @depth: the depth used for indentation
  3986. *
  3987. * Dump a SchemaType structure
  3988. */
  3989. static void
  3990. xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
  3991. {
  3992. xmlChar *str = NULL;
  3993. xmlSchemaTreeItemPtr term;
  3994. char shift[100];
  3995. int i;
  3996. if (particle == NULL)
  3997. return;
  3998. for (i = 0;((i < depth) && (i < 25));i++)
  3999. shift[2 * i] = shift[2 * i + 1] = ' ';
  4000. shift[2 * i] = shift[2 * i + 1] = 0;
  4001. fprintf(output, "%s", shift);
  4002. if (particle->children == NULL) {
  4003. fprintf(output, "MISSING particle term\n");
  4004. return;
  4005. }
  4006. term = particle->children;
  4007. if (term == NULL) {
  4008. fprintf(output, "(NULL)");
  4009. } else {
  4010. switch (term->type) {
  4011. case XML_SCHEMA_TYPE_ELEMENT:
  4012. fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
  4013. ((xmlSchemaElementPtr)term)->targetNamespace,
  4014. ((xmlSchemaElementPtr)term)->name));
  4015. FREE_AND_NULL(str);
  4016. break;
  4017. case XML_SCHEMA_TYPE_SEQUENCE:
  4018. fprintf(output, "SEQUENCE");
  4019. break;
  4020. case XML_SCHEMA_TYPE_CHOICE:
  4021. fprintf(output, "CHOICE");
  4022. break;
  4023. case XML_SCHEMA_TYPE_ALL:
  4024. fprintf(output, "ALL");
  4025. break;
  4026. case XML_SCHEMA_TYPE_ANY:
  4027. fprintf(output, "ANY");
  4028. break;
  4029. default:
  4030. fprintf(output, "UNKNOWN\n");
  4031. return;
  4032. }
  4033. }
  4034. if (particle->minOccurs != 1)
  4035. fprintf(output, " min: %d", particle->minOccurs);
  4036. if (particle->maxOccurs >= UNBOUNDED)
  4037. fprintf(output, " max: unbounded");
  4038. else if (particle->maxOccurs != 1)
  4039. fprintf(output, " max: %d", particle->maxOccurs);
  4040. fprintf(output, "\n");
  4041. if (term &&
  4042. ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
  4043. (term->type == XML_SCHEMA_TYPE_CHOICE) ||
  4044. (term->type == XML_SCHEMA_TYPE_ALL)) &&
  4045. (term->children != NULL)) {
  4046. xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
  4047. output, depth +1);
  4048. }
  4049. if (particle->next != NULL)
  4050. xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
  4051. output, depth);
  4052. }
  4053. /**
  4054. * xmlSchemaAttrUsesDump:
  4055. * @uses: attribute uses list
  4056. * @output: the file output
  4057. *
  4058. * Dumps a list of attribute use components.
  4059. */
  4060. static void
  4061. xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
  4062. {
  4063. xmlSchemaAttributeUsePtr use;
  4064. xmlSchemaAttributeUseProhibPtr prohib;
  4065. xmlSchemaQNameRefPtr ref;
  4066. const xmlChar *name, *tns;
  4067. xmlChar *str = NULL;
  4068. int i;
  4069. if ((uses == NULL) || (uses->nbItems == 0))
  4070. return;
  4071. fprintf(output, " attributes:\n");
  4072. for (i = 0; i < uses->nbItems; i++) {
  4073. use = uses->items[i];
  4074. if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
  4075. fprintf(output, " [prohibition] ");
  4076. prohib = (xmlSchemaAttributeUseProhibPtr) use;
  4077. name = prohib->name;
  4078. tns = prohib->targetNamespace;
  4079. } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
  4080. fprintf(output, " [reference] ");
  4081. ref = (xmlSchemaQNameRefPtr) use;
  4082. name = ref->name;
  4083. tns = ref->targetNamespace;
  4084. } else {
  4085. fprintf(output, " [use] ");
  4086. name = WXS_ATTRUSE_DECL_NAME(use);
  4087. tns = WXS_ATTRUSE_DECL_TNS(use);
  4088. }
  4089. fprintf(output, "'%s'\n",
  4090. (const char *) xmlSchemaFormatQName(&str, tns, name));
  4091. FREE_AND_NULL(str);
  4092. }
  4093. }
  4094. /**
  4095. * xmlSchemaTypeDump:
  4096. * @output: the file output
  4097. * @type: a type structure
  4098. *
  4099. * Dump a SchemaType structure
  4100. */
  4101. static void
  4102. xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
  4103. {
  4104. if (type == NULL) {
  4105. fprintf(output, "Type: NULL\n");
  4106. return;
  4107. }
  4108. fprintf(output, "Type: ");
  4109. if (type->name != NULL)
  4110. fprintf(output, "'%s' ", type->name);
  4111. else
  4112. fprintf(output, "(no name) ");
  4113. if (type->targetNamespace != NULL)
  4114. fprintf(output, "ns '%s' ", type->targetNamespace);
  4115. switch (type->type) {
  4116. case XML_SCHEMA_TYPE_BASIC:
  4117. fprintf(output, "[basic] ");
  4118. break;
  4119. case XML_SCHEMA_TYPE_SIMPLE:
  4120. fprintf(output, "[simple] ");
  4121. break;
  4122. case XML_SCHEMA_TYPE_COMPLEX:
  4123. fprintf(output, "[complex] ");
  4124. break;
  4125. case XML_SCHEMA_TYPE_SEQUENCE:
  4126. fprintf(output, "[sequence] ");
  4127. break;
  4128. case XML_SCHEMA_TYPE_CHOICE:
  4129. fprintf(output, "[choice] ");
  4130. break;
  4131. case XML_SCHEMA_TYPE_ALL:
  4132. fprintf(output, "[all] ");
  4133. break;
  4134. case XML_SCHEMA_TYPE_UR:
  4135. fprintf(output, "[ur] ");
  4136. break;
  4137. case XML_SCHEMA_TYPE_RESTRICTION:
  4138. fprintf(output, "[restriction] ");
  4139. break;
  4140. case XML_SCHEMA_TYPE_EXTENSION:
  4141. fprintf(output, "[extension] ");
  4142. break;
  4143. default:
  4144. fprintf(output, "[unknown type %d] ", type->type);
  4145. break;
  4146. }
  4147. fprintf(output, "content: ");
  4148. switch (type->contentType) {
  4149. case XML_SCHEMA_CONTENT_UNKNOWN:
  4150. fprintf(output, "[unknown] ");
  4151. break;
  4152. case XML_SCHEMA_CONTENT_EMPTY:
  4153. fprintf(output, "[empty] ");
  4154. break;
  4155. case XML_SCHEMA_CONTENT_ELEMENTS:
  4156. fprintf(output, "[element] ");
  4157. break;
  4158. case XML_SCHEMA_CONTENT_MIXED:
  4159. fprintf(output, "[mixed] ");
  4160. break;
  4161. case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
  4162. /* not used. */
  4163. break;
  4164. case XML_SCHEMA_CONTENT_BASIC:
  4165. fprintf(output, "[basic] ");
  4166. break;
  4167. case XML_SCHEMA_CONTENT_SIMPLE:
  4168. fprintf(output, "[simple] ");
  4169. break;
  4170. case XML_SCHEMA_CONTENT_ANY:
  4171. fprintf(output, "[any] ");
  4172. break;
  4173. }
  4174. fprintf(output, "\n");
  4175. if (type->base != NULL) {
  4176. fprintf(output, " base type: '%s'", type->base);
  4177. if (type->baseNs != NULL)
  4178. fprintf(output, " ns '%s'\n", type->baseNs);
  4179. else
  4180. fprintf(output, "\n");
  4181. }
  4182. if (type->attrUses != NULL)
  4183. xmlSchemaAttrUsesDump(type->attrUses, output);
  4184. if (type->annot != NULL)
  4185. xmlSchemaAnnotDump(output, type->annot);
  4186. #ifdef DUMP_CONTENT_MODEL
  4187. if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
  4188. (type->subtypes != NULL)) {
  4189. xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
  4190. output, 1);
  4191. }
  4192. #endif
  4193. }
  4194. static void
  4195. xmlSchemaTypeDumpEntry(void *type, void *output,
  4196. const xmlChar *name ATTRIBUTE_UNUSED)
  4197. {
  4198. xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
  4199. }
  4200. /**
  4201. * xmlSchemaDump:
  4202. * @output: the file output
  4203. * @schema: a schema structure
  4204. *
  4205. * Dump a Schema structure.
  4206. */
  4207. void
  4208. xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
  4209. {
  4210. if (output == NULL)
  4211. return;
  4212. if (schema == NULL) {
  4213. fprintf(output, "Schemas: NULL\n");
  4214. return;
  4215. }
  4216. fprintf(output, "Schemas: ");
  4217. if (schema->name != NULL)
  4218. fprintf(output, "%s, ", schema->name);
  4219. else
  4220. fprintf(output, "no name, ");
  4221. if (schema->targetNamespace != NULL)
  4222. fprintf(output, "%s", (const char *) schema->targetNamespace);
  4223. else
  4224. fprintf(output, "no target namespace");
  4225. fprintf(output, "\n");
  4226. if (schema->annot != NULL)
  4227. xmlSchemaAnnotDump(output, schema->annot);
  4228. xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
  4229. xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
  4230. }
  4231. #ifdef DEBUG_IDC_NODE_TABLE
  4232. /**
  4233. * xmlSchemaDebugDumpIDCTable:
  4234. * @vctxt: the WXS validation context
  4235. *
  4236. * Displays the current IDC table for debug purposes.
  4237. */
  4238. static void
  4239. xmlSchemaDebugDumpIDCTable(FILE * output,
  4240. const xmlChar *namespaceName,
  4241. const xmlChar *localName,
  4242. xmlSchemaPSVIIDCBindingPtr bind)
  4243. {
  4244. xmlChar *str = NULL;
  4245. const xmlChar *value;
  4246. xmlSchemaPSVIIDCNodePtr tab;
  4247. xmlSchemaPSVIIDCKeyPtr key;
  4248. int i, j, res;
  4249. fprintf(output, "IDC: TABLES on '%s'\n",
  4250. xmlSchemaFormatQName(&str, namespaceName, localName));
  4251. FREE_AND_NULL(str)
  4252. if (bind == NULL)
  4253. return;
  4254. do {
  4255. fprintf(output, "IDC: BINDING '%s' (%d)\n",
  4256. xmlSchemaGetComponentQName(&str,
  4257. bind->definition), bind->nbNodes);
  4258. FREE_AND_NULL(str)
  4259. for (i = 0; i < bind->nbNodes; i++) {
  4260. tab = bind->nodeTable[i];
  4261. fprintf(output, " ( ");
  4262. for (j = 0; j < bind->definition->nbFields; j++) {
  4263. key = tab->keys[j];
  4264. if ((key != NULL) && (key->val != NULL)) {
  4265. res = xmlSchemaGetCanonValue(key->val, &value);
  4266. if (res >= 0)
  4267. fprintf(output, "'%s' ", value);
  4268. else
  4269. fprintf(output, "CANON-VALUE-FAILED ");
  4270. if (res == 0)
  4271. FREE_AND_NULL(value)
  4272. } else if (key != NULL)
  4273. fprintf(output, "(no val), ");
  4274. else
  4275. fprintf(output, "(key missing), ");
  4276. }
  4277. fprintf(output, ")\n");
  4278. }
  4279. if (bind->dupls && bind->dupls->nbItems) {
  4280. fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems);
  4281. for (i = 0; i < bind->dupls->nbItems; i++) {
  4282. tab = bind->dupls->items[i];
  4283. fprintf(output, " ( ");
  4284. for (j = 0; j < bind->definition->nbFields; j++) {
  4285. key = tab->keys[j];
  4286. if ((key != NULL) && (key->val != NULL)) {
  4287. res = xmlSchemaGetCanonValue(key->val, &value);
  4288. if (res >= 0)
  4289. fprintf(output, "'%s' ", value);
  4290. else
  4291. fprintf(output, "CANON-VALUE-FAILED ");
  4292. if (res == 0)
  4293. FREE_AND_NULL(value)
  4294. } else if (key != NULL)
  4295. fprintf(output, "(no val), ");
  4296. else
  4297. fprintf(output, "(key missing), ");
  4298. }
  4299. fprintf(output, ")\n");
  4300. }
  4301. }
  4302. bind = bind->next;
  4303. } while (bind != NULL);
  4304. }
  4305. #endif /* DEBUG_IDC */
  4306. #endif /* LIBXML_OUTPUT_ENABLED */
  4307. /************************************************************************
  4308. * *
  4309. * Utilities *
  4310. * *
  4311. ************************************************************************/
  4312. /**
  4313. * xmlSchemaGetPropNode:
  4314. * @node: the element node
  4315. * @name: the name of the attribute
  4316. *
  4317. * Seeks an attribute with a name of @name in
  4318. * no namespace.
  4319. *
  4320. * Returns the attribute or NULL if not present.
  4321. */
  4322. static xmlAttrPtr
  4323. xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
  4324. {
  4325. xmlAttrPtr prop;
  4326. if ((node == NULL) || (name == NULL))
  4327. return(NULL);
  4328. prop = node->properties;
  4329. while (prop != NULL) {
  4330. if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
  4331. return(prop);
  4332. prop = prop->next;
  4333. }
  4334. return (NULL);
  4335. }
  4336. /**
  4337. * xmlSchemaGetPropNodeNs:
  4338. * @node: the element node
  4339. * @uri: the uri
  4340. * @name: the name of the attribute
  4341. *
  4342. * Seeks an attribute with a local name of @name and
  4343. * a namespace URI of @uri.
  4344. *
  4345. * Returns the attribute or NULL if not present.
  4346. */
  4347. static xmlAttrPtr
  4348. xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
  4349. {
  4350. xmlAttrPtr prop;
  4351. if ((node == NULL) || (name == NULL))
  4352. return(NULL);
  4353. prop = node->properties;
  4354. while (prop != NULL) {
  4355. if ((prop->ns != NULL) &&
  4356. xmlStrEqual(prop->name, BAD_CAST name) &&
  4357. xmlStrEqual(prop->ns->href, BAD_CAST uri))
  4358. return(prop);
  4359. prop = prop->next;
  4360. }
  4361. return (NULL);
  4362. }
  4363. static const xmlChar *
  4364. xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
  4365. {
  4366. xmlChar *val;
  4367. const xmlChar *ret;
  4368. val = xmlNodeGetContent(node);
  4369. if (val == NULL)
  4370. val = xmlStrdup((xmlChar *)"");
  4371. ret = xmlDictLookup(ctxt->dict, val, -1);
  4372. xmlFree(val);
  4373. return(ret);
  4374. }
  4375. static const xmlChar *
  4376. xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
  4377. {
  4378. return((const xmlChar*) xmlNodeGetContent(node));
  4379. }
  4380. /**
  4381. * xmlSchemaGetProp:
  4382. * @ctxt: the parser context
  4383. * @node: the node
  4384. * @name: the property name
  4385. *
  4386. * Read a attribute value and internalize the string
  4387. *
  4388. * Returns the string or NULL if not present.
  4389. */
  4390. static const xmlChar *
  4391. xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  4392. const char *name)
  4393. {
  4394. xmlChar *val;
  4395. const xmlChar *ret;
  4396. val = xmlGetNoNsProp(node, BAD_CAST name);
  4397. if (val == NULL)
  4398. return(NULL);
  4399. ret = xmlDictLookup(ctxt->dict, val, -1);
  4400. xmlFree(val);
  4401. return(ret);
  4402. }
  4403. /************************************************************************
  4404. * *
  4405. * Parsing functions *
  4406. * *
  4407. ************************************************************************/
  4408. #define WXS_FIND_GLOBAL_ITEM(slot) \
  4409. if (xmlStrEqual(nsName, schema->targetNamespace)) { \
  4410. ret = xmlHashLookup(schema->slot, name); \
  4411. if (ret != NULL) goto exit; \
  4412. } \
  4413. if (xmlHashSize(schema->schemasImports) > 1) { \
  4414. xmlSchemaImportPtr import; \
  4415. if (nsName == NULL) \
  4416. import = xmlHashLookup(schema->schemasImports, \
  4417. XML_SCHEMAS_NO_NAMESPACE); \
  4418. else \
  4419. import = xmlHashLookup(schema->schemasImports, nsName); \
  4420. if (import == NULL) \
  4421. goto exit; \
  4422. ret = xmlHashLookup(import->schema->slot, name); \
  4423. }
  4424. /**
  4425. * xmlSchemaGetElem:
  4426. * @schema: the schema context
  4427. * @name: the element name
  4428. * @ns: the element namespace
  4429. *
  4430. * Lookup a global element declaration in the schema.
  4431. *
  4432. * Returns the element declaration or NULL if not found.
  4433. */
  4434. static xmlSchemaElementPtr
  4435. xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
  4436. const xmlChar * nsName)
  4437. {
  4438. xmlSchemaElementPtr ret = NULL;
  4439. if ((name == NULL) || (schema == NULL))
  4440. return(NULL);
  4441. if (schema != NULL) {
  4442. WXS_FIND_GLOBAL_ITEM(elemDecl)
  4443. }
  4444. exit:
  4445. #ifdef DEBUG
  4446. if (ret == NULL) {
  4447. if (nsName == NULL)
  4448. fprintf(stderr, "Unable to lookup element decl. %s", name);
  4449. else
  4450. fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
  4451. nsName);
  4452. }
  4453. #endif
  4454. return (ret);
  4455. }
  4456. /**
  4457. * xmlSchemaGetType:
  4458. * @schema: the main schema
  4459. * @name: the type's name
  4460. * nsName: the type's namespace
  4461. *
  4462. * Lookup a type in the schemas or the predefined types
  4463. *
  4464. * Returns the group definition or NULL if not found.
  4465. */
  4466. static xmlSchemaTypePtr
  4467. xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
  4468. const xmlChar * nsName)
  4469. {
  4470. xmlSchemaTypePtr ret = NULL;
  4471. if (name == NULL)
  4472. return (NULL);
  4473. /* First try the built-in types. */
  4474. if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
  4475. ret = xmlSchemaGetPredefinedType(name, nsName);
  4476. if (ret != NULL)
  4477. goto exit;
  4478. /*
  4479. * Note that we try the parsed schemas as well here
  4480. * since one might have parsed the S4S, which contain more
  4481. * than the built-in types.
  4482. * TODO: Can we optimize this?
  4483. */
  4484. }
  4485. if (schema != NULL) {
  4486. WXS_FIND_GLOBAL_ITEM(typeDecl)
  4487. }
  4488. exit:
  4489. #ifdef DEBUG
  4490. if (ret == NULL) {
  4491. if (nsName == NULL)
  4492. fprintf(stderr, "Unable to lookup type %s", name);
  4493. else
  4494. fprintf(stderr, "Unable to lookup type %s:%s", name,
  4495. nsName);
  4496. }
  4497. #endif
  4498. return (ret);
  4499. }
  4500. /**
  4501. * xmlSchemaGetAttributeDecl:
  4502. * @schema: the context of the schema
  4503. * @name: the name of the attribute
  4504. * @ns: the target namespace of the attribute
  4505. *
  4506. * Lookup a an attribute in the schema or imported schemas
  4507. *
  4508. * Returns the attribute declaration or NULL if not found.
  4509. */
  4510. static xmlSchemaAttributePtr
  4511. xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
  4512. const xmlChar * nsName)
  4513. {
  4514. xmlSchemaAttributePtr ret = NULL;
  4515. if ((name == NULL) || (schema == NULL))
  4516. return (NULL);
  4517. if (schema != NULL) {
  4518. WXS_FIND_GLOBAL_ITEM(attrDecl)
  4519. }
  4520. exit:
  4521. #ifdef DEBUG
  4522. if (ret == NULL) {
  4523. if (nsName == NULL)
  4524. fprintf(stderr, "Unable to lookup attribute %s", name);
  4525. else
  4526. fprintf(stderr, "Unable to lookup attribute %s:%s", name,
  4527. nsName);
  4528. }
  4529. #endif
  4530. return (ret);
  4531. }
  4532. /**
  4533. * xmlSchemaGetAttributeGroup:
  4534. * @schema: the context of the schema
  4535. * @name: the name of the attribute group
  4536. * @ns: the target namespace of the attribute group
  4537. *
  4538. * Lookup a an attribute group in the schema or imported schemas
  4539. *
  4540. * Returns the attribute group definition or NULL if not found.
  4541. */
  4542. static xmlSchemaAttributeGroupPtr
  4543. xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
  4544. const xmlChar * nsName)
  4545. {
  4546. xmlSchemaAttributeGroupPtr ret = NULL;
  4547. if ((name == NULL) || (schema == NULL))
  4548. return (NULL);
  4549. if (schema != NULL) {
  4550. WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
  4551. }
  4552. exit:
  4553. /* TODO:
  4554. if ((ret != NULL) && (ret->redef != NULL)) {
  4555. * Return the last redefinition. *
  4556. ret = ret->redef;
  4557. }
  4558. */
  4559. #ifdef DEBUG
  4560. if (ret == NULL) {
  4561. if (nsName == NULL)
  4562. fprintf(stderr, "Unable to lookup attribute group %s", name);
  4563. else
  4564. fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
  4565. nsName);
  4566. }
  4567. #endif
  4568. return (ret);
  4569. }
  4570. /**
  4571. * xmlSchemaGetGroup:
  4572. * @schema: the context of the schema
  4573. * @name: the name of the group
  4574. * @ns: the target namespace of the group
  4575. *
  4576. * Lookup a group in the schema or imported schemas
  4577. *
  4578. * Returns the group definition or NULL if not found.
  4579. */
  4580. static xmlSchemaModelGroupDefPtr
  4581. xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
  4582. const xmlChar * nsName)
  4583. {
  4584. xmlSchemaModelGroupDefPtr ret = NULL;
  4585. if ((name == NULL) || (schema == NULL))
  4586. return (NULL);
  4587. if (schema != NULL) {
  4588. WXS_FIND_GLOBAL_ITEM(groupDecl)
  4589. }
  4590. exit:
  4591. #ifdef DEBUG
  4592. if (ret == NULL) {
  4593. if (nsName == NULL)
  4594. fprintf(stderr, "Unable to lookup group %s", name);
  4595. else
  4596. fprintf(stderr, "Unable to lookup group %s:%s", name,
  4597. nsName);
  4598. }
  4599. #endif
  4600. return (ret);
  4601. }
  4602. static xmlSchemaNotationPtr
  4603. xmlSchemaGetNotation(xmlSchemaPtr schema,
  4604. const xmlChar *name,
  4605. const xmlChar *nsName)
  4606. {
  4607. xmlSchemaNotationPtr ret = NULL;
  4608. if ((name == NULL) || (schema == NULL))
  4609. return (NULL);
  4610. if (schema != NULL) {
  4611. WXS_FIND_GLOBAL_ITEM(notaDecl)
  4612. }
  4613. exit:
  4614. return (ret);
  4615. }
  4616. static xmlSchemaIDCPtr
  4617. xmlSchemaGetIDC(xmlSchemaPtr schema,
  4618. const xmlChar *name,
  4619. const xmlChar *nsName)
  4620. {
  4621. xmlSchemaIDCPtr ret = NULL;
  4622. if ((name == NULL) || (schema == NULL))
  4623. return (NULL);
  4624. if (schema != NULL) {
  4625. WXS_FIND_GLOBAL_ITEM(idcDef)
  4626. }
  4627. exit:
  4628. return (ret);
  4629. }
  4630. /**
  4631. * xmlSchemaGetNamedComponent:
  4632. * @schema: the schema
  4633. * @name: the name of the group
  4634. * @ns: the target namespace of the group
  4635. *
  4636. * Lookup a group in the schema or imported schemas
  4637. *
  4638. * Returns the group definition or NULL if not found.
  4639. */
  4640. static xmlSchemaBasicItemPtr
  4641. xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
  4642. xmlSchemaTypeType itemType,
  4643. const xmlChar *name,
  4644. const xmlChar *targetNs)
  4645. {
  4646. switch (itemType) {
  4647. case XML_SCHEMA_TYPE_GROUP:
  4648. return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
  4649. name, targetNs));
  4650. case XML_SCHEMA_TYPE_ELEMENT:
  4651. return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
  4652. name, targetNs));
  4653. default:
  4654. TODO
  4655. return (NULL);
  4656. }
  4657. }
  4658. /************************************************************************
  4659. * *
  4660. * Parsing functions *
  4661. * *
  4662. ************************************************************************/
  4663. #define IS_BLANK_NODE(n) \
  4664. (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
  4665. /**
  4666. * xmlSchemaIsBlank:
  4667. * @str: a string
  4668. * @len: the length of the string or -1
  4669. *
  4670. * Check if a string is ignorable
  4671. *
  4672. * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
  4673. */
  4674. static int
  4675. xmlSchemaIsBlank(xmlChar * str, int len)
  4676. {
  4677. if (str == NULL)
  4678. return (1);
  4679. if (len < 0) {
  4680. while (*str != 0) {
  4681. if (!(IS_BLANK_CH(*str)))
  4682. return (0);
  4683. str++;
  4684. }
  4685. } else while ((*str != 0) && (len != 0)) {
  4686. if (!(IS_BLANK_CH(*str)))
  4687. return (0);
  4688. str++;
  4689. len--;
  4690. }
  4691. return (1);
  4692. }
  4693. #define WXS_COMP_NAME(c, t) ((t) (c))->name
  4694. #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
  4695. /*
  4696. * xmlSchemaFindRedefCompInGraph:
  4697. * ATTENTION TODO: This uses pointer comp. for strings.
  4698. */
  4699. static xmlSchemaBasicItemPtr
  4700. xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
  4701. xmlSchemaTypeType type,
  4702. const xmlChar *name,
  4703. const xmlChar *nsName)
  4704. {
  4705. xmlSchemaBasicItemPtr ret;
  4706. int i;
  4707. if ((bucket == NULL) || (name == NULL))
  4708. return(NULL);
  4709. if ((bucket->globals == NULL) ||
  4710. (bucket->globals->nbItems == 0))
  4711. goto subschemas;
  4712. /*
  4713. * Search in global components.
  4714. */
  4715. for (i = 0; i < bucket->globals->nbItems; i++) {
  4716. ret = bucket->globals->items[i];
  4717. if (ret->type == type) {
  4718. switch (type) {
  4719. case XML_SCHEMA_TYPE_COMPLEX:
  4720. case XML_SCHEMA_TYPE_SIMPLE:
  4721. if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
  4722. (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
  4723. nsName))
  4724. {
  4725. return(ret);
  4726. }
  4727. break;
  4728. case XML_SCHEMA_TYPE_GROUP:
  4729. if ((WXS_COMP_NAME(ret,
  4730. xmlSchemaModelGroupDefPtr) == name) &&
  4731. (WXS_COMP_TNS(ret,
  4732. xmlSchemaModelGroupDefPtr) == nsName))
  4733. {
  4734. return(ret);
  4735. }
  4736. break;
  4737. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  4738. if ((WXS_COMP_NAME(ret,
  4739. xmlSchemaAttributeGroupPtr) == name) &&
  4740. (WXS_COMP_TNS(ret,
  4741. xmlSchemaAttributeGroupPtr) == nsName))
  4742. {
  4743. return(ret);
  4744. }
  4745. break;
  4746. default:
  4747. /* Should not be hit. */
  4748. return(NULL);
  4749. }
  4750. }
  4751. }
  4752. subschemas:
  4753. /*
  4754. * Process imported/included schemas.
  4755. */
  4756. if (bucket->relations != NULL) {
  4757. xmlSchemaSchemaRelationPtr rel = bucket->relations;
  4758. /*
  4759. * TODO: Marking the bucket will not avoid multiple searches
  4760. * in the same schema, but avoids at least circularity.
  4761. */
  4762. bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
  4763. do {
  4764. if ((rel->bucket != NULL) &&
  4765. ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
  4766. ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
  4767. type, name, nsName);
  4768. if (ret != NULL)
  4769. return(ret);
  4770. }
  4771. rel = rel->next;
  4772. } while (rel != NULL);
  4773. bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
  4774. }
  4775. return(NULL);
  4776. }
  4777. /**
  4778. * xmlSchemaAddNotation:
  4779. * @ctxt: a schema parser context
  4780. * @schema: the schema being built
  4781. * @name: the item name
  4782. *
  4783. * Add an XML schema annotation declaration
  4784. * *WARNING* this interface is highly subject to change
  4785. *
  4786. * Returns the new structure or NULL in case of error
  4787. */
  4788. static xmlSchemaNotationPtr
  4789. xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4790. const xmlChar *name, const xmlChar *nsName,
  4791. xmlNodePtr node ATTRIBUTE_UNUSED)
  4792. {
  4793. xmlSchemaNotationPtr ret = NULL;
  4794. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  4795. return (NULL);
  4796. ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
  4797. if (ret == NULL) {
  4798. xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
  4799. return (NULL);
  4800. }
  4801. memset(ret, 0, sizeof(xmlSchemaNotation));
  4802. ret->type = XML_SCHEMA_TYPE_NOTATION;
  4803. ret->name = name;
  4804. ret->targetNamespace = nsName;
  4805. /* TODO: do we need the node to be set?
  4806. * ret->node = node;*/
  4807. WXS_ADD_GLOBAL(ctxt, ret);
  4808. return (ret);
  4809. }
  4810. /**
  4811. * xmlSchemaAddAttribute:
  4812. * @ctxt: a schema parser context
  4813. * @schema: the schema being built
  4814. * @name: the item name
  4815. * @namespace: the namespace
  4816. *
  4817. * Add an XML schema Attribute declaration
  4818. * *WARNING* this interface is highly subject to change
  4819. *
  4820. * Returns the new structure or NULL in case of error
  4821. */
  4822. static xmlSchemaAttributePtr
  4823. xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4824. const xmlChar * name, const xmlChar * nsName,
  4825. xmlNodePtr node, int topLevel)
  4826. {
  4827. xmlSchemaAttributePtr ret = NULL;
  4828. if ((ctxt == NULL) || (schema == NULL))
  4829. return (NULL);
  4830. ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
  4831. if (ret == NULL) {
  4832. xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
  4833. return (NULL);
  4834. }
  4835. memset(ret, 0, sizeof(xmlSchemaAttribute));
  4836. ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
  4837. ret->node = node;
  4838. ret->name = name;
  4839. ret->targetNamespace = nsName;
  4840. if (topLevel)
  4841. WXS_ADD_GLOBAL(ctxt, ret);
  4842. else
  4843. WXS_ADD_LOCAL(ctxt, ret);
  4844. WXS_ADD_PENDING(ctxt, ret);
  4845. return (ret);
  4846. }
  4847. /**
  4848. * xmlSchemaAddAttributeUse:
  4849. * @ctxt: a schema parser context
  4850. * @schema: the schema being built
  4851. * @name: the item name
  4852. * @namespace: the namespace
  4853. *
  4854. * Add an XML schema Attribute declaration
  4855. * *WARNING* this interface is highly subject to change
  4856. *
  4857. * Returns the new structure or NULL in case of error
  4858. */
  4859. static xmlSchemaAttributeUsePtr
  4860. xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
  4861. xmlNodePtr node)
  4862. {
  4863. xmlSchemaAttributeUsePtr ret = NULL;
  4864. if (pctxt == NULL)
  4865. return (NULL);
  4866. ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
  4867. if (ret == NULL) {
  4868. xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
  4869. return (NULL);
  4870. }
  4871. memset(ret, 0, sizeof(xmlSchemaAttributeUse));
  4872. ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
  4873. ret->node = node;
  4874. WXS_ADD_LOCAL(pctxt, ret);
  4875. return (ret);
  4876. }
  4877. /*
  4878. * xmlSchemaAddRedef:
  4879. *
  4880. * Adds a redefinition information. This is used at a later stage to:
  4881. * resolve references to the redefined components and to check constraints.
  4882. */
  4883. static xmlSchemaRedefPtr
  4884. xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
  4885. xmlSchemaBucketPtr targetBucket,
  4886. void *item,
  4887. const xmlChar *refName,
  4888. const xmlChar *refTargetNs)
  4889. {
  4890. xmlSchemaRedefPtr ret;
  4891. ret = (xmlSchemaRedefPtr)
  4892. xmlMalloc(sizeof(xmlSchemaRedef));
  4893. if (ret == NULL) {
  4894. xmlSchemaPErrMemory(pctxt,
  4895. "allocating redefinition info", NULL);
  4896. return (NULL);
  4897. }
  4898. memset(ret, 0, sizeof(xmlSchemaRedef));
  4899. ret->item = item;
  4900. ret->targetBucket = targetBucket;
  4901. ret->refName = refName;
  4902. ret->refTargetNs = refTargetNs;
  4903. if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
  4904. WXS_CONSTRUCTOR(pctxt)->redefs = ret;
  4905. else
  4906. WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
  4907. WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
  4908. return (ret);
  4909. }
  4910. /**
  4911. * xmlSchemaAddAttributeGroupDefinition:
  4912. * @ctxt: a schema parser context
  4913. * @schema: the schema being built
  4914. * @name: the item name
  4915. * @nsName: the target namespace
  4916. * @node: the corresponding node
  4917. *
  4918. * Add an XML schema Attribute Group definition.
  4919. *
  4920. * Returns the new structure or NULL in case of error
  4921. */
  4922. static xmlSchemaAttributeGroupPtr
  4923. xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
  4924. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  4925. const xmlChar *name,
  4926. const xmlChar *nsName,
  4927. xmlNodePtr node)
  4928. {
  4929. xmlSchemaAttributeGroupPtr ret = NULL;
  4930. if ((pctxt == NULL) || (name == NULL))
  4931. return (NULL);
  4932. ret = (xmlSchemaAttributeGroupPtr)
  4933. xmlMalloc(sizeof(xmlSchemaAttributeGroup));
  4934. if (ret == NULL) {
  4935. xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
  4936. return (NULL);
  4937. }
  4938. memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
  4939. ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
  4940. ret->name = name;
  4941. ret->targetNamespace = nsName;
  4942. ret->node = node;
  4943. /* TODO: Remove the flag. */
  4944. ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
  4945. if (pctxt->isRedefine) {
  4946. pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
  4947. ret, name, nsName);
  4948. if (pctxt->redef == NULL) {
  4949. xmlFree(ret);
  4950. return(NULL);
  4951. }
  4952. pctxt->redefCounter = 0;
  4953. }
  4954. WXS_ADD_GLOBAL(pctxt, ret);
  4955. WXS_ADD_PENDING(pctxt, ret);
  4956. return (ret);
  4957. }
  4958. /**
  4959. * xmlSchemaAddElement:
  4960. * @ctxt: a schema parser context
  4961. * @schema: the schema being built
  4962. * @name: the type name
  4963. * @namespace: the type namespace
  4964. *
  4965. * Add an XML schema Element declaration
  4966. * *WARNING* this interface is highly subject to change
  4967. *
  4968. * Returns the new structure or NULL in case of error
  4969. */
  4970. static xmlSchemaElementPtr
  4971. xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
  4972. const xmlChar * name, const xmlChar * nsName,
  4973. xmlNodePtr node, int topLevel)
  4974. {
  4975. xmlSchemaElementPtr ret = NULL;
  4976. if ((ctxt == NULL) || (name == NULL))
  4977. return (NULL);
  4978. ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
  4979. if (ret == NULL) {
  4980. xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
  4981. return (NULL);
  4982. }
  4983. memset(ret, 0, sizeof(xmlSchemaElement));
  4984. ret->type = XML_SCHEMA_TYPE_ELEMENT;
  4985. ret->name = name;
  4986. ret->targetNamespace = nsName;
  4987. ret->node = node;
  4988. if (topLevel)
  4989. WXS_ADD_GLOBAL(ctxt, ret);
  4990. else
  4991. WXS_ADD_LOCAL(ctxt, ret);
  4992. WXS_ADD_PENDING(ctxt, ret);
  4993. return (ret);
  4994. }
  4995. /**
  4996. * xmlSchemaAddType:
  4997. * @ctxt: a schema parser context
  4998. * @schema: the schema being built
  4999. * @name: the item name
  5000. * @namespace: the namespace
  5001. *
  5002. * Add an XML schema item
  5003. * *WARNING* this interface is highly subject to change
  5004. *
  5005. * Returns the new structure or NULL in case of error
  5006. */
  5007. static xmlSchemaTypePtr
  5008. xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5009. xmlSchemaTypeType type,
  5010. const xmlChar * name, const xmlChar * nsName,
  5011. xmlNodePtr node, int topLevel)
  5012. {
  5013. xmlSchemaTypePtr ret = NULL;
  5014. if ((ctxt == NULL) || (schema == NULL))
  5015. return (NULL);
  5016. ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
  5017. if (ret == NULL) {
  5018. xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
  5019. return (NULL);
  5020. }
  5021. memset(ret, 0, sizeof(xmlSchemaType));
  5022. ret->type = type;
  5023. ret->name = name;
  5024. ret->targetNamespace = nsName;
  5025. ret->node = node;
  5026. if (topLevel) {
  5027. if (ctxt->isRedefine) {
  5028. ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
  5029. ret, name, nsName);
  5030. if (ctxt->redef == NULL) {
  5031. xmlFree(ret);
  5032. return(NULL);
  5033. }
  5034. ctxt->redefCounter = 0;
  5035. }
  5036. WXS_ADD_GLOBAL(ctxt, ret);
  5037. } else
  5038. WXS_ADD_LOCAL(ctxt, ret);
  5039. WXS_ADD_PENDING(ctxt, ret);
  5040. return (ret);
  5041. }
  5042. static xmlSchemaQNameRefPtr
  5043. xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
  5044. xmlSchemaTypeType refType,
  5045. const xmlChar *refName,
  5046. const xmlChar *refNs)
  5047. {
  5048. xmlSchemaQNameRefPtr ret;
  5049. ret = (xmlSchemaQNameRefPtr)
  5050. xmlMalloc(sizeof(xmlSchemaQNameRef));
  5051. if (ret == NULL) {
  5052. xmlSchemaPErrMemory(pctxt,
  5053. "allocating QName reference item", NULL);
  5054. return (NULL);
  5055. }
  5056. ret->node = NULL;
  5057. ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
  5058. ret->name = refName;
  5059. ret->targetNamespace = refNs;
  5060. ret->item = NULL;
  5061. ret->itemType = refType;
  5062. /*
  5063. * Store the reference item in the schema.
  5064. */
  5065. WXS_ADD_LOCAL(pctxt, ret);
  5066. return (ret);
  5067. }
  5068. static xmlSchemaAttributeUseProhibPtr
  5069. xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
  5070. {
  5071. xmlSchemaAttributeUseProhibPtr ret;
  5072. ret = (xmlSchemaAttributeUseProhibPtr)
  5073. xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
  5074. if (ret == NULL) {
  5075. xmlSchemaPErrMemory(pctxt,
  5076. "allocating attribute use prohibition", NULL);
  5077. return (NULL);
  5078. }
  5079. memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
  5080. ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
  5081. WXS_ADD_LOCAL(pctxt, ret);
  5082. return (ret);
  5083. }
  5084. /**
  5085. * xmlSchemaAddModelGroup:
  5086. * @ctxt: a schema parser context
  5087. * @schema: the schema being built
  5088. * @type: the "compositor" type of the model group
  5089. * @node: the node in the schema doc
  5090. *
  5091. * Adds a schema model group
  5092. * *WARNING* this interface is highly subject to change
  5093. *
  5094. * Returns the new structure or NULL in case of error
  5095. */
  5096. static xmlSchemaModelGroupPtr
  5097. xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
  5098. xmlSchemaPtr schema,
  5099. xmlSchemaTypeType type,
  5100. xmlNodePtr node)
  5101. {
  5102. xmlSchemaModelGroupPtr ret = NULL;
  5103. if ((ctxt == NULL) || (schema == NULL))
  5104. return (NULL);
  5105. ret = (xmlSchemaModelGroupPtr)
  5106. xmlMalloc(sizeof(xmlSchemaModelGroup));
  5107. if (ret == NULL) {
  5108. xmlSchemaPErrMemory(ctxt, "allocating model group component",
  5109. NULL);
  5110. return (NULL);
  5111. }
  5112. memset(ret, 0, sizeof(xmlSchemaModelGroup));
  5113. ret->type = type;
  5114. ret->node = node;
  5115. WXS_ADD_LOCAL(ctxt, ret);
  5116. if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
  5117. (type == XML_SCHEMA_TYPE_CHOICE))
  5118. WXS_ADD_PENDING(ctxt, ret);
  5119. return (ret);
  5120. }
  5121. /**
  5122. * xmlSchemaAddParticle:
  5123. * @ctxt: a schema parser context
  5124. * @schema: the schema being built
  5125. * @node: the corresponding node in the schema doc
  5126. * @min: the minOccurs
  5127. * @max: the maxOccurs
  5128. *
  5129. * Adds an XML schema particle component.
  5130. * *WARNING* this interface is highly subject to change
  5131. *
  5132. * Returns the new structure or NULL in case of error
  5133. */
  5134. static xmlSchemaParticlePtr
  5135. xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
  5136. xmlNodePtr node, int min, int max)
  5137. {
  5138. xmlSchemaParticlePtr ret = NULL;
  5139. if (ctxt == NULL)
  5140. return (NULL);
  5141. #ifdef DEBUG
  5142. fprintf(stderr, "Adding particle component\n");
  5143. #endif
  5144. ret = (xmlSchemaParticlePtr)
  5145. xmlMalloc(sizeof(xmlSchemaParticle));
  5146. if (ret == NULL) {
  5147. xmlSchemaPErrMemory(ctxt, "allocating particle component",
  5148. NULL);
  5149. return (NULL);
  5150. }
  5151. ret->type = XML_SCHEMA_TYPE_PARTICLE;
  5152. ret->annot = NULL;
  5153. ret->node = node;
  5154. ret->minOccurs = min;
  5155. ret->maxOccurs = max;
  5156. ret->next = NULL;
  5157. ret->children = NULL;
  5158. WXS_ADD_LOCAL(ctxt, ret);
  5159. /*
  5160. * Note that addition to pending components will be done locally
  5161. * to the specific parsing function, since the most particles
  5162. * need not to be fixed up (i.e. the reference to be resolved).
  5163. * REMOVED: WXS_ADD_PENDING(ctxt, ret);
  5164. */
  5165. return (ret);
  5166. }
  5167. /**
  5168. * xmlSchemaAddModelGroupDefinition:
  5169. * @ctxt: a schema validation context
  5170. * @schema: the schema being built
  5171. * @name: the group name
  5172. *
  5173. * Add an XML schema Group definition
  5174. *
  5175. * Returns the new structure or NULL in case of error
  5176. */
  5177. static xmlSchemaModelGroupDefPtr
  5178. xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
  5179. xmlSchemaPtr schema,
  5180. const xmlChar *name,
  5181. const xmlChar *nsName,
  5182. xmlNodePtr node)
  5183. {
  5184. xmlSchemaModelGroupDefPtr ret = NULL;
  5185. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  5186. return (NULL);
  5187. ret = (xmlSchemaModelGroupDefPtr)
  5188. xmlMalloc(sizeof(xmlSchemaModelGroupDef));
  5189. if (ret == NULL) {
  5190. xmlSchemaPErrMemory(ctxt, "adding group", NULL);
  5191. return (NULL);
  5192. }
  5193. memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
  5194. ret->name = name;
  5195. ret->type = XML_SCHEMA_TYPE_GROUP;
  5196. ret->node = node;
  5197. ret->targetNamespace = nsName;
  5198. if (ctxt->isRedefine) {
  5199. ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
  5200. ret, name, nsName);
  5201. if (ctxt->redef == NULL) {
  5202. xmlFree(ret);
  5203. return(NULL);
  5204. }
  5205. ctxt->redefCounter = 0;
  5206. }
  5207. WXS_ADD_GLOBAL(ctxt, ret);
  5208. WXS_ADD_PENDING(ctxt, ret);
  5209. return (ret);
  5210. }
  5211. /**
  5212. * xmlSchemaNewWildcardNs:
  5213. * @ctxt: a schema validation context
  5214. *
  5215. * Creates a new wildcard namespace constraint.
  5216. *
  5217. * Returns the new structure or NULL in case of error
  5218. */
  5219. static xmlSchemaWildcardNsPtr
  5220. xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
  5221. {
  5222. xmlSchemaWildcardNsPtr ret;
  5223. ret = (xmlSchemaWildcardNsPtr)
  5224. xmlMalloc(sizeof(xmlSchemaWildcardNs));
  5225. if (ret == NULL) {
  5226. xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
  5227. return (NULL);
  5228. }
  5229. ret->value = NULL;
  5230. ret->next = NULL;
  5231. return (ret);
  5232. }
  5233. static xmlSchemaIDCPtr
  5234. xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5235. const xmlChar *name, const xmlChar *nsName,
  5236. int category, xmlNodePtr node)
  5237. {
  5238. xmlSchemaIDCPtr ret = NULL;
  5239. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  5240. return (NULL);
  5241. ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
  5242. if (ret == NULL) {
  5243. xmlSchemaPErrMemory(ctxt,
  5244. "allocating an identity-constraint definition", NULL);
  5245. return (NULL);
  5246. }
  5247. memset(ret, 0, sizeof(xmlSchemaIDC));
  5248. /* The target namespace of the parent element declaration. */
  5249. ret->targetNamespace = nsName;
  5250. ret->name = name;
  5251. ret->type = category;
  5252. ret->node = node;
  5253. WXS_ADD_GLOBAL(ctxt, ret);
  5254. /*
  5255. * Only keyrefs need to be fixup up.
  5256. */
  5257. if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
  5258. WXS_ADD_PENDING(ctxt, ret);
  5259. return (ret);
  5260. }
  5261. /**
  5262. * xmlSchemaAddWildcard:
  5263. * @ctxt: a schema validation context
  5264. * @schema: a schema
  5265. *
  5266. * Adds a wildcard.
  5267. * It corresponds to a xsd:anyAttribute and xsd:any.
  5268. *
  5269. * Returns the new structure or NULL in case of error
  5270. */
  5271. static xmlSchemaWildcardPtr
  5272. xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5273. xmlSchemaTypeType type, xmlNodePtr node)
  5274. {
  5275. xmlSchemaWildcardPtr ret = NULL;
  5276. if ((ctxt == NULL) || (schema == NULL))
  5277. return (NULL);
  5278. ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
  5279. if (ret == NULL) {
  5280. xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
  5281. return (NULL);
  5282. }
  5283. memset(ret, 0, sizeof(xmlSchemaWildcard));
  5284. ret->type = type;
  5285. ret->node = node;
  5286. WXS_ADD_LOCAL(ctxt, ret);
  5287. return (ret);
  5288. }
  5289. static void
  5290. xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
  5291. {
  5292. if (group == NULL)
  5293. return;
  5294. if (group->members != NULL)
  5295. xmlSchemaItemListFree(group->members);
  5296. xmlFree(group);
  5297. }
  5298. static void
  5299. xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
  5300. {
  5301. xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
  5302. }
  5303. static xmlSchemaSubstGroupPtr
  5304. xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
  5305. xmlSchemaElementPtr head)
  5306. {
  5307. xmlSchemaSubstGroupPtr ret;
  5308. /* Init subst group hash. */
  5309. if (WXS_SUBST_GROUPS(pctxt) == NULL) {
  5310. WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
  5311. if (WXS_SUBST_GROUPS(pctxt) == NULL)
  5312. return(NULL);
  5313. }
  5314. /* Create a new substitution group. */
  5315. ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
  5316. if (ret == NULL) {
  5317. xmlSchemaPErrMemory(NULL,
  5318. "allocating a substitution group container", NULL);
  5319. return(NULL);
  5320. }
  5321. memset(ret, 0, sizeof(xmlSchemaSubstGroup));
  5322. ret->head = head;
  5323. /* Create list of members. */
  5324. ret->members = xmlSchemaItemListCreate();
  5325. if (ret->members == NULL) {
  5326. xmlSchemaSubstGroupFree(ret);
  5327. return(NULL);
  5328. }
  5329. /* Add subst group to hash. */
  5330. if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
  5331. head->name, head->targetNamespace, ret) != 0) {
  5332. PERROR_INT("xmlSchemaSubstGroupAdd",
  5333. "failed to add a new substitution container");
  5334. xmlSchemaSubstGroupFree(ret);
  5335. return(NULL);
  5336. }
  5337. return(ret);
  5338. }
  5339. static xmlSchemaSubstGroupPtr
  5340. xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
  5341. xmlSchemaElementPtr head)
  5342. {
  5343. if (WXS_SUBST_GROUPS(pctxt) == NULL)
  5344. return(NULL);
  5345. return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
  5346. head->name, head->targetNamespace));
  5347. }
  5348. /**
  5349. * xmlSchemaAddElementSubstitutionMember:
  5350. * @pctxt: a schema parser context
  5351. * @head: the head of the substitution group
  5352. * @member: the new member of the substitution group
  5353. *
  5354. * Allocate a new annotation structure.
  5355. *
  5356. * Returns the newly allocated structure or NULL in case or error
  5357. */
  5358. static int
  5359. xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
  5360. xmlSchemaElementPtr head,
  5361. xmlSchemaElementPtr member)
  5362. {
  5363. xmlSchemaSubstGroupPtr substGroup = NULL;
  5364. if ((pctxt == NULL) || (head == NULL) || (member == NULL))
  5365. return (-1);
  5366. substGroup = xmlSchemaSubstGroupGet(pctxt, head);
  5367. if (substGroup == NULL)
  5368. substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
  5369. if (substGroup == NULL)
  5370. return(-1);
  5371. if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
  5372. return(-1);
  5373. return(0);
  5374. }
  5375. /************************************************************************
  5376. * *
  5377. * Utilities for parsing *
  5378. * *
  5379. ************************************************************************/
  5380. /**
  5381. * xmlSchemaPValAttrNodeQNameValue:
  5382. * @ctxt: a schema parser context
  5383. * @schema: the schema context
  5384. * @ownerItem: the parent as a schema object
  5385. * @value: the QName value
  5386. * @uri: the resulting namespace URI if found
  5387. * @local: the resulting local part if found, the attribute value otherwise
  5388. *
  5389. * Extracts the local name and the URI of a QName value and validates it.
  5390. * This one is intended to be used on attribute values that
  5391. * should resolve to schema components.
  5392. *
  5393. * Returns 0, in case the QName is valid, a positive error code
  5394. * if not valid and -1 if an internal error occurs.
  5395. */
  5396. static int
  5397. xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
  5398. xmlSchemaPtr schema,
  5399. xmlSchemaBasicItemPtr ownerItem,
  5400. xmlAttrPtr attr,
  5401. const xmlChar *value,
  5402. const xmlChar **uri,
  5403. const xmlChar **local)
  5404. {
  5405. const xmlChar *pref;
  5406. xmlNsPtr ns;
  5407. int len, ret;
  5408. *uri = NULL;
  5409. *local = NULL;
  5410. ret = xmlValidateQName(value, 1);
  5411. if (ret > 0) {
  5412. xmlSchemaPSimpleTypeErr(ctxt,
  5413. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5414. ownerItem, (xmlNodePtr) attr,
  5415. xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  5416. NULL, value, NULL, NULL, NULL);
  5417. *local = value;
  5418. return (ctxt->err);
  5419. } else if (ret < 0)
  5420. return (-1);
  5421. if (!strchr((char *) value, ':')) {
  5422. ns = xmlSearchNs(attr->doc, attr->parent, NULL);
  5423. if (ns && ns->href && ns->href[0])
  5424. *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
  5425. else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
  5426. /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
  5427. * parser context. */
  5428. /*
  5429. * This one takes care of included schemas with no
  5430. * target namespace.
  5431. */
  5432. *uri = ctxt->targetNamespace;
  5433. }
  5434. *local = xmlDictLookup(ctxt->dict, value, -1);
  5435. return (0);
  5436. }
  5437. /*
  5438. * At this point xmlSplitQName3 has to return a local name.
  5439. */
  5440. *local = xmlSplitQName3(value, &len);
  5441. *local = xmlDictLookup(ctxt->dict, *local, -1);
  5442. pref = xmlDictLookup(ctxt->dict, value, len);
  5443. ns = xmlSearchNs(attr->doc, attr->parent, pref);
  5444. if (ns == NULL) {
  5445. xmlSchemaPSimpleTypeErr(ctxt,
  5446. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5447. ownerItem, (xmlNodePtr) attr,
  5448. xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
  5449. "The value '%s' of simple type 'xs:QName' has no "
  5450. "corresponding namespace declaration in scope", value, NULL);
  5451. return (ctxt->err);
  5452. } else {
  5453. *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
  5454. }
  5455. return (0);
  5456. }
  5457. /**
  5458. * xmlSchemaPValAttrNodeQName:
  5459. * @ctxt: a schema parser context
  5460. * @schema: the schema context
  5461. * @ownerItem: the owner as a schema object
  5462. * @attr: the attribute node
  5463. * @uri: the resulting namespace URI if found
  5464. * @local: the resulting local part if found, the attribute value otherwise
  5465. *
  5466. * Extracts and validates the QName of an attribute value.
  5467. * This one is intended to be used on attribute values that
  5468. * should resolve to schema components.
  5469. *
  5470. * Returns 0, in case the QName is valid, a positive error code
  5471. * if not valid and -1 if an internal error occurs.
  5472. */
  5473. static int
  5474. xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
  5475. xmlSchemaPtr schema,
  5476. xmlSchemaBasicItemPtr ownerItem,
  5477. xmlAttrPtr attr,
  5478. const xmlChar **uri,
  5479. const xmlChar **local)
  5480. {
  5481. const xmlChar *value;
  5482. value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5483. return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
  5484. ownerItem, attr, value, uri, local));
  5485. }
  5486. /**
  5487. * xmlSchemaPValAttrQName:
  5488. * @ctxt: a schema parser context
  5489. * @schema: the schema context
  5490. * @ownerItem: the owner as a schema object
  5491. * @ownerElem: the parent node of the attribute
  5492. * @name: the name of the attribute
  5493. * @uri: the resulting namespace URI if found
  5494. * @local: the resulting local part if found, the attribute value otherwise
  5495. *
  5496. * Extracts and validates the QName of an attribute value.
  5497. *
  5498. * Returns 0, in case the QName is valid, a positive error code
  5499. * if not valid and -1 if an internal error occurs.
  5500. */
  5501. static int
  5502. xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
  5503. xmlSchemaPtr schema,
  5504. xmlSchemaBasicItemPtr ownerItem,
  5505. xmlNodePtr ownerElem,
  5506. const char *name,
  5507. const xmlChar **uri,
  5508. const xmlChar **local)
  5509. {
  5510. xmlAttrPtr attr;
  5511. attr = xmlSchemaGetPropNode(ownerElem, name);
  5512. if (attr == NULL) {
  5513. *local = NULL;
  5514. *uri = NULL;
  5515. return (0);
  5516. }
  5517. return (xmlSchemaPValAttrNodeQName(ctxt, schema,
  5518. ownerItem, attr, uri, local));
  5519. }
  5520. /**
  5521. * xmlSchemaPValAttrID:
  5522. * @ctxt: a schema parser context
  5523. *
  5524. * Extracts and validates the ID of an attribute value.
  5525. *
  5526. * Returns 0, in case the ID is valid, a positive error code
  5527. * if not valid and -1 if an internal error occurs.
  5528. */
  5529. static int
  5530. xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
  5531. {
  5532. int ret;
  5533. const xmlChar *value;
  5534. if (attr == NULL)
  5535. return(0);
  5536. value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
  5537. ret = xmlValidateNCName(value, 1);
  5538. if (ret == 0) {
  5539. /*
  5540. * NOTE: the IDness might have already be declared in the DTD
  5541. */
  5542. if (attr->atype != XML_ATTRIBUTE_ID) {
  5543. xmlIDPtr res;
  5544. xmlChar *strip;
  5545. /*
  5546. * TODO: Use xmlSchemaStrip here; it's not exported at this
  5547. * moment.
  5548. */
  5549. strip = xmlSchemaCollapseString(value);
  5550. if (strip != NULL) {
  5551. xmlFree((xmlChar *) value);
  5552. value = strip;
  5553. }
  5554. res = xmlAddID(NULL, attr->doc, value, attr);
  5555. if (res == NULL) {
  5556. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  5557. xmlSchemaPSimpleTypeErr(ctxt,
  5558. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5559. NULL, (xmlNodePtr) attr,
  5560. xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
  5561. NULL, NULL, "Duplicate value '%s' of simple "
  5562. "type 'xs:ID'", value, NULL);
  5563. } else
  5564. attr->atype = XML_ATTRIBUTE_ID;
  5565. }
  5566. } else if (ret > 0) {
  5567. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  5568. xmlSchemaPSimpleTypeErr(ctxt,
  5569. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5570. NULL, (xmlNodePtr) attr,
  5571. xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
  5572. NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
  5573. "not a valid 'xs:NCName'",
  5574. value, NULL);
  5575. }
  5576. if (value != NULL)
  5577. xmlFree((xmlChar *)value);
  5578. return (ret);
  5579. }
  5580. static int
  5581. xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
  5582. xmlNodePtr ownerElem,
  5583. const xmlChar *name)
  5584. {
  5585. xmlAttrPtr attr;
  5586. attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
  5587. if (attr == NULL)
  5588. return(0);
  5589. return(xmlSchemaPValAttrNodeID(ctxt, attr));
  5590. }
  5591. /**
  5592. * xmlGetMaxOccurs:
  5593. * @ctxt: a schema validation context
  5594. * @node: a subtree containing XML Schema information
  5595. *
  5596. * Get the maxOccurs property
  5597. *
  5598. * Returns the default if not found, or the value
  5599. */
  5600. static int
  5601. xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  5602. int min, int max, int def, const char *expected)
  5603. {
  5604. const xmlChar *val, *cur;
  5605. int ret = 0;
  5606. xmlAttrPtr attr;
  5607. attr = xmlSchemaGetPropNode(node, "maxOccurs");
  5608. if (attr == NULL)
  5609. return (def);
  5610. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5611. if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
  5612. if (max != UNBOUNDED) {
  5613. xmlSchemaPSimpleTypeErr(ctxt,
  5614. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5615. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5616. NULL, (xmlNodePtr) attr, NULL, expected,
  5617. val, NULL, NULL, NULL);
  5618. return (def);
  5619. } else
  5620. return (UNBOUNDED); /* encoding it with -1 might be another option */
  5621. }
  5622. cur = val;
  5623. while (IS_BLANK_CH(*cur))
  5624. cur++;
  5625. if (*cur == 0) {
  5626. xmlSchemaPSimpleTypeErr(ctxt,
  5627. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5628. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5629. NULL, (xmlNodePtr) attr, NULL, expected,
  5630. val, NULL, NULL, NULL);
  5631. return (def);
  5632. }
  5633. while ((*cur >= '0') && (*cur <= '9')) {
  5634. if (ret > INT_MAX / 10) {
  5635. ret = INT_MAX;
  5636. } else {
  5637. int digit = *cur - '0';
  5638. ret *= 10;
  5639. if (ret > INT_MAX - digit)
  5640. ret = INT_MAX;
  5641. else
  5642. ret += digit;
  5643. }
  5644. cur++;
  5645. }
  5646. while (IS_BLANK_CH(*cur))
  5647. cur++;
  5648. /*
  5649. * TODO: Restrict the maximal value to Integer.
  5650. */
  5651. if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
  5652. xmlSchemaPSimpleTypeErr(ctxt,
  5653. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5654. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5655. NULL, (xmlNodePtr) attr, NULL, expected,
  5656. val, NULL, NULL, NULL);
  5657. return (def);
  5658. }
  5659. return (ret);
  5660. }
  5661. /**
  5662. * xmlGetMinOccurs:
  5663. * @ctxt: a schema validation context
  5664. * @node: a subtree containing XML Schema information
  5665. *
  5666. * Get the minOccurs property
  5667. *
  5668. * Returns the default if not found, or the value
  5669. */
  5670. static int
  5671. xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  5672. int min, int max, int def, const char *expected)
  5673. {
  5674. const xmlChar *val, *cur;
  5675. int ret = 0;
  5676. xmlAttrPtr attr;
  5677. attr = xmlSchemaGetPropNode(node, "minOccurs");
  5678. if (attr == NULL)
  5679. return (def);
  5680. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5681. cur = val;
  5682. while (IS_BLANK_CH(*cur))
  5683. cur++;
  5684. if (*cur == 0) {
  5685. xmlSchemaPSimpleTypeErr(ctxt,
  5686. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5687. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5688. NULL, (xmlNodePtr) attr, NULL, expected,
  5689. val, NULL, NULL, NULL);
  5690. return (def);
  5691. }
  5692. while ((*cur >= '0') && (*cur <= '9')) {
  5693. if (ret > INT_MAX / 10) {
  5694. ret = INT_MAX;
  5695. } else {
  5696. int digit = *cur - '0';
  5697. ret *= 10;
  5698. if (ret > INT_MAX - digit)
  5699. ret = INT_MAX;
  5700. else
  5701. ret += digit;
  5702. }
  5703. cur++;
  5704. }
  5705. while (IS_BLANK_CH(*cur))
  5706. cur++;
  5707. /*
  5708. * TODO: Restrict the maximal value to Integer.
  5709. */
  5710. if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
  5711. xmlSchemaPSimpleTypeErr(ctxt,
  5712. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5713. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5714. NULL, (xmlNodePtr) attr, NULL, expected,
  5715. val, NULL, NULL, NULL);
  5716. return (def);
  5717. }
  5718. return (ret);
  5719. }
  5720. /**
  5721. * xmlSchemaPGetBoolNodeValue:
  5722. * @ctxt: a schema validation context
  5723. * @ownerItem: the owner as a schema item
  5724. * @node: the node holding the value
  5725. *
  5726. * Converts a boolean string value into 1 or 0.
  5727. *
  5728. * Returns 0 or 1.
  5729. */
  5730. static int
  5731. xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
  5732. xmlSchemaBasicItemPtr ownerItem,
  5733. xmlNodePtr node)
  5734. {
  5735. xmlChar *value = NULL;
  5736. int res = 0;
  5737. value = xmlNodeGetContent(node);
  5738. /*
  5739. * 3.2.2.1 Lexical representation
  5740. * An instance of a datatype that is defined as `boolean`
  5741. * can have the following legal literals {true, false, 1, 0}.
  5742. */
  5743. if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
  5744. res = 1;
  5745. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
  5746. res = 0;
  5747. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
  5748. res = 1;
  5749. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
  5750. res = 0;
  5751. else {
  5752. xmlSchemaPSimpleTypeErr(ctxt,
  5753. XML_SCHEMAP_INVALID_BOOLEAN,
  5754. ownerItem, node,
  5755. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  5756. NULL, BAD_CAST value,
  5757. NULL, NULL, NULL);
  5758. }
  5759. if (value != NULL)
  5760. xmlFree(value);
  5761. return (res);
  5762. }
  5763. /**
  5764. * xmlGetBooleanProp:
  5765. * @ctxt: a schema validation context
  5766. * @node: a subtree containing XML Schema information
  5767. * @name: the attribute name
  5768. * @def: the default value
  5769. *
  5770. * Evaluate if a boolean property is set
  5771. *
  5772. * Returns the default if not found, 0 if found to be false,
  5773. * 1 if found to be true
  5774. */
  5775. static int
  5776. xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
  5777. xmlNodePtr node,
  5778. const char *name, int def)
  5779. {
  5780. const xmlChar *val;
  5781. val = xmlSchemaGetProp(ctxt, node, name);
  5782. if (val == NULL)
  5783. return (def);
  5784. /*
  5785. * 3.2.2.1 Lexical representation
  5786. * An instance of a datatype that is defined as `boolean`
  5787. * can have the following legal literals {true, false, 1, 0}.
  5788. */
  5789. if (xmlStrEqual(val, BAD_CAST "true"))
  5790. def = 1;
  5791. else if (xmlStrEqual(val, BAD_CAST "false"))
  5792. def = 0;
  5793. else if (xmlStrEqual(val, BAD_CAST "1"))
  5794. def = 1;
  5795. else if (xmlStrEqual(val, BAD_CAST "0"))
  5796. def = 0;
  5797. else {
  5798. xmlSchemaPSimpleTypeErr(ctxt,
  5799. XML_SCHEMAP_INVALID_BOOLEAN,
  5800. NULL,
  5801. (xmlNodePtr) xmlSchemaGetPropNode(node, name),
  5802. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  5803. NULL, val, NULL, NULL, NULL);
  5804. }
  5805. return (def);
  5806. }
  5807. /************************************************************************
  5808. * *
  5809. * Schema extraction from an Infoset *
  5810. * *
  5811. ************************************************************************/
  5812. static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
  5813. ctxt, xmlSchemaPtr schema,
  5814. xmlNodePtr node,
  5815. int topLevel);
  5816. static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
  5817. ctxt,
  5818. xmlSchemaPtr schema,
  5819. xmlNodePtr node,
  5820. int topLevel);
  5821. static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
  5822. ctxt,
  5823. xmlSchemaPtr schema,
  5824. xmlNodePtr node,
  5825. xmlSchemaTypeType parentType);
  5826. static xmlSchemaBasicItemPtr
  5827. xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
  5828. xmlSchemaPtr schema,
  5829. xmlNodePtr node,
  5830. xmlSchemaItemListPtr uses,
  5831. int parentType);
  5832. static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
  5833. xmlSchemaPtr schema,
  5834. xmlNodePtr node);
  5835. static xmlSchemaWildcardPtr
  5836. xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
  5837. xmlSchemaPtr schema, xmlNodePtr node);
  5838. /**
  5839. * xmlSchemaPValAttrNodeValue:
  5840. *
  5841. * @pctxt: a schema parser context
  5842. * @ownerItem: the schema object owner if existent
  5843. * @attr: the schema attribute node being validated
  5844. * @value: the value
  5845. * @type: the built-in type to be validated against
  5846. *
  5847. * Validates a value against the given built-in type.
  5848. * This one is intended to be used internally for validation
  5849. * of schema attribute values during parsing of the schema.
  5850. *
  5851. * Returns 0 if the value is valid, a positive error code
  5852. * number otherwise and -1 in case of an internal or API error.
  5853. */
  5854. static int
  5855. xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
  5856. xmlSchemaBasicItemPtr ownerItem,
  5857. xmlAttrPtr attr,
  5858. const xmlChar *value,
  5859. xmlSchemaTypePtr type)
  5860. {
  5861. int ret = 0;
  5862. /*
  5863. * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
  5864. * one is really meant to be used internally, so better not.
  5865. */
  5866. if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
  5867. return (-1);
  5868. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  5869. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5870. "the given type is not a built-in type");
  5871. return (-1);
  5872. }
  5873. switch (type->builtInType) {
  5874. case XML_SCHEMAS_NCNAME:
  5875. case XML_SCHEMAS_QNAME:
  5876. case XML_SCHEMAS_ANYURI:
  5877. case XML_SCHEMAS_TOKEN:
  5878. case XML_SCHEMAS_LANGUAGE:
  5879. ret = xmlSchemaValPredefTypeNode(type, value, NULL,
  5880. (xmlNodePtr) attr);
  5881. break;
  5882. default: {
  5883. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5884. "validation using the given type is not supported while "
  5885. "parsing a schema");
  5886. return (-1);
  5887. }
  5888. }
  5889. /*
  5890. * TODO: Should we use the S4S error codes instead?
  5891. */
  5892. if (ret < 0) {
  5893. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5894. "failed to validate a schema attribute value");
  5895. return (-1);
  5896. } else if (ret > 0) {
  5897. if (WXS_IS_LIST(type))
  5898. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  5899. else
  5900. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  5901. xmlSchemaPSimpleTypeErr(pctxt,
  5902. ret, ownerItem, (xmlNodePtr) attr,
  5903. type, NULL, value, NULL, NULL, NULL);
  5904. }
  5905. return (ret);
  5906. }
  5907. /**
  5908. * xmlSchemaPValAttrNode:
  5909. *
  5910. * @ctxt: a schema parser context
  5911. * @ownerItem: the schema object owner if existent
  5912. * @attr: the schema attribute node being validated
  5913. * @type: the built-in type to be validated against
  5914. * @value: the resulting value if any
  5915. *
  5916. * Extracts and validates a value against the given built-in type.
  5917. * This one is intended to be used internally for validation
  5918. * of schema attribute values during parsing of the schema.
  5919. *
  5920. * Returns 0 if the value is valid, a positive error code
  5921. * number otherwise and -1 in case of an internal or API error.
  5922. */
  5923. static int
  5924. xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
  5925. xmlSchemaBasicItemPtr ownerItem,
  5926. xmlAttrPtr attr,
  5927. xmlSchemaTypePtr type,
  5928. const xmlChar **value)
  5929. {
  5930. const xmlChar *val;
  5931. if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
  5932. return (-1);
  5933. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5934. if (value != NULL)
  5935. *value = val;
  5936. return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
  5937. val, type));
  5938. }
  5939. /**
  5940. * xmlSchemaPValAttr:
  5941. *
  5942. * @ctxt: a schema parser context
  5943. * @node: the element node of the attribute
  5944. * @ownerItem: the schema object owner if existent
  5945. * @ownerElem: the owner element node
  5946. * @name: the name of the schema attribute node
  5947. * @type: the built-in type to be validated against
  5948. * @value: the resulting value if any
  5949. *
  5950. * Extracts and validates a value against the given built-in type.
  5951. * This one is intended to be used internally for validation
  5952. * of schema attribute values during parsing of the schema.
  5953. *
  5954. * Returns 0 if the value is valid, a positive error code
  5955. * number otherwise and -1 in case of an internal or API error.
  5956. */
  5957. static int
  5958. xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
  5959. xmlSchemaBasicItemPtr ownerItem,
  5960. xmlNodePtr ownerElem,
  5961. const char *name,
  5962. xmlSchemaTypePtr type,
  5963. const xmlChar **value)
  5964. {
  5965. xmlAttrPtr attr;
  5966. if ((ctxt == NULL) || (type == NULL)) {
  5967. if (value != NULL)
  5968. *value = NULL;
  5969. return (-1);
  5970. }
  5971. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  5972. if (value != NULL)
  5973. *value = NULL;
  5974. xmlSchemaPErr(ctxt, ownerElem,
  5975. XML_SCHEMAP_INTERNAL,
  5976. "Internal error: xmlSchemaPValAttr, the given "
  5977. "type '%s' is not a built-in type.\n",
  5978. type->name, NULL);
  5979. return (-1);
  5980. }
  5981. attr = xmlSchemaGetPropNode(ownerElem, name);
  5982. if (attr == NULL) {
  5983. if (value != NULL)
  5984. *value = NULL;
  5985. return (0);
  5986. }
  5987. return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
  5988. type, value));
  5989. }
  5990. static int
  5991. xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
  5992. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  5993. xmlNodePtr node,
  5994. xmlAttrPtr attr,
  5995. const xmlChar *namespaceName)
  5996. {
  5997. /* TODO: Pointer comparison instead? */
  5998. if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
  5999. return (0);
  6000. if (xmlStrEqual(xmlSchemaNs, namespaceName))
  6001. return (0);
  6002. /*
  6003. * Check if the referenced namespace was <import>ed.
  6004. */
  6005. if (WXS_BUCKET(pctxt)->relations != NULL) {
  6006. xmlSchemaSchemaRelationPtr rel;
  6007. rel = WXS_BUCKET(pctxt)->relations;
  6008. do {
  6009. if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
  6010. xmlStrEqual(namespaceName, rel->importNamespace))
  6011. return (0);
  6012. rel = rel->next;
  6013. } while (rel != NULL);
  6014. }
  6015. /*
  6016. * No matching <import>ed namespace found.
  6017. */
  6018. {
  6019. xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
  6020. if (namespaceName == NULL)
  6021. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  6022. XML_SCHEMAP_SRC_RESOLVE, n, NULL,
  6023. "References from this schema to components in no "
  6024. "namespace are not allowed, since not indicated by an "
  6025. "import statement", NULL, NULL);
  6026. else
  6027. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  6028. XML_SCHEMAP_SRC_RESOLVE, n, NULL,
  6029. "References from this schema to components in the "
  6030. "namespace '%s' are not allowed, since not indicated by an "
  6031. "import statement", namespaceName, NULL);
  6032. }
  6033. return (XML_SCHEMAP_SRC_RESOLVE);
  6034. }
  6035. /**
  6036. * xmlSchemaParseLocalAttributes:
  6037. * @ctxt: a schema validation context
  6038. * @schema: the schema being built
  6039. * @node: a subtree containing XML Schema information
  6040. * @type: the hosting type where the attributes will be anchored
  6041. *
  6042. * Parses attribute uses and attribute declarations and
  6043. * attribute group references.
  6044. */
  6045. static int
  6046. xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6047. xmlNodePtr *child, xmlSchemaItemListPtr *list,
  6048. int parentType, int *hasRefs)
  6049. {
  6050. void *item;
  6051. while ((IS_SCHEMA((*child), "attribute")) ||
  6052. (IS_SCHEMA((*child), "attributeGroup"))) {
  6053. if (IS_SCHEMA((*child), "attribute")) {
  6054. item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
  6055. *list, parentType);
  6056. } else {
  6057. item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
  6058. if ((item != NULL) && (hasRefs != NULL))
  6059. *hasRefs = 1;
  6060. }
  6061. if (item != NULL) {
  6062. if (*list == NULL) {
  6063. /* TODO: Customize grow factor. */
  6064. *list = xmlSchemaItemListCreate();
  6065. if (*list == NULL)
  6066. return(-1);
  6067. }
  6068. if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
  6069. return(-1);
  6070. }
  6071. *child = (*child)->next;
  6072. }
  6073. return (0);
  6074. }
  6075. /**
  6076. * xmlSchemaParseAnnotation:
  6077. * @ctxt: a schema validation context
  6078. * @schema: the schema being built
  6079. * @node: a subtree containing XML Schema information
  6080. *
  6081. * parse a XML schema Attribute declaration
  6082. * *WARNING* this interface is highly subject to change
  6083. *
  6084. * Returns -1 in case of error, 0 if the declaration is improper and
  6085. * 1 in case of success.
  6086. */
  6087. static xmlSchemaAnnotPtr
  6088. xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
  6089. {
  6090. xmlSchemaAnnotPtr ret;
  6091. xmlNodePtr child = NULL;
  6092. xmlAttrPtr attr;
  6093. int barked = 0;
  6094. /*
  6095. * INFO: S4S completed.
  6096. */
  6097. /*
  6098. * id = ID
  6099. * {any attributes with non-schema namespace . . .}>
  6100. * Content: (appinfo | documentation)*
  6101. */
  6102. if ((ctxt == NULL) || (node == NULL))
  6103. return (NULL);
  6104. if (needed)
  6105. ret = xmlSchemaNewAnnot(ctxt, node);
  6106. else
  6107. ret = NULL;
  6108. attr = node->properties;
  6109. while (attr != NULL) {
  6110. if (((attr->ns == NULL) &&
  6111. (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
  6112. ((attr->ns != NULL) &&
  6113. xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
  6114. xmlSchemaPIllegalAttrErr(ctxt,
  6115. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6116. }
  6117. attr = attr->next;
  6118. }
  6119. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6120. /*
  6121. * And now for the children...
  6122. */
  6123. child = node->children;
  6124. while (child != NULL) {
  6125. if (IS_SCHEMA(child, "appinfo")) {
  6126. /* TODO: make available the content of "appinfo". */
  6127. /*
  6128. * source = anyURI
  6129. * {any attributes with non-schema namespace . . .}>
  6130. * Content: ({any})*
  6131. */
  6132. attr = child->properties;
  6133. while (attr != NULL) {
  6134. if (((attr->ns == NULL) &&
  6135. (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
  6136. ((attr->ns != NULL) &&
  6137. xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
  6138. xmlSchemaPIllegalAttrErr(ctxt,
  6139. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6140. }
  6141. attr = attr->next;
  6142. }
  6143. xmlSchemaPValAttr(ctxt, NULL, child, "source",
  6144. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
  6145. child = child->next;
  6146. } else if (IS_SCHEMA(child, "documentation")) {
  6147. /* TODO: make available the content of "documentation". */
  6148. /*
  6149. * source = anyURI
  6150. * {any attributes with non-schema namespace . . .}>
  6151. * Content: ({any})*
  6152. */
  6153. attr = child->properties;
  6154. while (attr != NULL) {
  6155. if (attr->ns == NULL) {
  6156. if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
  6157. xmlSchemaPIllegalAttrErr(ctxt,
  6158. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6159. }
  6160. } else {
  6161. if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
  6162. (xmlStrEqual(attr->name, BAD_CAST "lang") &&
  6163. (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
  6164. xmlSchemaPIllegalAttrErr(ctxt,
  6165. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6166. }
  6167. }
  6168. attr = attr->next;
  6169. }
  6170. /*
  6171. * Attribute "xml:lang".
  6172. */
  6173. attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
  6174. if (attr != NULL)
  6175. xmlSchemaPValAttrNode(ctxt, NULL, attr,
  6176. xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
  6177. child = child->next;
  6178. } else {
  6179. if (!barked)
  6180. xmlSchemaPContentErr(ctxt,
  6181. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6182. NULL, node, child, NULL, "(appinfo | documentation)*");
  6183. barked = 1;
  6184. child = child->next;
  6185. }
  6186. }
  6187. return (ret);
  6188. }
  6189. /**
  6190. * xmlSchemaParseFacet:
  6191. * @ctxt: a schema validation context
  6192. * @schema: the schema being built
  6193. * @node: a subtree containing XML Schema information
  6194. *
  6195. * parse a XML schema Facet declaration
  6196. * *WARNING* this interface is highly subject to change
  6197. *
  6198. * Returns the new type structure or NULL in case of error
  6199. */
  6200. static xmlSchemaFacetPtr
  6201. xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6202. xmlNodePtr node)
  6203. {
  6204. xmlSchemaFacetPtr facet;
  6205. xmlNodePtr child = NULL;
  6206. const xmlChar *value;
  6207. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6208. return (NULL);
  6209. facet = xmlSchemaNewFacet();
  6210. if (facet == NULL) {
  6211. xmlSchemaPErrMemory(ctxt, "allocating facet", node);
  6212. return (NULL);
  6213. }
  6214. facet->node = node;
  6215. value = xmlSchemaGetProp(ctxt, node, "value");
  6216. if (value == NULL) {
  6217. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
  6218. "Facet %s has no value\n", node->name, NULL);
  6219. xmlSchemaFreeFacet(facet);
  6220. return (NULL);
  6221. }
  6222. if (IS_SCHEMA(node, "minInclusive")) {
  6223. facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
  6224. } else if (IS_SCHEMA(node, "minExclusive")) {
  6225. facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
  6226. } else if (IS_SCHEMA(node, "maxInclusive")) {
  6227. facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
  6228. } else if (IS_SCHEMA(node, "maxExclusive")) {
  6229. facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
  6230. } else if (IS_SCHEMA(node, "totalDigits")) {
  6231. facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
  6232. } else if (IS_SCHEMA(node, "fractionDigits")) {
  6233. facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
  6234. } else if (IS_SCHEMA(node, "pattern")) {
  6235. facet->type = XML_SCHEMA_FACET_PATTERN;
  6236. } else if (IS_SCHEMA(node, "enumeration")) {
  6237. facet->type = XML_SCHEMA_FACET_ENUMERATION;
  6238. } else if (IS_SCHEMA(node, "whiteSpace")) {
  6239. facet->type = XML_SCHEMA_FACET_WHITESPACE;
  6240. } else if (IS_SCHEMA(node, "length")) {
  6241. facet->type = XML_SCHEMA_FACET_LENGTH;
  6242. } else if (IS_SCHEMA(node, "maxLength")) {
  6243. facet->type = XML_SCHEMA_FACET_MAXLENGTH;
  6244. } else if (IS_SCHEMA(node, "minLength")) {
  6245. facet->type = XML_SCHEMA_FACET_MINLENGTH;
  6246. } else {
  6247. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
  6248. "Unknown facet type %s\n", node->name, NULL);
  6249. xmlSchemaFreeFacet(facet);
  6250. return (NULL);
  6251. }
  6252. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6253. facet->value = value;
  6254. if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
  6255. (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
  6256. const xmlChar *fixed;
  6257. fixed = xmlSchemaGetProp(ctxt, node, "fixed");
  6258. if (fixed != NULL) {
  6259. if (xmlStrEqual(fixed, BAD_CAST "true"))
  6260. facet->fixed = 1;
  6261. }
  6262. }
  6263. child = node->children;
  6264. if (IS_SCHEMA(child, "annotation")) {
  6265. facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6266. child = child->next;
  6267. }
  6268. if (child != NULL) {
  6269. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
  6270. "Facet %s has unexpected child content\n",
  6271. node->name, NULL);
  6272. }
  6273. return (facet);
  6274. }
  6275. /**
  6276. * xmlSchemaParseWildcardNs:
  6277. * @ctxt: a schema parser context
  6278. * @wildc: the wildcard, already created
  6279. * @node: a subtree containing XML Schema information
  6280. *
  6281. * Parses the attribute "processContents" and "namespace"
  6282. * of a xsd:anyAttribute and xsd:any.
  6283. * *WARNING* this interface is highly subject to change
  6284. *
  6285. * Returns 0 if everything goes fine, a positive error code
  6286. * if something is not valid and -1 if an internal error occurs.
  6287. */
  6288. static int
  6289. xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
  6290. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  6291. xmlSchemaWildcardPtr wildc,
  6292. xmlNodePtr node)
  6293. {
  6294. const xmlChar *pc, *ns, *dictnsItem;
  6295. int ret = 0;
  6296. xmlChar *nsItem;
  6297. xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
  6298. xmlAttrPtr attr;
  6299. pc = xmlSchemaGetProp(ctxt, node, "processContents");
  6300. if ((pc == NULL)
  6301. || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
  6302. wildc->processContents = XML_SCHEMAS_ANY_STRICT;
  6303. } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
  6304. wildc->processContents = XML_SCHEMAS_ANY_SKIP;
  6305. } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
  6306. wildc->processContents = XML_SCHEMAS_ANY_LAX;
  6307. } else {
  6308. xmlSchemaPSimpleTypeErr(ctxt,
  6309. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  6310. NULL, node,
  6311. NULL, "(strict | skip | lax)", pc,
  6312. NULL, NULL, NULL);
  6313. wildc->processContents = XML_SCHEMAS_ANY_STRICT;
  6314. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  6315. }
  6316. /*
  6317. * Build the namespace constraints.
  6318. */
  6319. attr = xmlSchemaGetPropNode(node, "namespace");
  6320. ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  6321. if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
  6322. wildc->any = 1;
  6323. else if (xmlStrEqual(ns, BAD_CAST "##other")) {
  6324. wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  6325. if (wildc->negNsSet == NULL) {
  6326. return (-1);
  6327. }
  6328. wildc->negNsSet->value = ctxt->targetNamespace;
  6329. } else {
  6330. const xmlChar *end, *cur;
  6331. cur = ns;
  6332. do {
  6333. while (IS_BLANK_CH(*cur))
  6334. cur++;
  6335. end = cur;
  6336. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  6337. end++;
  6338. if (end == cur)
  6339. break;
  6340. nsItem = xmlStrndup(cur, end - cur);
  6341. if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
  6342. (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
  6343. xmlSchemaPSimpleTypeErr(ctxt,
  6344. XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
  6345. NULL, (xmlNodePtr) attr,
  6346. NULL,
  6347. "((##any | ##other) | List of (xs:anyURI | "
  6348. "(##targetNamespace | ##local)))",
  6349. nsItem, NULL, NULL, NULL);
  6350. ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
  6351. } else {
  6352. if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
  6353. dictnsItem = ctxt->targetNamespace;
  6354. } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
  6355. dictnsItem = NULL;
  6356. } else {
  6357. /*
  6358. * Validate the item (anyURI).
  6359. */
  6360. xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
  6361. nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
  6362. dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
  6363. }
  6364. /*
  6365. * Avoid duplicate namespaces.
  6366. */
  6367. tmp = wildc->nsSet;
  6368. while (tmp != NULL) {
  6369. if (dictnsItem == tmp->value)
  6370. break;
  6371. tmp = tmp->next;
  6372. }
  6373. if (tmp == NULL) {
  6374. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  6375. if (tmp == NULL) {
  6376. xmlFree(nsItem);
  6377. return (-1);
  6378. }
  6379. tmp->value = dictnsItem;
  6380. tmp->next = NULL;
  6381. if (wildc->nsSet == NULL)
  6382. wildc->nsSet = tmp;
  6383. else if (lastNs != NULL)
  6384. lastNs->next = tmp;
  6385. lastNs = tmp;
  6386. }
  6387. }
  6388. xmlFree(nsItem);
  6389. cur = end;
  6390. } while (*cur != 0);
  6391. }
  6392. return (ret);
  6393. }
  6394. static int
  6395. xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
  6396. xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
  6397. xmlNodePtr node,
  6398. int minOccurs,
  6399. int maxOccurs) {
  6400. if ((maxOccurs == 0) && ( minOccurs == 0))
  6401. return (0);
  6402. if (maxOccurs != UNBOUNDED) {
  6403. /*
  6404. * TODO: Maybe we should better not create the particle,
  6405. * if min/max is invalid, since it could confuse the build of the
  6406. * content model.
  6407. */
  6408. /*
  6409. * 3.9.6 Schema Component Constraint: Particle Correct
  6410. *
  6411. */
  6412. if (maxOccurs < 1) {
  6413. /*
  6414. * 2.2 {max occurs} must be greater than or equal to 1.
  6415. */
  6416. xmlSchemaPCustomAttrErr(ctxt,
  6417. XML_SCHEMAP_P_PROPS_CORRECT_2_2,
  6418. NULL, NULL,
  6419. xmlSchemaGetPropNode(node, "maxOccurs"),
  6420. "The value must be greater than or equal to 1");
  6421. return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
  6422. } else if (minOccurs > maxOccurs) {
  6423. /*
  6424. * 2.1 {min occurs} must not be greater than {max occurs}.
  6425. */
  6426. xmlSchemaPCustomAttrErr(ctxt,
  6427. XML_SCHEMAP_P_PROPS_CORRECT_2_1,
  6428. NULL, NULL,
  6429. xmlSchemaGetPropNode(node, "minOccurs"),
  6430. "The value must not be greater than the value of 'maxOccurs'");
  6431. return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
  6432. }
  6433. }
  6434. return (0);
  6435. }
  6436. /**
  6437. * xmlSchemaParseAny:
  6438. * @ctxt: a schema validation context
  6439. * @schema: the schema being built
  6440. * @node: a subtree containing XML Schema information
  6441. *
  6442. * Parsea a XML schema <any> element. A particle and wildcard
  6443. * will be created (except if minOccurs==maxOccurs==0, in this case
  6444. * nothing will be created).
  6445. * *WARNING* this interface is highly subject to change
  6446. *
  6447. * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
  6448. */
  6449. static xmlSchemaParticlePtr
  6450. xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6451. xmlNodePtr node)
  6452. {
  6453. xmlSchemaParticlePtr particle;
  6454. xmlNodePtr child = NULL;
  6455. xmlSchemaWildcardPtr wild;
  6456. int min, max;
  6457. xmlAttrPtr attr;
  6458. xmlSchemaAnnotPtr annot = NULL;
  6459. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6460. return (NULL);
  6461. /*
  6462. * Check for illegal attributes.
  6463. */
  6464. attr = node->properties;
  6465. while (attr != NULL) {
  6466. if (attr->ns == NULL) {
  6467. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  6468. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  6469. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  6470. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  6471. (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
  6472. xmlSchemaPIllegalAttrErr(ctxt,
  6473. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6474. }
  6475. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  6476. xmlSchemaPIllegalAttrErr(ctxt,
  6477. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6478. }
  6479. attr = attr->next;
  6480. }
  6481. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6482. /*
  6483. * minOccurs/maxOccurs.
  6484. */
  6485. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  6486. "(xs:nonNegativeInteger | unbounded)");
  6487. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
  6488. "xs:nonNegativeInteger");
  6489. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  6490. /*
  6491. * Create & parse the wildcard.
  6492. */
  6493. wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
  6494. if (wild == NULL)
  6495. return (NULL);
  6496. xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
  6497. /*
  6498. * And now for the children...
  6499. */
  6500. child = node->children;
  6501. if (IS_SCHEMA(child, "annotation")) {
  6502. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6503. child = child->next;
  6504. }
  6505. if (child != NULL) {
  6506. xmlSchemaPContentErr(ctxt,
  6507. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6508. NULL, node, child,
  6509. NULL, "(annotation?)");
  6510. }
  6511. /*
  6512. * No component if minOccurs==maxOccurs==0.
  6513. */
  6514. if ((min == 0) && (max == 0)) {
  6515. /* Don't free the wildcard, since it's already on the list. */
  6516. return (NULL);
  6517. }
  6518. /*
  6519. * Create the particle.
  6520. */
  6521. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  6522. if (particle == NULL)
  6523. return (NULL);
  6524. particle->annot = annot;
  6525. particle->children = (xmlSchemaTreeItemPtr) wild;
  6526. return (particle);
  6527. }
  6528. /**
  6529. * xmlSchemaParseNotation:
  6530. * @ctxt: a schema validation context
  6531. * @schema: the schema being built
  6532. * @node: a subtree containing XML Schema information
  6533. *
  6534. * parse a XML schema Notation declaration
  6535. *
  6536. * Returns the new structure or NULL in case of error
  6537. */
  6538. static xmlSchemaNotationPtr
  6539. xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6540. xmlNodePtr node)
  6541. {
  6542. const xmlChar *name;
  6543. xmlSchemaNotationPtr ret;
  6544. xmlNodePtr child = NULL;
  6545. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6546. return (NULL);
  6547. name = xmlSchemaGetProp(ctxt, node, "name");
  6548. if (name == NULL) {
  6549. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
  6550. "Notation has no name\n", NULL, NULL);
  6551. return (NULL);
  6552. }
  6553. ret = xmlSchemaAddNotation(ctxt, schema, name,
  6554. ctxt->targetNamespace, node);
  6555. if (ret == NULL)
  6556. return (NULL);
  6557. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6558. child = node->children;
  6559. if (IS_SCHEMA(child, "annotation")) {
  6560. ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6561. child = child->next;
  6562. }
  6563. if (child != NULL) {
  6564. xmlSchemaPContentErr(ctxt,
  6565. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6566. NULL, node, child,
  6567. NULL, "(annotation?)");
  6568. }
  6569. return (ret);
  6570. }
  6571. /**
  6572. * xmlSchemaParseAnyAttribute:
  6573. * @ctxt: a schema validation context
  6574. * @schema: the schema being built
  6575. * @node: a subtree containing XML Schema information
  6576. *
  6577. * parse a XML schema AnyAttribute declaration
  6578. * *WARNING* this interface is highly subject to change
  6579. *
  6580. * Returns a wildcard or NULL.
  6581. */
  6582. static xmlSchemaWildcardPtr
  6583. xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
  6584. xmlSchemaPtr schema, xmlNodePtr node)
  6585. {
  6586. xmlSchemaWildcardPtr ret;
  6587. xmlNodePtr child = NULL;
  6588. xmlAttrPtr attr;
  6589. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6590. return (NULL);
  6591. ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
  6592. node);
  6593. if (ret == NULL) {
  6594. return (NULL);
  6595. }
  6596. /*
  6597. * Check for illegal attributes.
  6598. */
  6599. attr = node->properties;
  6600. while (attr != NULL) {
  6601. if (attr->ns == NULL) {
  6602. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  6603. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  6604. (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
  6605. xmlSchemaPIllegalAttrErr(ctxt,
  6606. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6607. }
  6608. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  6609. xmlSchemaPIllegalAttrErr(ctxt,
  6610. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6611. }
  6612. attr = attr->next;
  6613. }
  6614. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6615. /*
  6616. * Parse the namespace list.
  6617. */
  6618. if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
  6619. return (NULL);
  6620. /*
  6621. * And now for the children...
  6622. */
  6623. child = node->children;
  6624. if (IS_SCHEMA(child, "annotation")) {
  6625. ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6626. child = child->next;
  6627. }
  6628. if (child != NULL) {
  6629. xmlSchemaPContentErr(ctxt,
  6630. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6631. NULL, node, child,
  6632. NULL, "(annotation?)");
  6633. }
  6634. return (ret);
  6635. }
  6636. /**
  6637. * xmlSchemaParseAttribute:
  6638. * @ctxt: a schema validation context
  6639. * @schema: the schema being built
  6640. * @node: a subtree containing XML Schema information
  6641. *
  6642. * parse a XML schema Attribute declaration
  6643. * *WARNING* this interface is highly subject to change
  6644. *
  6645. * Returns the attribute declaration.
  6646. */
  6647. static xmlSchemaBasicItemPtr
  6648. xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
  6649. xmlSchemaPtr schema,
  6650. xmlNodePtr node,
  6651. xmlSchemaItemListPtr uses,
  6652. int parentType)
  6653. {
  6654. const xmlChar *attrValue, *name = NULL, *ns = NULL;
  6655. xmlSchemaAttributeUsePtr use = NULL;
  6656. xmlNodePtr child = NULL;
  6657. xmlAttrPtr attr;
  6658. const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
  6659. int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
  6660. int nberrors, hasForm = 0, defValueType = 0;
  6661. #define WXS_ATTR_DEF_VAL_DEFAULT 1
  6662. #define WXS_ATTR_DEF_VAL_FIXED 2
  6663. /*
  6664. * 3.2.3 Constraints on XML Representations of Attribute Declarations
  6665. */
  6666. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  6667. return (NULL);
  6668. attr = xmlSchemaGetPropNode(node, "ref");
  6669. if (attr != NULL) {
  6670. if (xmlSchemaPValAttrNodeQName(pctxt, schema,
  6671. NULL, attr, &tmpNs, &tmpName) != 0) {
  6672. return (NULL);
  6673. }
  6674. if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
  6675. return(NULL);
  6676. isRef = 1;
  6677. }
  6678. nberrors = pctxt->nberrors;
  6679. /*
  6680. * Check for illegal attributes.
  6681. */
  6682. attr = node->properties;
  6683. while (attr != NULL) {
  6684. if (attr->ns == NULL) {
  6685. if (isRef) {
  6686. if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  6687. xmlSchemaPValAttrNodeID(pctxt, attr);
  6688. goto attr_next;
  6689. } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
  6690. goto attr_next;
  6691. }
  6692. } else {
  6693. if (xmlStrEqual(attr->name, BAD_CAST "name")) {
  6694. goto attr_next;
  6695. } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  6696. xmlSchemaPValAttrNodeID(pctxt, attr);
  6697. goto attr_next;
  6698. } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
  6699. xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
  6700. attr, &tmpNs, &tmpName);
  6701. goto attr_next;
  6702. } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
  6703. /*
  6704. * Evaluate the target namespace
  6705. */
  6706. hasForm = 1;
  6707. attrValue = xmlSchemaGetNodeContent(pctxt,
  6708. (xmlNodePtr) attr);
  6709. if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
  6710. ns = pctxt->targetNamespace;
  6711. } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
  6712. {
  6713. xmlSchemaPSimpleTypeErr(pctxt,
  6714. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  6715. NULL, (xmlNodePtr) attr,
  6716. NULL, "(qualified | unqualified)",
  6717. attrValue, NULL, NULL, NULL);
  6718. }
  6719. goto attr_next;
  6720. }
  6721. }
  6722. if (xmlStrEqual(attr->name, BAD_CAST "use")) {
  6723. attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6724. /* TODO: Maybe we need to normalize the value beforehand. */
  6725. if (xmlStrEqual(attrValue, BAD_CAST "optional"))
  6726. occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
  6727. else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
  6728. occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
  6729. else if (xmlStrEqual(attrValue, BAD_CAST "required"))
  6730. occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
  6731. else {
  6732. xmlSchemaPSimpleTypeErr(pctxt,
  6733. XML_SCHEMAP_INVALID_ATTR_USE,
  6734. NULL, (xmlNodePtr) attr,
  6735. NULL, "(optional | prohibited | required)",
  6736. attrValue, NULL, NULL, NULL);
  6737. }
  6738. goto attr_next;
  6739. } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
  6740. /*
  6741. * 3.2.3 : 1
  6742. * default and fixed must not both be present.
  6743. */
  6744. if (defValue) {
  6745. xmlSchemaPMutualExclAttrErr(pctxt,
  6746. XML_SCHEMAP_SRC_ATTRIBUTE_1,
  6747. NULL, attr, "default", "fixed");
  6748. } else {
  6749. defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6750. defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
  6751. }
  6752. goto attr_next;
  6753. } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
  6754. /*
  6755. * 3.2.3 : 1
  6756. * default and fixed must not both be present.
  6757. */
  6758. if (defValue) {
  6759. xmlSchemaPMutualExclAttrErr(pctxt,
  6760. XML_SCHEMAP_SRC_ATTRIBUTE_1,
  6761. NULL, attr, "default", "fixed");
  6762. } else {
  6763. defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6764. defValueType = WXS_ATTR_DEF_VAL_FIXED;
  6765. }
  6766. goto attr_next;
  6767. }
  6768. } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
  6769. goto attr_next;
  6770. xmlSchemaPIllegalAttrErr(pctxt,
  6771. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6772. attr_next:
  6773. attr = attr->next;
  6774. }
  6775. /*
  6776. * 3.2.3 : 2
  6777. * If default and use are both present, use must have
  6778. * the actual value optional.
  6779. */
  6780. if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
  6781. (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
  6782. xmlSchemaPSimpleTypeErr(pctxt,
  6783. XML_SCHEMAP_SRC_ATTRIBUTE_2,
  6784. NULL, node, NULL,
  6785. "(optional | prohibited | required)", NULL,
  6786. "The value of the attribute 'use' must be 'optional' "
  6787. "if the attribute 'default' is present",
  6788. NULL, NULL);
  6789. }
  6790. /*
  6791. * We want correct attributes.
  6792. */
  6793. if (nberrors != pctxt->nberrors)
  6794. return(NULL);
  6795. if (! isRef) {
  6796. xmlSchemaAttributePtr attrDecl;
  6797. /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
  6798. if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
  6799. ns = pctxt->targetNamespace;
  6800. /*
  6801. * 3.2.6 Schema Component Constraint: xsi: Not Allowed
  6802. * TODO: Move this to the component layer.
  6803. */
  6804. if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
  6805. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  6806. XML_SCHEMAP_NO_XSI,
  6807. node, NULL,
  6808. "The target namespace must not match '%s'",
  6809. xmlSchemaInstanceNs, NULL);
  6810. }
  6811. attr = xmlSchemaGetPropNode(node, "name");
  6812. if (attr == NULL) {
  6813. xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
  6814. NULL, node, "name", NULL);
  6815. return (NULL);
  6816. }
  6817. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  6818. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  6819. return (NULL);
  6820. }
  6821. /*
  6822. * 3.2.6 Schema Component Constraint: xmlns Not Allowed
  6823. * TODO: Move this to the component layer.
  6824. */
  6825. if (xmlStrEqual(name, BAD_CAST "xmlns")) {
  6826. xmlSchemaPSimpleTypeErr(pctxt,
  6827. XML_SCHEMAP_NO_XMLNS,
  6828. NULL, (xmlNodePtr) attr,
  6829. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
  6830. "The value of the attribute must not match 'xmlns'",
  6831. NULL, NULL);
  6832. return (NULL);
  6833. }
  6834. if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
  6835. goto check_children;
  6836. /*
  6837. * Create the attribute use component.
  6838. */
  6839. use = xmlSchemaAddAttributeUse(pctxt, node);
  6840. if (use == NULL)
  6841. return(NULL);
  6842. use->occurs = occurs;
  6843. /*
  6844. * Create the attribute declaration.
  6845. */
  6846. attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
  6847. if (attrDecl == NULL)
  6848. return (NULL);
  6849. if (tmpName != NULL) {
  6850. attrDecl->typeName = tmpName;
  6851. attrDecl->typeNs = tmpNs;
  6852. }
  6853. use->attrDecl = attrDecl;
  6854. /*
  6855. * Value constraint.
  6856. */
  6857. if (defValue != NULL) {
  6858. attrDecl->defValue = defValue;
  6859. if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
  6860. attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
  6861. }
  6862. } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
  6863. xmlSchemaQNameRefPtr ref;
  6864. /*
  6865. * Create the attribute use component.
  6866. */
  6867. use = xmlSchemaAddAttributeUse(pctxt, node);
  6868. if (use == NULL)
  6869. return(NULL);
  6870. /*
  6871. * We need to resolve the reference at later stage.
  6872. */
  6873. WXS_ADD_PENDING(pctxt, use);
  6874. use->occurs = occurs;
  6875. /*
  6876. * Create a QName reference to the attribute declaration.
  6877. */
  6878. ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
  6879. tmpName, tmpNs);
  6880. if (ref == NULL)
  6881. return(NULL);
  6882. /*
  6883. * Assign the reference. This will be substituted for the
  6884. * referenced attribute declaration when the QName is resolved.
  6885. */
  6886. use->attrDecl = WXS_ATTR_CAST ref;
  6887. /*
  6888. * Value constraint.
  6889. */
  6890. if (defValue != NULL)
  6891. use->defValue = defValue;
  6892. if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
  6893. use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
  6894. }
  6895. check_children:
  6896. /*
  6897. * And now for the children...
  6898. */
  6899. child = node->children;
  6900. if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
  6901. xmlSchemaAttributeUseProhibPtr prohib;
  6902. if (IS_SCHEMA(child, "annotation")) {
  6903. xmlSchemaParseAnnotation(pctxt, child, 0);
  6904. child = child->next;
  6905. }
  6906. if (child != NULL) {
  6907. xmlSchemaPContentErr(pctxt,
  6908. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6909. NULL, node, child, NULL,
  6910. "(annotation?)");
  6911. }
  6912. /*
  6913. * Check for pointlessness of attribute prohibitions.
  6914. */
  6915. if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
  6916. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6917. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6918. node, NULL,
  6919. "Skipping attribute use prohibition, since it is "
  6920. "pointless inside an <attributeGroup>",
  6921. NULL, NULL, NULL);
  6922. return(NULL);
  6923. } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
  6924. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6925. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6926. node, NULL,
  6927. "Skipping attribute use prohibition, since it is "
  6928. "pointless when extending a type",
  6929. NULL, NULL, NULL);
  6930. return(NULL);
  6931. }
  6932. if (! isRef) {
  6933. tmpName = name;
  6934. tmpNs = ns;
  6935. }
  6936. /*
  6937. * Check for duplicate attribute prohibitions.
  6938. */
  6939. if (uses) {
  6940. int i;
  6941. for (i = 0; i < uses->nbItems; i++) {
  6942. use = uses->items[i];
  6943. if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
  6944. (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
  6945. (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
  6946. {
  6947. xmlChar *str = NULL;
  6948. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6949. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6950. node, NULL,
  6951. "Skipping duplicate attribute use prohibition '%s'",
  6952. xmlSchemaFormatQName(&str, tmpNs, tmpName),
  6953. NULL, NULL);
  6954. FREE_AND_NULL(str)
  6955. return(NULL);
  6956. }
  6957. }
  6958. }
  6959. /*
  6960. * Create the attribute prohibition helper component.
  6961. */
  6962. prohib = xmlSchemaAddAttributeUseProhib(pctxt);
  6963. if (prohib == NULL)
  6964. return(NULL);
  6965. prohib->node = node;
  6966. prohib->name = tmpName;
  6967. prohib->targetNamespace = tmpNs;
  6968. if (isRef) {
  6969. /*
  6970. * We need at least to resolve to the attribute declaration.
  6971. */
  6972. WXS_ADD_PENDING(pctxt, prohib);
  6973. }
  6974. return(WXS_BASIC_CAST prohib);
  6975. } else {
  6976. if (IS_SCHEMA(child, "annotation")) {
  6977. /*
  6978. * TODO: Should this go into the attr decl?
  6979. */
  6980. use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  6981. child = child->next;
  6982. }
  6983. if (isRef) {
  6984. if (child != NULL) {
  6985. if (IS_SCHEMA(child, "simpleType"))
  6986. /*
  6987. * 3.2.3 : 3.2
  6988. * If ref is present, then all of <simpleType>,
  6989. * form and type must be absent.
  6990. */
  6991. xmlSchemaPContentErr(pctxt,
  6992. XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
  6993. NULL, node, child, NULL,
  6994. "(annotation?)");
  6995. else
  6996. xmlSchemaPContentErr(pctxt,
  6997. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6998. NULL, node, child, NULL,
  6999. "(annotation?)");
  7000. }
  7001. } else {
  7002. if (IS_SCHEMA(child, "simpleType")) {
  7003. if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
  7004. /*
  7005. * 3.2.3 : 4
  7006. * type and <simpleType> must not both be present.
  7007. */
  7008. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
  7009. NULL, node, child,
  7010. "The attribute 'type' and the <simpleType> child "
  7011. "are mutually exclusive", NULL);
  7012. } else
  7013. WXS_ATTRUSE_TYPEDEF(use) =
  7014. xmlSchemaParseSimpleType(pctxt, schema, child, 0);
  7015. child = child->next;
  7016. }
  7017. if (child != NULL)
  7018. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7019. NULL, node, child, NULL,
  7020. "(annotation?, simpleType?)");
  7021. }
  7022. }
  7023. return (WXS_BASIC_CAST use);
  7024. }
  7025. static xmlSchemaAttributePtr
  7026. xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
  7027. xmlSchemaPtr schema,
  7028. xmlNodePtr node)
  7029. {
  7030. const xmlChar *attrValue;
  7031. xmlSchemaAttributePtr ret;
  7032. xmlNodePtr child = NULL;
  7033. xmlAttrPtr attr;
  7034. /*
  7035. * Note that the w3c spec assumes the schema to be validated with schema
  7036. * for schemas beforehand.
  7037. *
  7038. * 3.2.3 Constraints on XML Representations of Attribute Declarations
  7039. */
  7040. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  7041. return (NULL);
  7042. /*
  7043. * 3.2.3 : 3.1
  7044. * One of ref or name must be present, but not both
  7045. */
  7046. attr = xmlSchemaGetPropNode(node, "name");
  7047. if (attr == NULL) {
  7048. xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
  7049. NULL, node, "name", NULL);
  7050. return (NULL);
  7051. }
  7052. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  7053. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
  7054. return (NULL);
  7055. }
  7056. /*
  7057. * 3.2.6 Schema Component Constraint: xmlns Not Allowed
  7058. * TODO: Move this to the component layer.
  7059. */
  7060. if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
  7061. xmlSchemaPSimpleTypeErr(pctxt,
  7062. XML_SCHEMAP_NO_XMLNS,
  7063. NULL, (xmlNodePtr) attr,
  7064. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
  7065. "The value of the attribute must not match 'xmlns'",
  7066. NULL, NULL);
  7067. return (NULL);
  7068. }
  7069. /*
  7070. * 3.2.6 Schema Component Constraint: xsi: Not Allowed
  7071. * TODO: Move this to the component layer.
  7072. * Or better leave it here and add it to the component layer
  7073. * if we have a schema construction API.
  7074. */
  7075. if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
  7076. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  7077. XML_SCHEMAP_NO_XSI, node, NULL,
  7078. "The target namespace must not match '%s'",
  7079. xmlSchemaInstanceNs, NULL);
  7080. }
  7081. ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
  7082. pctxt->targetNamespace, node, 1);
  7083. if (ret == NULL)
  7084. return (NULL);
  7085. ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
  7086. /*
  7087. * Check for illegal attributes.
  7088. */
  7089. attr = node->properties;
  7090. while (attr != NULL) {
  7091. if (attr->ns == NULL) {
  7092. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7093. (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
  7094. (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
  7095. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7096. (!xmlStrEqual(attr->name, BAD_CAST "type")))
  7097. {
  7098. xmlSchemaPIllegalAttrErr(pctxt,
  7099. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7100. }
  7101. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7102. xmlSchemaPIllegalAttrErr(pctxt,
  7103. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7104. }
  7105. attr = attr->next;
  7106. }
  7107. xmlSchemaPValAttrQName(pctxt, schema, NULL,
  7108. node, "type", &ret->typeNs, &ret->typeName);
  7109. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7110. /*
  7111. * Attribute "fixed".
  7112. */
  7113. ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
  7114. if (ret->defValue != NULL)
  7115. ret->flags |= XML_SCHEMAS_ATTR_FIXED;
  7116. /*
  7117. * Attribute "default".
  7118. */
  7119. attr = xmlSchemaGetPropNode(node, "default");
  7120. if (attr != NULL) {
  7121. /*
  7122. * 3.2.3 : 1
  7123. * default and fixed must not both be present.
  7124. */
  7125. if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
  7126. xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
  7127. WXS_BASIC_CAST ret, attr, "default", "fixed");
  7128. } else
  7129. ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  7130. }
  7131. /*
  7132. * And now for the children...
  7133. */
  7134. child = node->children;
  7135. if (IS_SCHEMA(child, "annotation")) {
  7136. ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  7137. child = child->next;
  7138. }
  7139. if (IS_SCHEMA(child, "simpleType")) {
  7140. if (ret->typeName != NULL) {
  7141. /*
  7142. * 3.2.3 : 4
  7143. * type and <simpleType> must not both be present.
  7144. */
  7145. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
  7146. NULL, node, child,
  7147. "The attribute 'type' and the <simpleType> child "
  7148. "are mutually exclusive", NULL);
  7149. } else
  7150. ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
  7151. child = child->next;
  7152. }
  7153. if (child != NULL)
  7154. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7155. NULL, node, child, NULL,
  7156. "(annotation?, simpleType?)");
  7157. return (ret);
  7158. }
  7159. /**
  7160. * xmlSchemaParseAttributeGroupRef:
  7161. * @ctxt: a schema validation context
  7162. * @schema: the schema being built
  7163. * @node: a subtree containing XML Schema information
  7164. *
  7165. * Parse an attribute group definition reference.
  7166. * Note that a reference to an attribute group does not
  7167. * correspond to any component at all.
  7168. * *WARNING* this interface is highly subject to change
  7169. *
  7170. * Returns the attribute group or NULL in case of error.
  7171. */
  7172. static xmlSchemaQNameRefPtr
  7173. xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
  7174. xmlSchemaPtr schema,
  7175. xmlNodePtr node)
  7176. {
  7177. xmlSchemaQNameRefPtr ret;
  7178. xmlNodePtr child = NULL;
  7179. xmlAttrPtr attr;
  7180. const xmlChar *refNs = NULL, *ref = NULL;
  7181. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  7182. return (NULL);
  7183. attr = xmlSchemaGetPropNode(node, "ref");
  7184. if (attr == NULL) {
  7185. xmlSchemaPMissingAttrErr(pctxt,
  7186. XML_SCHEMAP_S4S_ATTR_MISSING,
  7187. NULL, node, "ref", NULL);
  7188. return (NULL);
  7189. }
  7190. xmlSchemaPValAttrNodeQName(pctxt, schema,
  7191. NULL, attr, &refNs, &ref);
  7192. if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
  7193. return(NULL);
  7194. /*
  7195. * Check for illegal attributes.
  7196. */
  7197. attr = node->properties;
  7198. while (attr != NULL) {
  7199. if (attr->ns == NULL) {
  7200. if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
  7201. (!xmlStrEqual(attr->name, BAD_CAST "id")))
  7202. {
  7203. xmlSchemaPIllegalAttrErr(pctxt,
  7204. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7205. }
  7206. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7207. xmlSchemaPIllegalAttrErr(pctxt,
  7208. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7209. }
  7210. attr = attr->next;
  7211. }
  7212. /* Attribute ID */
  7213. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7214. /*
  7215. * And now for the children...
  7216. */
  7217. child = node->children;
  7218. if (IS_SCHEMA(child, "annotation")) {
  7219. /*
  7220. * TODO: We do not have a place to store the annotation, do we?
  7221. */
  7222. xmlSchemaParseAnnotation(pctxt, child, 0);
  7223. child = child->next;
  7224. }
  7225. if (child != NULL) {
  7226. xmlSchemaPContentErr(pctxt,
  7227. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7228. NULL, node, child, NULL,
  7229. "(annotation?)");
  7230. }
  7231. /*
  7232. * Handle attribute group redefinitions.
  7233. */
  7234. if (pctxt->isRedefine && pctxt->redef &&
  7235. (pctxt->redef->item->type ==
  7236. XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
  7237. (ref == pctxt->redef->refName) &&
  7238. (refNs == pctxt->redef->refTargetNs))
  7239. {
  7240. /*
  7241. * SPEC src-redefine:
  7242. * (7.1) "If it has an <attributeGroup> among its contents
  7243. * the `actual value` of whose ref [attribute] is the same
  7244. * as the `actual value` of its own name attribute plus
  7245. * target namespace, then it must have exactly one such group."
  7246. */
  7247. if (pctxt->redefCounter != 0) {
  7248. xmlChar *str = NULL;
  7249. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  7250. XML_SCHEMAP_SRC_REDEFINE, node, NULL,
  7251. "The redefining attribute group definition "
  7252. "'%s' must not contain more than one "
  7253. "reference to the redefined definition",
  7254. xmlSchemaFormatQName(&str, refNs, ref), NULL);
  7255. FREE_AND_NULL(str);
  7256. return(NULL);
  7257. }
  7258. pctxt->redefCounter++;
  7259. /*
  7260. * URGENT TODO: How to ensure that the reference will not be
  7261. * handled by the normal component resolution mechanism?
  7262. */
  7263. ret = xmlSchemaNewQNameRef(pctxt,
  7264. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
  7265. if (ret == NULL)
  7266. return(NULL);
  7267. ret->node = node;
  7268. pctxt->redef->reference = WXS_BASIC_CAST ret;
  7269. } else {
  7270. /*
  7271. * Create a QName-reference helper component. We will substitute this
  7272. * component for the attribute uses of the referenced attribute group
  7273. * definition.
  7274. */
  7275. ret = xmlSchemaNewQNameRef(pctxt,
  7276. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
  7277. if (ret == NULL)
  7278. return(NULL);
  7279. ret->node = node;
  7280. /* Add to pending items, to be able to resolve the reference. */
  7281. WXS_ADD_PENDING(pctxt, ret);
  7282. }
  7283. return (ret);
  7284. }
  7285. /**
  7286. * xmlSchemaParseAttributeGroupDefinition:
  7287. * @pctxt: a schema validation context
  7288. * @schema: the schema being built
  7289. * @node: a subtree containing XML Schema information
  7290. *
  7291. * parse a XML schema Attribute Group declaration
  7292. * *WARNING* this interface is highly subject to change
  7293. *
  7294. * Returns the attribute group definition or NULL in case of error.
  7295. */
  7296. static xmlSchemaAttributeGroupPtr
  7297. xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
  7298. xmlSchemaPtr schema,
  7299. xmlNodePtr node)
  7300. {
  7301. const xmlChar *name;
  7302. xmlSchemaAttributeGroupPtr ret;
  7303. xmlNodePtr child = NULL;
  7304. xmlAttrPtr attr;
  7305. int hasRefs = 0;
  7306. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  7307. return (NULL);
  7308. attr = xmlSchemaGetPropNode(node, "name");
  7309. if (attr == NULL) {
  7310. xmlSchemaPMissingAttrErr(pctxt,
  7311. XML_SCHEMAP_S4S_ATTR_MISSING,
  7312. NULL, node, "name", NULL);
  7313. return (NULL);
  7314. }
  7315. /*
  7316. * The name is crucial, exit if invalid.
  7317. */
  7318. if (xmlSchemaPValAttrNode(pctxt,
  7319. NULL, attr,
  7320. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  7321. return (NULL);
  7322. }
  7323. ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
  7324. name, pctxt->targetNamespace, node);
  7325. if (ret == NULL)
  7326. return (NULL);
  7327. /*
  7328. * Check for illegal attributes.
  7329. */
  7330. attr = node->properties;
  7331. while (attr != NULL) {
  7332. if (attr->ns == NULL) {
  7333. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7334. (!xmlStrEqual(attr->name, BAD_CAST "id")))
  7335. {
  7336. xmlSchemaPIllegalAttrErr(pctxt,
  7337. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7338. }
  7339. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7340. xmlSchemaPIllegalAttrErr(pctxt,
  7341. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7342. }
  7343. attr = attr->next;
  7344. }
  7345. /* Attribute ID */
  7346. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7347. /*
  7348. * And now for the children...
  7349. */
  7350. child = node->children;
  7351. if (IS_SCHEMA(child, "annotation")) {
  7352. ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  7353. child = child->next;
  7354. }
  7355. /*
  7356. * Parse contained attribute decls/refs.
  7357. */
  7358. if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
  7359. (xmlSchemaItemListPtr *) &(ret->attrUses),
  7360. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
  7361. return(NULL);
  7362. if (hasRefs)
  7363. ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
  7364. /*
  7365. * Parse the attribute wildcard.
  7366. */
  7367. if (IS_SCHEMA(child, "anyAttribute")) {
  7368. ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
  7369. schema, child);
  7370. child = child->next;
  7371. }
  7372. if (child != NULL) {
  7373. xmlSchemaPContentErr(pctxt,
  7374. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7375. NULL, node, child, NULL,
  7376. "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
  7377. }
  7378. return (ret);
  7379. }
  7380. /**
  7381. * xmlSchemaPValAttrFormDefault:
  7382. * @value: the value
  7383. * @flags: the flags to be modified
  7384. * @flagQualified: the specific flag for "qualified"
  7385. *
  7386. * Returns 0 if the value is valid, 1 otherwise.
  7387. */
  7388. static int
  7389. xmlSchemaPValAttrFormDefault(const xmlChar *value,
  7390. int *flags,
  7391. int flagQualified)
  7392. {
  7393. if (xmlStrEqual(value, BAD_CAST "qualified")) {
  7394. if ((*flags & flagQualified) == 0)
  7395. *flags |= flagQualified;
  7396. } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
  7397. return (1);
  7398. return (0);
  7399. }
  7400. /**
  7401. * xmlSchemaPValAttrBlockFinal:
  7402. * @value: the value
  7403. * @flags: the flags to be modified
  7404. * @flagAll: the specific flag for "#all"
  7405. * @flagExtension: the specific flag for "extension"
  7406. * @flagRestriction: the specific flag for "restriction"
  7407. * @flagSubstitution: the specific flag for "substitution"
  7408. * @flagList: the specific flag for "list"
  7409. * @flagUnion: the specific flag for "union"
  7410. *
  7411. * Validates the value of the attribute "final" and "block". The value
  7412. * is converted into the specified flag values and returned in @flags.
  7413. *
  7414. * Returns 0 if the value is valid, 1 otherwise.
  7415. */
  7416. static int
  7417. xmlSchemaPValAttrBlockFinal(const xmlChar *value,
  7418. int *flags,
  7419. int flagAll,
  7420. int flagExtension,
  7421. int flagRestriction,
  7422. int flagSubstitution,
  7423. int flagList,
  7424. int flagUnion)
  7425. {
  7426. int ret = 0;
  7427. /*
  7428. * TODO: This does not check for duplicate entries.
  7429. */
  7430. if ((flags == NULL) || (value == NULL))
  7431. return (-1);
  7432. if (value[0] == 0)
  7433. return (0);
  7434. if (xmlStrEqual(value, BAD_CAST "#all")) {
  7435. if (flagAll != -1)
  7436. *flags |= flagAll;
  7437. else {
  7438. if (flagExtension != -1)
  7439. *flags |= flagExtension;
  7440. if (flagRestriction != -1)
  7441. *flags |= flagRestriction;
  7442. if (flagSubstitution != -1)
  7443. *flags |= flagSubstitution;
  7444. if (flagList != -1)
  7445. *flags |= flagList;
  7446. if (flagUnion != -1)
  7447. *flags |= flagUnion;
  7448. }
  7449. } else {
  7450. const xmlChar *end, *cur = value;
  7451. xmlChar *item;
  7452. do {
  7453. while (IS_BLANK_CH(*cur))
  7454. cur++;
  7455. end = cur;
  7456. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  7457. end++;
  7458. if (end == cur)
  7459. break;
  7460. item = xmlStrndup(cur, end - cur);
  7461. if (xmlStrEqual(item, BAD_CAST "extension")) {
  7462. if (flagExtension != -1) {
  7463. if ((*flags & flagExtension) == 0)
  7464. *flags |= flagExtension;
  7465. } else
  7466. ret = 1;
  7467. } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
  7468. if (flagRestriction != -1) {
  7469. if ((*flags & flagRestriction) == 0)
  7470. *flags |= flagRestriction;
  7471. } else
  7472. ret = 1;
  7473. } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
  7474. if (flagSubstitution != -1) {
  7475. if ((*flags & flagSubstitution) == 0)
  7476. *flags |= flagSubstitution;
  7477. } else
  7478. ret = 1;
  7479. } else if (xmlStrEqual(item, BAD_CAST "list")) {
  7480. if (flagList != -1) {
  7481. if ((*flags & flagList) == 0)
  7482. *flags |= flagList;
  7483. } else
  7484. ret = 1;
  7485. } else if (xmlStrEqual(item, BAD_CAST "union")) {
  7486. if (flagUnion != -1) {
  7487. if ((*flags & flagUnion) == 0)
  7488. *flags |= flagUnion;
  7489. } else
  7490. ret = 1;
  7491. } else
  7492. ret = 1;
  7493. if (item != NULL)
  7494. xmlFree(item);
  7495. cur = end;
  7496. } while ((ret == 0) && (*cur != 0));
  7497. }
  7498. return (ret);
  7499. }
  7500. static int
  7501. xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
  7502. xmlSchemaIDCPtr idc,
  7503. xmlSchemaIDCSelectPtr selector,
  7504. xmlAttrPtr attr,
  7505. int isField)
  7506. {
  7507. xmlNodePtr node;
  7508. /*
  7509. * c-selector-xpath:
  7510. * Schema Component Constraint: Selector Value OK
  7511. *
  7512. * TODO: 1 The {selector} must be a valid XPath expression, as defined
  7513. * in [XPath].
  7514. */
  7515. if (selector == NULL) {
  7516. xmlSchemaPErr(ctxt, idc->node,
  7517. XML_SCHEMAP_INTERNAL,
  7518. "Internal error: xmlSchemaCheckCSelectorXPath, "
  7519. "the selector is not specified.\n", NULL, NULL);
  7520. return (-1);
  7521. }
  7522. if (attr == NULL)
  7523. node = idc->node;
  7524. else
  7525. node = (xmlNodePtr) attr;
  7526. if (selector->xpath == NULL) {
  7527. xmlSchemaPCustomErr(ctxt,
  7528. /* TODO: Adjust error code. */
  7529. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  7530. NULL, node,
  7531. "The XPath expression of the selector is not valid", NULL);
  7532. return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
  7533. } else {
  7534. const xmlChar **nsArray = NULL;
  7535. xmlNsPtr *nsList = NULL;
  7536. /*
  7537. * Compile the XPath expression.
  7538. */
  7539. /*
  7540. * TODO: We need the array of in-scope namespaces for compilation.
  7541. * TODO: Call xmlPatterncompile with different options for selector/
  7542. * field.
  7543. */
  7544. if (attr == NULL)
  7545. nsList = NULL;
  7546. else
  7547. nsList = xmlGetNsList(attr->doc, attr->parent);
  7548. /*
  7549. * Build an array of prefixes and namespaces.
  7550. */
  7551. if (nsList != NULL) {
  7552. int i, count = 0;
  7553. for (i = 0; nsList[i] != NULL; i++)
  7554. count++;
  7555. nsArray = (const xmlChar **) xmlMalloc(
  7556. (count * 2 + 1) * sizeof(const xmlChar *));
  7557. if (nsArray == NULL) {
  7558. xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
  7559. NULL);
  7560. xmlFree(nsList);
  7561. return (-1);
  7562. }
  7563. for (i = 0; i < count; i++) {
  7564. nsArray[2 * i] = nsList[i]->href;
  7565. nsArray[2 * i + 1] = nsList[i]->prefix;
  7566. }
  7567. nsArray[count * 2] = NULL;
  7568. xmlFree(nsList);
  7569. }
  7570. /*
  7571. * TODO: Differentiate between "selector" and "field".
  7572. */
  7573. if (isField)
  7574. selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
  7575. NULL, XML_PATTERN_XSFIELD, nsArray);
  7576. else
  7577. selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
  7578. NULL, XML_PATTERN_XSSEL, nsArray);
  7579. if (nsArray != NULL)
  7580. xmlFree((xmlChar **) nsArray);
  7581. if (selector->xpathComp == NULL) {
  7582. xmlSchemaPCustomErr(ctxt,
  7583. /* TODO: Adjust error code? */
  7584. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  7585. NULL, node,
  7586. "The XPath expression '%s' could not be "
  7587. "compiled", selector->xpath);
  7588. return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
  7589. }
  7590. }
  7591. return (0);
  7592. }
  7593. #define ADD_ANNOTATION(annot) \
  7594. xmlSchemaAnnotPtr cur = item->annot; \
  7595. if (item->annot == NULL) { \
  7596. item->annot = annot; \
  7597. return (annot); \
  7598. } \
  7599. cur = item->annot; \
  7600. if (cur->next != NULL) { \
  7601. cur = cur->next; \
  7602. } \
  7603. cur->next = annot;
  7604. /**
  7605. * xmlSchemaAssignAnnotation:
  7606. * @item: the schema component
  7607. * @annot: the annotation
  7608. *
  7609. * Adds the annotation to the given schema component.
  7610. *
  7611. * Returns the given annotation.
  7612. */
  7613. static xmlSchemaAnnotPtr
  7614. xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
  7615. xmlSchemaAnnotPtr annot)
  7616. {
  7617. if ((annItem == NULL) || (annot == NULL))
  7618. return (NULL);
  7619. switch (annItem->type) {
  7620. case XML_SCHEMA_TYPE_ELEMENT: {
  7621. xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
  7622. ADD_ANNOTATION(annot)
  7623. }
  7624. break;
  7625. case XML_SCHEMA_TYPE_ATTRIBUTE: {
  7626. xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
  7627. ADD_ANNOTATION(annot)
  7628. }
  7629. break;
  7630. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  7631. case XML_SCHEMA_TYPE_ANY: {
  7632. xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
  7633. ADD_ANNOTATION(annot)
  7634. }
  7635. break;
  7636. case XML_SCHEMA_TYPE_PARTICLE:
  7637. case XML_SCHEMA_TYPE_IDC_KEY:
  7638. case XML_SCHEMA_TYPE_IDC_KEYREF:
  7639. case XML_SCHEMA_TYPE_IDC_UNIQUE: {
  7640. xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
  7641. ADD_ANNOTATION(annot)
  7642. }
  7643. break;
  7644. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
  7645. xmlSchemaAttributeGroupPtr item =
  7646. (xmlSchemaAttributeGroupPtr) annItem;
  7647. ADD_ANNOTATION(annot)
  7648. }
  7649. break;
  7650. case XML_SCHEMA_TYPE_NOTATION: {
  7651. xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
  7652. ADD_ANNOTATION(annot)
  7653. }
  7654. break;
  7655. case XML_SCHEMA_FACET_MININCLUSIVE:
  7656. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  7657. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  7658. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  7659. case XML_SCHEMA_FACET_TOTALDIGITS:
  7660. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  7661. case XML_SCHEMA_FACET_PATTERN:
  7662. case XML_SCHEMA_FACET_ENUMERATION:
  7663. case XML_SCHEMA_FACET_WHITESPACE:
  7664. case XML_SCHEMA_FACET_LENGTH:
  7665. case XML_SCHEMA_FACET_MAXLENGTH:
  7666. case XML_SCHEMA_FACET_MINLENGTH: {
  7667. xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
  7668. ADD_ANNOTATION(annot)
  7669. }
  7670. break;
  7671. case XML_SCHEMA_TYPE_SIMPLE:
  7672. case XML_SCHEMA_TYPE_COMPLEX: {
  7673. xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
  7674. ADD_ANNOTATION(annot)
  7675. }
  7676. break;
  7677. case XML_SCHEMA_TYPE_GROUP: {
  7678. xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
  7679. ADD_ANNOTATION(annot)
  7680. }
  7681. break;
  7682. case XML_SCHEMA_TYPE_SEQUENCE:
  7683. case XML_SCHEMA_TYPE_CHOICE:
  7684. case XML_SCHEMA_TYPE_ALL: {
  7685. xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
  7686. ADD_ANNOTATION(annot)
  7687. }
  7688. break;
  7689. default:
  7690. xmlSchemaPCustomErr(NULL,
  7691. XML_SCHEMAP_INTERNAL,
  7692. NULL, NULL,
  7693. "Internal error: xmlSchemaAddAnnotation, "
  7694. "The item is not a annotated schema component", NULL);
  7695. break;
  7696. }
  7697. return (annot);
  7698. }
  7699. /**
  7700. * xmlSchemaParseIDCSelectorAndField:
  7701. * @ctxt: a schema validation context
  7702. * @schema: the schema being built
  7703. * @node: a subtree containing XML Schema information
  7704. *
  7705. * Parses a XML Schema identity-constraint definition's
  7706. * <selector> and <field> elements.
  7707. *
  7708. * Returns the parsed identity-constraint definition.
  7709. */
  7710. static xmlSchemaIDCSelectPtr
  7711. xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
  7712. xmlSchemaIDCPtr idc,
  7713. xmlNodePtr node,
  7714. int isField)
  7715. {
  7716. xmlSchemaIDCSelectPtr item;
  7717. xmlNodePtr child = NULL;
  7718. xmlAttrPtr attr;
  7719. /*
  7720. * Check for illegal attributes.
  7721. */
  7722. attr = node->properties;
  7723. while (attr != NULL) {
  7724. if (attr->ns == NULL) {
  7725. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7726. (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
  7727. xmlSchemaPIllegalAttrErr(ctxt,
  7728. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7729. }
  7730. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7731. xmlSchemaPIllegalAttrErr(ctxt,
  7732. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7733. }
  7734. attr = attr->next;
  7735. }
  7736. /*
  7737. * Create the item.
  7738. */
  7739. item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
  7740. if (item == NULL) {
  7741. xmlSchemaPErrMemory(ctxt,
  7742. "allocating a 'selector' of an identity-constraint definition",
  7743. NULL);
  7744. return (NULL);
  7745. }
  7746. memset(item, 0, sizeof(xmlSchemaIDCSelect));
  7747. /*
  7748. * Attribute "xpath" (mandatory).
  7749. */
  7750. attr = xmlSchemaGetPropNode(node, "xpath");
  7751. if (attr == NULL) {
  7752. xmlSchemaPMissingAttrErr(ctxt,
  7753. XML_SCHEMAP_S4S_ATTR_MISSING,
  7754. NULL, node,
  7755. "name", NULL);
  7756. } else {
  7757. item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  7758. /*
  7759. * URGENT TODO: "field"s have an other syntax than "selector"s.
  7760. */
  7761. if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
  7762. isField) == -1) {
  7763. xmlSchemaPErr(ctxt,
  7764. (xmlNodePtr) attr,
  7765. XML_SCHEMAP_INTERNAL,
  7766. "Internal error: xmlSchemaParseIDCSelectorAndField, "
  7767. "validating the XPath expression of a IDC selector.\n",
  7768. NULL, NULL);
  7769. }
  7770. }
  7771. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7772. /*
  7773. * And now for the children...
  7774. */
  7775. child = node->children;
  7776. if (IS_SCHEMA(child, "annotation")) {
  7777. /*
  7778. * Add the annotation to the parent IDC.
  7779. */
  7780. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
  7781. xmlSchemaParseAnnotation(ctxt, child, 1));
  7782. child = child->next;
  7783. }
  7784. if (child != NULL) {
  7785. xmlSchemaPContentErr(ctxt,
  7786. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7787. NULL, node, child,
  7788. NULL, "(annotation?)");
  7789. }
  7790. return (item);
  7791. }
  7792. /**
  7793. * xmlSchemaParseIDC:
  7794. * @ctxt: a schema validation context
  7795. * @schema: the schema being built
  7796. * @node: a subtree containing XML Schema information
  7797. *
  7798. * Parses a XML Schema identity-constraint definition.
  7799. *
  7800. * Returns the parsed identity-constraint definition.
  7801. */
  7802. static xmlSchemaIDCPtr
  7803. xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
  7804. xmlSchemaPtr schema,
  7805. xmlNodePtr node,
  7806. xmlSchemaTypeType idcCategory,
  7807. const xmlChar *targetNamespace)
  7808. {
  7809. xmlSchemaIDCPtr item = NULL;
  7810. xmlNodePtr child = NULL;
  7811. xmlAttrPtr attr;
  7812. const xmlChar *name = NULL;
  7813. xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
  7814. /*
  7815. * Check for illegal attributes.
  7816. */
  7817. attr = node->properties;
  7818. while (attr != NULL) {
  7819. if (attr->ns == NULL) {
  7820. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7821. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7822. ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
  7823. (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
  7824. xmlSchemaPIllegalAttrErr(ctxt,
  7825. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7826. }
  7827. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7828. xmlSchemaPIllegalAttrErr(ctxt,
  7829. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7830. }
  7831. attr = attr->next;
  7832. }
  7833. /*
  7834. * Attribute "name" (mandatory).
  7835. */
  7836. attr = xmlSchemaGetPropNode(node, "name");
  7837. if (attr == NULL) {
  7838. xmlSchemaPMissingAttrErr(ctxt,
  7839. XML_SCHEMAP_S4S_ATTR_MISSING,
  7840. NULL, node,
  7841. "name", NULL);
  7842. return (NULL);
  7843. } else if (xmlSchemaPValAttrNode(ctxt,
  7844. NULL, attr,
  7845. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  7846. return (NULL);
  7847. }
  7848. /* Create the component. */
  7849. item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
  7850. idcCategory, node);
  7851. if (item == NULL)
  7852. return(NULL);
  7853. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7854. if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
  7855. /*
  7856. * Attribute "refer" (mandatory).
  7857. */
  7858. attr = xmlSchemaGetPropNode(node, "refer");
  7859. if (attr == NULL) {
  7860. xmlSchemaPMissingAttrErr(ctxt,
  7861. XML_SCHEMAP_S4S_ATTR_MISSING,
  7862. NULL, node,
  7863. "refer", NULL);
  7864. } else {
  7865. /*
  7866. * Create a reference item.
  7867. */
  7868. item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
  7869. NULL, NULL);
  7870. if (item->ref == NULL)
  7871. return (NULL);
  7872. xmlSchemaPValAttrNodeQName(ctxt, schema,
  7873. NULL, attr,
  7874. &(item->ref->targetNamespace),
  7875. &(item->ref->name));
  7876. xmlSchemaCheckReference(ctxt, schema, node, attr,
  7877. item->ref->targetNamespace);
  7878. }
  7879. }
  7880. /*
  7881. * And now for the children...
  7882. */
  7883. child = node->children;
  7884. if (IS_SCHEMA(child, "annotation")) {
  7885. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  7886. child = child->next;
  7887. }
  7888. if (child == NULL) {
  7889. xmlSchemaPContentErr(ctxt,
  7890. XML_SCHEMAP_S4S_ELEM_MISSING,
  7891. NULL, node, child,
  7892. "A child element is missing",
  7893. "(annotation?, (selector, field+))");
  7894. }
  7895. /*
  7896. * Child element <selector>.
  7897. */
  7898. if (IS_SCHEMA(child, "selector")) {
  7899. item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
  7900. item, child, 0);
  7901. child = child->next;
  7902. /*
  7903. * Child elements <field>.
  7904. */
  7905. if (IS_SCHEMA(child, "field")) {
  7906. do {
  7907. field = xmlSchemaParseIDCSelectorAndField(ctxt,
  7908. item, child, 1);
  7909. if (field != NULL) {
  7910. field->index = item->nbFields;
  7911. item->nbFields++;
  7912. if (lastField != NULL)
  7913. lastField->next = field;
  7914. else
  7915. item->fields = field;
  7916. lastField = field;
  7917. }
  7918. child = child->next;
  7919. } while (IS_SCHEMA(child, "field"));
  7920. } else {
  7921. xmlSchemaPContentErr(ctxt,
  7922. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7923. NULL, node, child,
  7924. NULL, "(annotation?, (selector, field+))");
  7925. }
  7926. }
  7927. if (child != NULL) {
  7928. xmlSchemaPContentErr(ctxt,
  7929. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7930. NULL, node, child,
  7931. NULL, "(annotation?, (selector, field+))");
  7932. }
  7933. return (item);
  7934. }
  7935. /**
  7936. * xmlSchemaParseElement:
  7937. * @ctxt: a schema validation context
  7938. * @schema: the schema being built
  7939. * @node: a subtree containing XML Schema information
  7940. * @topLevel: indicates if this is global declaration
  7941. *
  7942. * Parses a XML schema element declaration.
  7943. * *WARNING* this interface is highly subject to change
  7944. *
  7945. * Returns the element declaration or a particle; NULL in case
  7946. * of an error or if the particle has minOccurs==maxOccurs==0.
  7947. */
  7948. static xmlSchemaBasicItemPtr
  7949. xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  7950. xmlNodePtr node, int *isElemRef, int topLevel)
  7951. {
  7952. xmlSchemaElementPtr decl = NULL;
  7953. xmlSchemaParticlePtr particle = NULL;
  7954. xmlSchemaAnnotPtr annot = NULL;
  7955. xmlNodePtr child = NULL;
  7956. xmlAttrPtr attr, nameAttr;
  7957. int min, max, isRef = 0;
  7958. xmlChar *des = NULL;
  7959. /* 3.3.3 Constraints on XML Representations of Element Declarations */
  7960. /* TODO: Complete implementation of 3.3.6 */
  7961. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  7962. return (NULL);
  7963. if (isElemRef != NULL)
  7964. *isElemRef = 0;
  7965. /*
  7966. * If we get a "ref" attribute on a local <element> we will assume it's
  7967. * a reference - even if there's a "name" attribute; this seems to be more
  7968. * robust.
  7969. */
  7970. nameAttr = xmlSchemaGetPropNode(node, "name");
  7971. attr = xmlSchemaGetPropNode(node, "ref");
  7972. if ((topLevel) || (attr == NULL)) {
  7973. if (nameAttr == NULL) {
  7974. xmlSchemaPMissingAttrErr(ctxt,
  7975. XML_SCHEMAP_S4S_ATTR_MISSING,
  7976. NULL, node, "name", NULL);
  7977. return (NULL);
  7978. }
  7979. } else
  7980. isRef = 1;
  7981. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7982. child = node->children;
  7983. if (IS_SCHEMA(child, "annotation")) {
  7984. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  7985. child = child->next;
  7986. }
  7987. /*
  7988. * Skip particle part if a global declaration.
  7989. */
  7990. if (topLevel)
  7991. goto declaration_part;
  7992. /*
  7993. * The particle part ==================================================
  7994. */
  7995. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  7996. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
  7997. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  7998. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  7999. if (particle == NULL)
  8000. goto return_null;
  8001. /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
  8002. if (isRef) {
  8003. const xmlChar *refNs = NULL, *ref = NULL;
  8004. xmlSchemaQNameRefPtr refer = NULL;
  8005. /*
  8006. * The reference part =============================================
  8007. */
  8008. if (isElemRef != NULL)
  8009. *isElemRef = 1;
  8010. xmlSchemaPValAttrNodeQName(ctxt, schema,
  8011. NULL, attr, &refNs, &ref);
  8012. xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
  8013. /*
  8014. * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
  8015. */
  8016. if (nameAttr != NULL) {
  8017. xmlSchemaPMutualExclAttrErr(ctxt,
  8018. XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
  8019. }
  8020. /*
  8021. * Check for illegal attributes.
  8022. */
  8023. attr = node->properties;
  8024. while (attr != NULL) {
  8025. if (attr->ns == NULL) {
  8026. if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
  8027. xmlStrEqual(attr->name, BAD_CAST "name") ||
  8028. xmlStrEqual(attr->name, BAD_CAST "id") ||
  8029. xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
  8030. xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
  8031. {
  8032. attr = attr->next;
  8033. continue;
  8034. } else {
  8035. /* SPEC (3.3.3 : 2.2) */
  8036. xmlSchemaPCustomAttrErr(ctxt,
  8037. XML_SCHEMAP_SRC_ELEMENT_2_2,
  8038. NULL, NULL, attr,
  8039. "Only the attributes 'minOccurs', 'maxOccurs' and "
  8040. "'id' are allowed in addition to 'ref'");
  8041. break;
  8042. }
  8043. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8044. xmlSchemaPIllegalAttrErr(ctxt,
  8045. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8046. }
  8047. attr = attr->next;
  8048. }
  8049. /*
  8050. * No children except <annotation> expected.
  8051. */
  8052. if (child != NULL) {
  8053. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8054. NULL, node, child, NULL, "(annotation?)");
  8055. }
  8056. if ((min == 0) && (max == 0))
  8057. goto return_null;
  8058. /*
  8059. * Create the reference item and attach it to the particle.
  8060. */
  8061. refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
  8062. ref, refNs);
  8063. if (refer == NULL)
  8064. goto return_null;
  8065. particle->children = (xmlSchemaTreeItemPtr) refer;
  8066. particle->annot = annot;
  8067. /*
  8068. * Add the particle to pending components, since the reference
  8069. * need to be resolved.
  8070. */
  8071. WXS_ADD_PENDING(ctxt, particle);
  8072. return ((xmlSchemaBasicItemPtr) particle);
  8073. }
  8074. /*
  8075. * The declaration part ===============================================
  8076. */
  8077. declaration_part:
  8078. {
  8079. const xmlChar *ns = NULL, *fixed, *name, *attrValue;
  8080. xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
  8081. if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
  8082. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
  8083. goto return_null;
  8084. /*
  8085. * Evaluate the target namespace.
  8086. */
  8087. if (topLevel) {
  8088. ns = ctxt->targetNamespace;
  8089. } else {
  8090. attr = xmlSchemaGetPropNode(node, "form");
  8091. if (attr != NULL) {
  8092. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8093. if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
  8094. ns = ctxt->targetNamespace;
  8095. } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
  8096. xmlSchemaPSimpleTypeErr(ctxt,
  8097. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8098. NULL, (xmlNodePtr) attr,
  8099. NULL, "(qualified | unqualified)",
  8100. attrValue, NULL, NULL, NULL);
  8101. }
  8102. } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
  8103. ns = ctxt->targetNamespace;
  8104. }
  8105. decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
  8106. if (decl == NULL) {
  8107. goto return_null;
  8108. }
  8109. /*
  8110. * Check for illegal attributes.
  8111. */
  8112. attr = node->properties;
  8113. while (attr != NULL) {
  8114. if (attr->ns == NULL) {
  8115. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8116. (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
  8117. (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8118. (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
  8119. (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
  8120. (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
  8121. (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
  8122. {
  8123. if (topLevel == 0) {
  8124. if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  8125. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  8126. (!xmlStrEqual(attr->name, BAD_CAST "form")))
  8127. {
  8128. xmlSchemaPIllegalAttrErr(ctxt,
  8129. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8130. }
  8131. } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
  8132. (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
  8133. (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
  8134. xmlSchemaPIllegalAttrErr(ctxt,
  8135. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8136. }
  8137. }
  8138. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8139. xmlSchemaPIllegalAttrErr(ctxt,
  8140. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8141. }
  8142. attr = attr->next;
  8143. }
  8144. /*
  8145. * Extract/validate attributes.
  8146. */
  8147. if (topLevel) {
  8148. /*
  8149. * Process top attributes of global element declarations here.
  8150. */
  8151. decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
  8152. decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
  8153. xmlSchemaPValAttrQName(ctxt, schema,
  8154. NULL, node, "substitutionGroup",
  8155. &(decl->substGroupNs), &(decl->substGroup));
  8156. if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
  8157. decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
  8158. /*
  8159. * Attribute "final".
  8160. */
  8161. attr = xmlSchemaGetPropNode(node, "final");
  8162. if (attr == NULL) {
  8163. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  8164. decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
  8165. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8166. decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
  8167. } else {
  8168. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8169. if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
  8170. -1,
  8171. XML_SCHEMAS_ELEM_FINAL_EXTENSION,
  8172. XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
  8173. xmlSchemaPSimpleTypeErr(ctxt,
  8174. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8175. NULL, (xmlNodePtr) attr,
  8176. NULL, "(#all | List of (extension | restriction))",
  8177. attrValue, NULL, NULL, NULL);
  8178. }
  8179. }
  8180. }
  8181. /*
  8182. * Attribute "block".
  8183. */
  8184. attr = xmlSchemaGetPropNode(node, "block");
  8185. if (attr == NULL) {
  8186. /*
  8187. * Apply default "block" values.
  8188. */
  8189. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  8190. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
  8191. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  8192. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
  8193. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
  8194. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
  8195. } else {
  8196. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8197. if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
  8198. -1,
  8199. XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
  8200. XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
  8201. XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
  8202. xmlSchemaPSimpleTypeErr(ctxt,
  8203. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8204. NULL, (xmlNodePtr) attr,
  8205. NULL, "(#all | List of (extension | "
  8206. "restriction | substitution))", attrValue,
  8207. NULL, NULL, NULL);
  8208. }
  8209. }
  8210. if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
  8211. decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
  8212. attr = xmlSchemaGetPropNode(node, "type");
  8213. if (attr != NULL) {
  8214. xmlSchemaPValAttrNodeQName(ctxt, schema,
  8215. NULL, attr,
  8216. &(decl->namedTypeNs), &(decl->namedType));
  8217. xmlSchemaCheckReference(ctxt, schema, node,
  8218. attr, decl->namedTypeNs);
  8219. }
  8220. decl->value = xmlSchemaGetProp(ctxt, node, "default");
  8221. attr = xmlSchemaGetPropNode(node, "fixed");
  8222. if (attr != NULL) {
  8223. fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8224. if (decl->value != NULL) {
  8225. /*
  8226. * 3.3.3 : 1
  8227. * default and fixed must not both be present.
  8228. */
  8229. xmlSchemaPMutualExclAttrErr(ctxt,
  8230. XML_SCHEMAP_SRC_ELEMENT_1,
  8231. NULL, attr, "default", "fixed");
  8232. } else {
  8233. decl->flags |= XML_SCHEMAS_ELEM_FIXED;
  8234. decl->value = fixed;
  8235. }
  8236. }
  8237. /*
  8238. * And now for the children...
  8239. */
  8240. if (IS_SCHEMA(child, "complexType")) {
  8241. /*
  8242. * 3.3.3 : 3
  8243. * "type" and either <simpleType> or <complexType> are mutually
  8244. * exclusive
  8245. */
  8246. if (decl->namedType != NULL) {
  8247. xmlSchemaPContentErr(ctxt,
  8248. XML_SCHEMAP_SRC_ELEMENT_3,
  8249. NULL, node, child,
  8250. "The attribute 'type' and the <complexType> child are "
  8251. "mutually exclusive", NULL);
  8252. } else
  8253. WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
  8254. child = child->next;
  8255. } else if (IS_SCHEMA(child, "simpleType")) {
  8256. /*
  8257. * 3.3.3 : 3
  8258. * "type" and either <simpleType> or <complexType> are
  8259. * mutually exclusive
  8260. */
  8261. if (decl->namedType != NULL) {
  8262. xmlSchemaPContentErr(ctxt,
  8263. XML_SCHEMAP_SRC_ELEMENT_3,
  8264. NULL, node, child,
  8265. "The attribute 'type' and the <simpleType> child are "
  8266. "mutually exclusive", NULL);
  8267. } else
  8268. WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8269. child = child->next;
  8270. }
  8271. while ((IS_SCHEMA(child, "unique")) ||
  8272. (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
  8273. if (IS_SCHEMA(child, "unique")) {
  8274. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8275. XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
  8276. } else if (IS_SCHEMA(child, "key")) {
  8277. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8278. XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
  8279. } else if (IS_SCHEMA(child, "keyref")) {
  8280. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8281. XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
  8282. }
  8283. if (lastIDC != NULL)
  8284. lastIDC->next = curIDC;
  8285. else
  8286. decl->idcs = (void *) curIDC;
  8287. lastIDC = curIDC;
  8288. child = child->next;
  8289. }
  8290. if (child != NULL) {
  8291. xmlSchemaPContentErr(ctxt,
  8292. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8293. NULL, node, child,
  8294. NULL, "(annotation?, ((simpleType | complexType)?, "
  8295. "(unique | key | keyref)*))");
  8296. }
  8297. decl->annot = annot;
  8298. }
  8299. /*
  8300. * NOTE: Element Declaration Representation OK 4. will be checked at a
  8301. * different layer.
  8302. */
  8303. FREE_AND_NULL(des)
  8304. if (topLevel)
  8305. return ((xmlSchemaBasicItemPtr) decl);
  8306. else {
  8307. particle->children = (xmlSchemaTreeItemPtr) decl;
  8308. return ((xmlSchemaBasicItemPtr) particle);
  8309. }
  8310. return_null:
  8311. FREE_AND_NULL(des);
  8312. if (annot != NULL) {
  8313. if (particle != NULL)
  8314. particle->annot = NULL;
  8315. if (decl != NULL)
  8316. decl->annot = NULL;
  8317. xmlSchemaFreeAnnot(annot);
  8318. }
  8319. return (NULL);
  8320. }
  8321. /**
  8322. * xmlSchemaParseUnion:
  8323. * @ctxt: a schema validation context
  8324. * @schema: the schema being built
  8325. * @node: a subtree containing XML Schema information
  8326. *
  8327. * parse a XML schema Union definition
  8328. * *WARNING* this interface is highly subject to change
  8329. *
  8330. * Returns -1 in case of internal error, 0 in case of success and a positive
  8331. * error code otherwise.
  8332. */
  8333. static int
  8334. xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8335. xmlNodePtr node)
  8336. {
  8337. xmlSchemaTypePtr type;
  8338. xmlNodePtr child = NULL;
  8339. xmlAttrPtr attr;
  8340. const xmlChar *cur = NULL;
  8341. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8342. return (-1);
  8343. /* Not a component, don't create it. */
  8344. type = ctxt->ctxtType;
  8345. /*
  8346. * Mark the simple type as being of variety "union".
  8347. */
  8348. type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
  8349. /*
  8350. * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
  8351. * then the `simple ur-type definition`."
  8352. */
  8353. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  8354. /*
  8355. * Check for illegal attributes.
  8356. */
  8357. attr = node->properties;
  8358. while (attr != NULL) {
  8359. if (attr->ns == NULL) {
  8360. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8361. (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
  8362. xmlSchemaPIllegalAttrErr(ctxt,
  8363. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8364. }
  8365. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8366. xmlSchemaPIllegalAttrErr(ctxt,
  8367. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8368. }
  8369. attr = attr->next;
  8370. }
  8371. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8372. /*
  8373. * Attribute "memberTypes". This is a list of QNames.
  8374. * TODO: Check the value to contain anything.
  8375. */
  8376. attr = xmlSchemaGetPropNode(node, "memberTypes");
  8377. if (attr != NULL) {
  8378. const xmlChar *end;
  8379. xmlChar *tmp;
  8380. const xmlChar *localName, *nsName;
  8381. xmlSchemaTypeLinkPtr link, lastLink = NULL;
  8382. xmlSchemaQNameRefPtr ref;
  8383. cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8384. type->base = cur;
  8385. do {
  8386. while (IS_BLANK_CH(*cur))
  8387. cur++;
  8388. end = cur;
  8389. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  8390. end++;
  8391. if (end == cur)
  8392. break;
  8393. tmp = xmlStrndup(cur, end - cur);
  8394. if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
  8395. NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
  8396. /*
  8397. * Create the member type link.
  8398. */
  8399. link = (xmlSchemaTypeLinkPtr)
  8400. xmlMalloc(sizeof(xmlSchemaTypeLink));
  8401. if (link == NULL) {
  8402. xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
  8403. "allocating a type link", NULL);
  8404. return (-1);
  8405. }
  8406. link->type = NULL;
  8407. link->next = NULL;
  8408. if (lastLink == NULL)
  8409. type->memberTypes = link;
  8410. else
  8411. lastLink->next = link;
  8412. lastLink = link;
  8413. /*
  8414. * Create a reference item.
  8415. */
  8416. ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
  8417. localName, nsName);
  8418. if (ref == NULL) {
  8419. FREE_AND_NULL(tmp)
  8420. return (-1);
  8421. }
  8422. /*
  8423. * Assign the reference to the link, it will be resolved
  8424. * later during fixup of the union simple type.
  8425. */
  8426. link->type = (xmlSchemaTypePtr) ref;
  8427. }
  8428. FREE_AND_NULL(tmp)
  8429. cur = end;
  8430. } while (*cur != 0);
  8431. }
  8432. /*
  8433. * And now for the children...
  8434. */
  8435. child = node->children;
  8436. if (IS_SCHEMA(child, "annotation")) {
  8437. /*
  8438. * Add the annotation to the simple type ancestor.
  8439. */
  8440. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  8441. xmlSchemaParseAnnotation(ctxt, child, 1));
  8442. child = child->next;
  8443. }
  8444. if (IS_SCHEMA(child, "simpleType")) {
  8445. xmlSchemaTypePtr subtype, last = NULL;
  8446. /*
  8447. * Anchor the member types in the "subtypes" field of the
  8448. * simple type.
  8449. */
  8450. while (IS_SCHEMA(child, "simpleType")) {
  8451. subtype = (xmlSchemaTypePtr)
  8452. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8453. if (subtype != NULL) {
  8454. if (last == NULL) {
  8455. type->subtypes = subtype;
  8456. last = subtype;
  8457. } else {
  8458. last->next = subtype;
  8459. last = subtype;
  8460. }
  8461. last->next = NULL;
  8462. }
  8463. child = child->next;
  8464. }
  8465. }
  8466. if (child != NULL) {
  8467. xmlSchemaPContentErr(ctxt,
  8468. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8469. NULL, node, child, NULL, "(annotation?, simpleType*)");
  8470. }
  8471. if ((attr == NULL) && (type->subtypes == NULL)) {
  8472. /*
  8473. * src-union-memberTypes-or-simpleTypes
  8474. * Either the memberTypes [attribute] of the <union> element must
  8475. * be non-empty or there must be at least one simpleType [child].
  8476. */
  8477. xmlSchemaPCustomErr(ctxt,
  8478. XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
  8479. NULL, node,
  8480. "Either the attribute 'memberTypes' or "
  8481. "at least one <simpleType> child must be present", NULL);
  8482. }
  8483. return (0);
  8484. }
  8485. /**
  8486. * xmlSchemaParseList:
  8487. * @ctxt: a schema validation context
  8488. * @schema: the schema being built
  8489. * @node: a subtree containing XML Schema information
  8490. *
  8491. * parse a XML schema List definition
  8492. * *WARNING* this interface is highly subject to change
  8493. *
  8494. * Returns -1 in case of error, 0 if the declaration is improper and
  8495. * 1 in case of success.
  8496. */
  8497. static xmlSchemaTypePtr
  8498. xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8499. xmlNodePtr node)
  8500. {
  8501. xmlSchemaTypePtr type;
  8502. xmlNodePtr child = NULL;
  8503. xmlAttrPtr attr;
  8504. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8505. return (NULL);
  8506. /* Not a component, don't create it. */
  8507. type = ctxt->ctxtType;
  8508. /*
  8509. * Mark the type as being of variety "list".
  8510. */
  8511. type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
  8512. /*
  8513. * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
  8514. * then the `simple ur-type definition`."
  8515. */
  8516. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  8517. /*
  8518. * Check for illegal attributes.
  8519. */
  8520. attr = node->properties;
  8521. while (attr != NULL) {
  8522. if (attr->ns == NULL) {
  8523. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8524. (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
  8525. xmlSchemaPIllegalAttrErr(ctxt,
  8526. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8527. }
  8528. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8529. xmlSchemaPIllegalAttrErr(ctxt,
  8530. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8531. }
  8532. attr = attr->next;
  8533. }
  8534. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8535. /*
  8536. * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
  8537. * fields for holding the reference to the itemType.
  8538. *
  8539. * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
  8540. * the "ref" fields.
  8541. */
  8542. xmlSchemaPValAttrQName(ctxt, schema, NULL,
  8543. node, "itemType", &(type->baseNs), &(type->base));
  8544. /*
  8545. * And now for the children...
  8546. */
  8547. child = node->children;
  8548. if (IS_SCHEMA(child, "annotation")) {
  8549. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  8550. xmlSchemaParseAnnotation(ctxt, child, 1));
  8551. child = child->next;
  8552. }
  8553. if (IS_SCHEMA(child, "simpleType")) {
  8554. /*
  8555. * src-list-itemType-or-simpleType
  8556. * Either the itemType [attribute] or the <simpleType> [child] of
  8557. * the <list> element must be present, but not both.
  8558. */
  8559. if (type->base != NULL) {
  8560. xmlSchemaPCustomErr(ctxt,
  8561. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8562. NULL, node,
  8563. "The attribute 'itemType' and the <simpleType> child "
  8564. "are mutually exclusive", NULL);
  8565. } else {
  8566. type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8567. }
  8568. child = child->next;
  8569. } else if (type->base == NULL) {
  8570. xmlSchemaPCustomErr(ctxt,
  8571. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8572. NULL, node,
  8573. "Either the attribute 'itemType' or the <simpleType> child "
  8574. "must be present", NULL);
  8575. }
  8576. if (child != NULL) {
  8577. xmlSchemaPContentErr(ctxt,
  8578. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8579. NULL, node, child, NULL, "(annotation?, simpleType?)");
  8580. }
  8581. if ((type->base == NULL) &&
  8582. (type->subtypes == NULL) &&
  8583. (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
  8584. xmlSchemaPCustomErr(ctxt,
  8585. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8586. NULL, node,
  8587. "Either the attribute 'itemType' or the <simpleType> child "
  8588. "must be present", NULL);
  8589. }
  8590. return (NULL);
  8591. }
  8592. /**
  8593. * xmlSchemaParseSimpleType:
  8594. * @ctxt: a schema validation context
  8595. * @schema: the schema being built
  8596. * @node: a subtree containing XML Schema information
  8597. *
  8598. * parse a XML schema Simple Type definition
  8599. * *WARNING* this interface is highly subject to change
  8600. *
  8601. * Returns -1 in case of error, 0 if the declaration is improper and
  8602. * 1 in case of success.
  8603. */
  8604. static xmlSchemaTypePtr
  8605. xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8606. xmlNodePtr node, int topLevel)
  8607. {
  8608. xmlSchemaTypePtr type, oldCtxtType;
  8609. xmlNodePtr child = NULL;
  8610. const xmlChar *attrValue = NULL;
  8611. xmlAttrPtr attr;
  8612. int hasRestriction = 0;
  8613. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8614. return (NULL);
  8615. if (topLevel) {
  8616. attr = xmlSchemaGetPropNode(node, "name");
  8617. if (attr == NULL) {
  8618. xmlSchemaPMissingAttrErr(ctxt,
  8619. XML_SCHEMAP_S4S_ATTR_MISSING,
  8620. NULL, node,
  8621. "name", NULL);
  8622. return (NULL);
  8623. } else {
  8624. if (xmlSchemaPValAttrNode(ctxt,
  8625. NULL, attr,
  8626. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
  8627. return (NULL);
  8628. /*
  8629. * Skip built-in types.
  8630. */
  8631. if (ctxt->isS4S) {
  8632. xmlSchemaTypePtr biType;
  8633. if (ctxt->isRedefine) {
  8634. /*
  8635. * REDEFINE: Disallow redefinition of built-in-types.
  8636. * TODO: It seems that the spec does not say anything
  8637. * about this case.
  8638. */
  8639. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  8640. NULL, node,
  8641. "Redefinition of built-in simple types is not "
  8642. "supported", NULL);
  8643. return(NULL);
  8644. }
  8645. biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
  8646. if (biType != NULL)
  8647. return (biType);
  8648. }
  8649. }
  8650. }
  8651. /*
  8652. * TargetNamespace:
  8653. * SPEC "The `actual value` of the targetNamespace [attribute]
  8654. * of the <schema> ancestor element information item if present,
  8655. * otherwise `absent`.
  8656. */
  8657. if (topLevel == 0) {
  8658. #ifdef ENABLE_NAMED_LOCALS
  8659. char buf[40];
  8660. #endif
  8661. /*
  8662. * Parse as local simple type definition.
  8663. */
  8664. #ifdef ENABLE_NAMED_LOCALS
  8665. snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
  8666. type = xmlSchemaAddType(ctxt, schema,
  8667. XML_SCHEMA_TYPE_SIMPLE,
  8668. xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
  8669. ctxt->targetNamespace, node, 0);
  8670. #else
  8671. type = xmlSchemaAddType(ctxt, schema,
  8672. XML_SCHEMA_TYPE_SIMPLE,
  8673. NULL, ctxt->targetNamespace, node, 0);
  8674. #endif
  8675. if (type == NULL)
  8676. return (NULL);
  8677. type->type = XML_SCHEMA_TYPE_SIMPLE;
  8678. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  8679. /*
  8680. * Check for illegal attributes.
  8681. */
  8682. attr = node->properties;
  8683. while (attr != NULL) {
  8684. if (attr->ns == NULL) {
  8685. if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
  8686. xmlSchemaPIllegalAttrErr(ctxt,
  8687. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8688. }
  8689. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8690. xmlSchemaPIllegalAttrErr(ctxt,
  8691. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8692. }
  8693. attr = attr->next;
  8694. }
  8695. } else {
  8696. /*
  8697. * Parse as global simple type definition.
  8698. *
  8699. * Note that attrValue is the value of the attribute "name" here.
  8700. */
  8701. type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
  8702. attrValue, ctxt->targetNamespace, node, 1);
  8703. if (type == NULL)
  8704. return (NULL);
  8705. type->type = XML_SCHEMA_TYPE_SIMPLE;
  8706. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  8707. type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
  8708. /*
  8709. * Check for illegal attributes.
  8710. */
  8711. attr = node->properties;
  8712. while (attr != NULL) {
  8713. if (attr->ns == NULL) {
  8714. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8715. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8716. (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
  8717. xmlSchemaPIllegalAttrErr(ctxt,
  8718. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8719. }
  8720. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8721. xmlSchemaPIllegalAttrErr(ctxt,
  8722. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8723. }
  8724. attr = attr->next;
  8725. }
  8726. /*
  8727. * Attribute "final".
  8728. */
  8729. attr = xmlSchemaGetPropNode(node, "final");
  8730. if (attr == NULL) {
  8731. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8732. type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
  8733. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
  8734. type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
  8735. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
  8736. type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
  8737. } else {
  8738. attrValue = xmlSchemaGetProp(ctxt, node, "final");
  8739. if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
  8740. -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
  8741. XML_SCHEMAS_TYPE_FINAL_LIST,
  8742. XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
  8743. xmlSchemaPSimpleTypeErr(ctxt,
  8744. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8745. WXS_BASIC_CAST type, (xmlNodePtr) attr,
  8746. NULL, "(#all | List of (list | union | restriction)",
  8747. attrValue, NULL, NULL, NULL);
  8748. }
  8749. }
  8750. }
  8751. type->targetNamespace = ctxt->targetNamespace;
  8752. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8753. /*
  8754. * And now for the children...
  8755. */
  8756. oldCtxtType = ctxt->ctxtType;
  8757. ctxt->ctxtType = type;
  8758. child = node->children;
  8759. if (IS_SCHEMA(child, "annotation")) {
  8760. type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8761. child = child->next;
  8762. }
  8763. if (child == NULL) {
  8764. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
  8765. NULL, node, child, NULL,
  8766. "(annotation?, (restriction | list | union))");
  8767. } else if (IS_SCHEMA(child, "restriction")) {
  8768. xmlSchemaParseRestriction(ctxt, schema, child,
  8769. XML_SCHEMA_TYPE_SIMPLE);
  8770. hasRestriction = 1;
  8771. child = child->next;
  8772. } else if (IS_SCHEMA(child, "list")) {
  8773. xmlSchemaParseList(ctxt, schema, child);
  8774. child = child->next;
  8775. } else if (IS_SCHEMA(child, "union")) {
  8776. xmlSchemaParseUnion(ctxt, schema, child);
  8777. child = child->next;
  8778. }
  8779. if (child != NULL) {
  8780. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8781. NULL, node, child, NULL,
  8782. "(annotation?, (restriction | list | union))");
  8783. }
  8784. /*
  8785. * REDEFINE: SPEC src-redefine (5)
  8786. * "Within the [children], each <simpleType> must have a
  8787. * <restriction> among its [children] ... the `actual value` of whose
  8788. * base [attribute] must be the same as the `actual value` of its own
  8789. * name attribute plus target namespace;"
  8790. */
  8791. if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
  8792. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  8793. NULL, node, "This is a redefinition, thus the "
  8794. "<simpleType> must have a <restriction> child", NULL);
  8795. }
  8796. ctxt->ctxtType = oldCtxtType;
  8797. return (type);
  8798. }
  8799. /**
  8800. * xmlSchemaParseModelGroupDefRef:
  8801. * @ctxt: the parser context
  8802. * @schema: the schema being built
  8803. * @node: the node
  8804. *
  8805. * Parses a reference to a model group definition.
  8806. *
  8807. * We will return a particle component with a qname-component or
  8808. * NULL in case of an error.
  8809. */
  8810. static xmlSchemaTreeItemPtr
  8811. xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
  8812. xmlSchemaPtr schema,
  8813. xmlNodePtr node)
  8814. {
  8815. xmlSchemaParticlePtr item;
  8816. xmlNodePtr child = NULL;
  8817. xmlAttrPtr attr;
  8818. const xmlChar *ref = NULL, *refNs = NULL;
  8819. int min, max;
  8820. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8821. return (NULL);
  8822. attr = xmlSchemaGetPropNode(node, "ref");
  8823. if (attr == NULL) {
  8824. xmlSchemaPMissingAttrErr(ctxt,
  8825. XML_SCHEMAP_S4S_ATTR_MISSING,
  8826. NULL, node, "ref", NULL);
  8827. return (NULL);
  8828. } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
  8829. attr, &refNs, &ref) != 0) {
  8830. return (NULL);
  8831. }
  8832. xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
  8833. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  8834. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  8835. "(xs:nonNegativeInteger | unbounded)");
  8836. /*
  8837. * Check for illegal attributes.
  8838. */
  8839. attr = node->properties;
  8840. while (attr != NULL) {
  8841. if (attr->ns == NULL) {
  8842. if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
  8843. (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8844. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  8845. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
  8846. xmlSchemaPIllegalAttrErr(ctxt,
  8847. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8848. }
  8849. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8850. xmlSchemaPIllegalAttrErr(ctxt,
  8851. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8852. }
  8853. attr = attr->next;
  8854. }
  8855. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8856. item = xmlSchemaAddParticle(ctxt, node, min, max);
  8857. if (item == NULL)
  8858. return (NULL);
  8859. /*
  8860. * Create a qname-reference and set as the term; it will be substituted
  8861. * for the model group after the reference has been resolved.
  8862. */
  8863. item->children = (xmlSchemaTreeItemPtr)
  8864. xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
  8865. xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
  8866. /*
  8867. * And now for the children...
  8868. */
  8869. child = node->children;
  8870. /* TODO: Is annotation even allowed for a model group reference? */
  8871. if (IS_SCHEMA(child, "annotation")) {
  8872. /*
  8873. * TODO: What to do exactly with the annotation?
  8874. */
  8875. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8876. child = child->next;
  8877. }
  8878. if (child != NULL) {
  8879. xmlSchemaPContentErr(ctxt,
  8880. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8881. NULL, node, child, NULL,
  8882. "(annotation?)");
  8883. }
  8884. /*
  8885. * Corresponds to no component at all if minOccurs==maxOccurs==0.
  8886. */
  8887. if ((min == 0) && (max == 0))
  8888. return (NULL);
  8889. return ((xmlSchemaTreeItemPtr) item);
  8890. }
  8891. /**
  8892. * xmlSchemaParseModelGroupDefinition:
  8893. * @ctxt: a schema validation context
  8894. * @schema: the schema being built
  8895. * @node: a subtree containing XML Schema information
  8896. *
  8897. * Parses a XML schema model group definition.
  8898. *
  8899. * Note that the constraint src-redefine (6.2) can't be applied until
  8900. * references have been resolved. So we will do this at the
  8901. * component fixup level.
  8902. *
  8903. * *WARNING* this interface is highly subject to change
  8904. *
  8905. * Returns -1 in case of error, 0 if the declaration is improper and
  8906. * 1 in case of success.
  8907. */
  8908. static xmlSchemaModelGroupDefPtr
  8909. xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
  8910. xmlSchemaPtr schema,
  8911. xmlNodePtr node)
  8912. {
  8913. xmlSchemaModelGroupDefPtr item;
  8914. xmlNodePtr child = NULL;
  8915. xmlAttrPtr attr;
  8916. const xmlChar *name;
  8917. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8918. return (NULL);
  8919. attr = xmlSchemaGetPropNode(node, "name");
  8920. if (attr == NULL) {
  8921. xmlSchemaPMissingAttrErr(ctxt,
  8922. XML_SCHEMAP_S4S_ATTR_MISSING,
  8923. NULL, node,
  8924. "name", NULL);
  8925. return (NULL);
  8926. } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
  8927. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  8928. return (NULL);
  8929. }
  8930. item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
  8931. ctxt->targetNamespace, node);
  8932. if (item == NULL)
  8933. return (NULL);
  8934. /*
  8935. * Check for illegal attributes.
  8936. */
  8937. attr = node->properties;
  8938. while (attr != NULL) {
  8939. if (attr->ns == NULL) {
  8940. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8941. (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
  8942. xmlSchemaPIllegalAttrErr(ctxt,
  8943. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8944. }
  8945. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8946. xmlSchemaPIllegalAttrErr(ctxt,
  8947. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8948. }
  8949. attr = attr->next;
  8950. }
  8951. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8952. /*
  8953. * And now for the children...
  8954. */
  8955. child = node->children;
  8956. if (IS_SCHEMA(child, "annotation")) {
  8957. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8958. child = child->next;
  8959. }
  8960. if (IS_SCHEMA(child, "all")) {
  8961. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8962. XML_SCHEMA_TYPE_ALL, 0);
  8963. child = child->next;
  8964. } else if (IS_SCHEMA(child, "choice")) {
  8965. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8966. XML_SCHEMA_TYPE_CHOICE, 0);
  8967. child = child->next;
  8968. } else if (IS_SCHEMA(child, "sequence")) {
  8969. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8970. XML_SCHEMA_TYPE_SEQUENCE, 0);
  8971. child = child->next;
  8972. }
  8973. if (child != NULL) {
  8974. xmlSchemaPContentErr(ctxt,
  8975. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8976. NULL, node, child, NULL,
  8977. "(annotation?, (all | choice | sequence)?)");
  8978. }
  8979. return (item);
  8980. }
  8981. /**
  8982. * xmlSchemaCleanupDoc:
  8983. * @ctxt: a schema validation context
  8984. * @node: the root of the document.
  8985. *
  8986. * removes unwanted nodes in a schemas document tree
  8987. */
  8988. static void
  8989. xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
  8990. {
  8991. xmlNodePtr delete, cur;
  8992. if ((ctxt == NULL) || (root == NULL)) return;
  8993. /*
  8994. * Remove all the blank text nodes
  8995. */
  8996. delete = NULL;
  8997. cur = root;
  8998. while (cur != NULL) {
  8999. if (delete != NULL) {
  9000. xmlUnlinkNode(delete);
  9001. xmlFreeNode(delete);
  9002. delete = NULL;
  9003. }
  9004. if (cur->type == XML_TEXT_NODE) {
  9005. if (IS_BLANK_NODE(cur)) {
  9006. if (xmlNodeGetSpacePreserve(cur) != 1) {
  9007. delete = cur;
  9008. }
  9009. }
  9010. } else if ((cur->type != XML_ELEMENT_NODE) &&
  9011. (cur->type != XML_CDATA_SECTION_NODE)) {
  9012. delete = cur;
  9013. goto skip_children;
  9014. }
  9015. /*
  9016. * Skip to next node
  9017. */
  9018. if (cur->children != NULL) {
  9019. if ((cur->children->type != XML_ENTITY_DECL) &&
  9020. (cur->children->type != XML_ENTITY_REF_NODE) &&
  9021. (cur->children->type != XML_ENTITY_NODE)) {
  9022. cur = cur->children;
  9023. continue;
  9024. }
  9025. }
  9026. skip_children:
  9027. if (cur->next != NULL) {
  9028. cur = cur->next;
  9029. continue;
  9030. }
  9031. do {
  9032. cur = cur->parent;
  9033. if (cur == NULL)
  9034. break;
  9035. if (cur == root) {
  9036. cur = NULL;
  9037. break;
  9038. }
  9039. if (cur->next != NULL) {
  9040. cur = cur->next;
  9041. break;
  9042. }
  9043. } while (cur != NULL);
  9044. }
  9045. if (delete != NULL) {
  9046. xmlUnlinkNode(delete);
  9047. xmlFreeNode(delete);
  9048. delete = NULL;
  9049. }
  9050. }
  9051. static void
  9052. xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
  9053. {
  9054. if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
  9055. schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
  9056. if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
  9057. schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
  9058. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  9059. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
  9060. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  9061. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
  9062. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
  9063. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
  9064. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
  9065. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
  9066. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  9067. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
  9068. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  9069. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
  9070. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
  9071. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
  9072. }
  9073. static int
  9074. xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
  9075. xmlSchemaPtr schema,
  9076. xmlNodePtr node)
  9077. {
  9078. xmlAttrPtr attr;
  9079. const xmlChar *val;
  9080. int res = 0, oldErrs = ctxt->nberrors;
  9081. /*
  9082. * Those flags should be moved to the parser context flags,
  9083. * since they are not visible at the component level. I.e.
  9084. * they are used if processing schema *documents* only.
  9085. */
  9086. res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  9087. HFAILURE;
  9088. /*
  9089. * Since the version is of type xs:token, we won't bother to
  9090. * check it.
  9091. */
  9092. /* REMOVED:
  9093. attr = xmlSchemaGetPropNode(node, "version");
  9094. if (attr != NULL) {
  9095. res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
  9096. xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
  9097. HFAILURE;
  9098. }
  9099. */
  9100. attr = xmlSchemaGetPropNode(node, "targetNamespace");
  9101. if (attr != NULL) {
  9102. res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
  9103. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
  9104. HFAILURE;
  9105. if (res != 0) {
  9106. ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  9107. goto exit;
  9108. }
  9109. }
  9110. attr = xmlSchemaGetPropNode(node, "elementFormDefault");
  9111. if (attr != NULL) {
  9112. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9113. res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
  9114. XML_SCHEMAS_QUALIF_ELEM);
  9115. HFAILURE;
  9116. if (res != 0) {
  9117. xmlSchemaPSimpleTypeErr(ctxt,
  9118. XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
  9119. NULL, (xmlNodePtr) attr, NULL,
  9120. "(qualified | unqualified)", val, NULL, NULL, NULL);
  9121. }
  9122. }
  9123. attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
  9124. if (attr != NULL) {
  9125. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9126. res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
  9127. XML_SCHEMAS_QUALIF_ATTR);
  9128. HFAILURE;
  9129. if (res != 0) {
  9130. xmlSchemaPSimpleTypeErr(ctxt,
  9131. XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
  9132. NULL, (xmlNodePtr) attr, NULL,
  9133. "(qualified | unqualified)", val, NULL, NULL, NULL);
  9134. }
  9135. }
  9136. attr = xmlSchemaGetPropNode(node, "finalDefault");
  9137. if (attr != NULL) {
  9138. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9139. res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
  9140. XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
  9141. XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
  9142. -1,
  9143. XML_SCHEMAS_FINAL_DEFAULT_LIST,
  9144. XML_SCHEMAS_FINAL_DEFAULT_UNION);
  9145. HFAILURE;
  9146. if (res != 0) {
  9147. xmlSchemaPSimpleTypeErr(ctxt,
  9148. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  9149. NULL, (xmlNodePtr) attr, NULL,
  9150. "(#all | List of (extension | restriction | list | union))",
  9151. val, NULL, NULL, NULL);
  9152. }
  9153. }
  9154. attr = xmlSchemaGetPropNode(node, "blockDefault");
  9155. if (attr != NULL) {
  9156. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9157. res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
  9158. XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
  9159. XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
  9160. XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
  9161. HFAILURE;
  9162. if (res != 0) {
  9163. xmlSchemaPSimpleTypeErr(ctxt,
  9164. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  9165. NULL, (xmlNodePtr) attr, NULL,
  9166. "(#all | List of (extension | restriction | substitution))",
  9167. val, NULL, NULL, NULL);
  9168. }
  9169. }
  9170. exit:
  9171. if (oldErrs != ctxt->nberrors)
  9172. res = ctxt->err;
  9173. return(res);
  9174. exit_failure:
  9175. return(-1);
  9176. }
  9177. /**
  9178. * xmlSchemaParseSchemaTopLevel:
  9179. * @ctxt: a schema validation context
  9180. * @schema: the schemas
  9181. * @nodes: the list of top level nodes
  9182. *
  9183. * Returns the internal XML Schema structure built from the resource or
  9184. * NULL in case of error
  9185. */
  9186. static int
  9187. xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
  9188. xmlSchemaPtr schema, xmlNodePtr nodes)
  9189. {
  9190. xmlNodePtr child;
  9191. xmlSchemaAnnotPtr annot;
  9192. int res = 0, oldErrs, tmpOldErrs;
  9193. if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
  9194. return(-1);
  9195. oldErrs = ctxt->nberrors;
  9196. child = nodes;
  9197. while ((IS_SCHEMA(child, "include")) ||
  9198. (IS_SCHEMA(child, "import")) ||
  9199. (IS_SCHEMA(child, "redefine")) ||
  9200. (IS_SCHEMA(child, "annotation"))) {
  9201. if (IS_SCHEMA(child, "annotation")) {
  9202. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  9203. if (schema->annot == NULL)
  9204. schema->annot = annot;
  9205. else
  9206. xmlSchemaFreeAnnot(annot);
  9207. } else if (IS_SCHEMA(child, "import")) {
  9208. tmpOldErrs = ctxt->nberrors;
  9209. res = xmlSchemaParseImport(ctxt, schema, child);
  9210. HFAILURE;
  9211. HSTOP(ctxt);
  9212. if (tmpOldErrs != ctxt->nberrors)
  9213. goto exit;
  9214. } else if (IS_SCHEMA(child, "include")) {
  9215. tmpOldErrs = ctxt->nberrors;
  9216. res = xmlSchemaParseInclude(ctxt, schema, child);
  9217. HFAILURE;
  9218. HSTOP(ctxt);
  9219. if (tmpOldErrs != ctxt->nberrors)
  9220. goto exit;
  9221. } else if (IS_SCHEMA(child, "redefine")) {
  9222. tmpOldErrs = ctxt->nberrors;
  9223. res = xmlSchemaParseRedefine(ctxt, schema, child);
  9224. HFAILURE;
  9225. HSTOP(ctxt);
  9226. if (tmpOldErrs != ctxt->nberrors)
  9227. goto exit;
  9228. }
  9229. child = child->next;
  9230. }
  9231. /*
  9232. * URGENT TODO: Change the functions to return int results.
  9233. * We need especially to catch internal errors.
  9234. */
  9235. while (child != NULL) {
  9236. if (IS_SCHEMA(child, "complexType")) {
  9237. xmlSchemaParseComplexType(ctxt, schema, child, 1);
  9238. child = child->next;
  9239. } else if (IS_SCHEMA(child, "simpleType")) {
  9240. xmlSchemaParseSimpleType(ctxt, schema, child, 1);
  9241. child = child->next;
  9242. } else if (IS_SCHEMA(child, "element")) {
  9243. xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
  9244. child = child->next;
  9245. } else if (IS_SCHEMA(child, "attribute")) {
  9246. xmlSchemaParseGlobalAttribute(ctxt, schema, child);
  9247. child = child->next;
  9248. } else if (IS_SCHEMA(child, "attributeGroup")) {
  9249. xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
  9250. child = child->next;
  9251. } else if (IS_SCHEMA(child, "group")) {
  9252. xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
  9253. child = child->next;
  9254. } else if (IS_SCHEMA(child, "notation")) {
  9255. xmlSchemaParseNotation(ctxt, schema, child);
  9256. child = child->next;
  9257. } else {
  9258. xmlSchemaPContentErr(ctxt,
  9259. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  9260. NULL, child->parent, child,
  9261. NULL, "((include | import | redefine | annotation)*, "
  9262. "(((simpleType | complexType | group | attributeGroup) "
  9263. "| element | attribute | notation), annotation*)*)");
  9264. child = child->next;
  9265. }
  9266. while (IS_SCHEMA(child, "annotation")) {
  9267. /*
  9268. * TODO: We should add all annotations.
  9269. */
  9270. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  9271. if (schema->annot == NULL)
  9272. schema->annot = annot;
  9273. else
  9274. xmlSchemaFreeAnnot(annot);
  9275. child = child->next;
  9276. }
  9277. }
  9278. exit:
  9279. ctxt->ctxtType = NULL;
  9280. if (oldErrs != ctxt->nberrors)
  9281. res = ctxt->err;
  9282. return(res);
  9283. exit_failure:
  9284. return(-1);
  9285. }
  9286. static xmlSchemaSchemaRelationPtr
  9287. xmlSchemaSchemaRelationCreate(void)
  9288. {
  9289. xmlSchemaSchemaRelationPtr ret;
  9290. ret = (xmlSchemaSchemaRelationPtr)
  9291. xmlMalloc(sizeof(xmlSchemaSchemaRelation));
  9292. if (ret == NULL) {
  9293. xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
  9294. return(NULL);
  9295. }
  9296. memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
  9297. return(ret);
  9298. }
  9299. #if 0
  9300. static void
  9301. xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
  9302. {
  9303. xmlFree(rel);
  9304. }
  9305. #endif
  9306. static void
  9307. xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
  9308. {
  9309. xmlSchemaRedefPtr prev;
  9310. while (redef != NULL) {
  9311. prev = redef;
  9312. redef = redef->next;
  9313. xmlFree(prev);
  9314. }
  9315. }
  9316. static void
  9317. xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
  9318. {
  9319. /*
  9320. * After the construction context has been freed, there will be
  9321. * no schema graph available any more. Only the schema buckets
  9322. * will stay alive, which are put into the "schemasImports" and
  9323. * "includes" slots of the xmlSchema.
  9324. */
  9325. if (con->buckets != NULL)
  9326. xmlSchemaItemListFree(con->buckets);
  9327. if (con->pending != NULL)
  9328. xmlSchemaItemListFree(con->pending);
  9329. if (con->substGroups != NULL)
  9330. xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
  9331. if (con->redefs != NULL)
  9332. xmlSchemaRedefListFree(con->redefs);
  9333. if (con->dict != NULL)
  9334. xmlDictFree(con->dict);
  9335. xmlFree(con);
  9336. }
  9337. static xmlSchemaConstructionCtxtPtr
  9338. xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
  9339. {
  9340. xmlSchemaConstructionCtxtPtr ret;
  9341. ret = (xmlSchemaConstructionCtxtPtr)
  9342. xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
  9343. if (ret == NULL) {
  9344. xmlSchemaPErrMemory(NULL,
  9345. "allocating schema construction context", NULL);
  9346. return (NULL);
  9347. }
  9348. memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
  9349. ret->buckets = xmlSchemaItemListCreate();
  9350. if (ret->buckets == NULL) {
  9351. xmlSchemaPErrMemory(NULL,
  9352. "allocating list of schema buckets", NULL);
  9353. xmlFree(ret);
  9354. return (NULL);
  9355. }
  9356. ret->pending = xmlSchemaItemListCreate();
  9357. if (ret->pending == NULL) {
  9358. xmlSchemaPErrMemory(NULL,
  9359. "allocating list of pending global components", NULL);
  9360. xmlSchemaConstructionCtxtFree(ret);
  9361. return (NULL);
  9362. }
  9363. ret->dict = dict;
  9364. xmlDictReference(dict);
  9365. return(ret);
  9366. }
  9367. static xmlSchemaParserCtxtPtr
  9368. xmlSchemaParserCtxtCreate(void)
  9369. {
  9370. xmlSchemaParserCtxtPtr ret;
  9371. ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
  9372. if (ret == NULL) {
  9373. xmlSchemaPErrMemory(NULL, "allocating schema parser context",
  9374. NULL);
  9375. return (NULL);
  9376. }
  9377. memset(ret, 0, sizeof(xmlSchemaParserCtxt));
  9378. ret->type = XML_SCHEMA_CTXT_PARSER;
  9379. ret->attrProhibs = xmlSchemaItemListCreate();
  9380. if (ret->attrProhibs == NULL) {
  9381. xmlFree(ret);
  9382. return(NULL);
  9383. }
  9384. return(ret);
  9385. }
  9386. /**
  9387. * xmlSchemaNewParserCtxtUseDict:
  9388. * @URL: the location of the schema
  9389. * @dict: the dictionary to be used
  9390. *
  9391. * Create an XML Schemas parse context for that file/resource expected
  9392. * to contain an XML Schemas file.
  9393. *
  9394. * Returns the parser context or NULL in case of error
  9395. */
  9396. static xmlSchemaParserCtxtPtr
  9397. xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
  9398. {
  9399. xmlSchemaParserCtxtPtr ret;
  9400. ret = xmlSchemaParserCtxtCreate();
  9401. if (ret == NULL)
  9402. return (NULL);
  9403. ret->dict = dict;
  9404. xmlDictReference(dict);
  9405. if (URL != NULL)
  9406. ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
  9407. return (ret);
  9408. }
  9409. static int
  9410. xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
  9411. {
  9412. if (vctxt->pctxt == NULL) {
  9413. if (vctxt->schema != NULL)
  9414. vctxt->pctxt =
  9415. xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
  9416. else
  9417. vctxt->pctxt = xmlSchemaNewParserCtxt("*");
  9418. if (vctxt->pctxt == NULL) {
  9419. VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
  9420. "failed to create a temp. parser context");
  9421. return (-1);
  9422. }
  9423. /* TODO: Pass user data. */
  9424. xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
  9425. vctxt->warning, vctxt->errCtxt);
  9426. xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
  9427. vctxt->errCtxt);
  9428. }
  9429. return (0);
  9430. }
  9431. /**
  9432. * xmlSchemaGetSchemaBucket:
  9433. * @pctxt: the schema parser context
  9434. * @schemaLocation: the URI of the schema document
  9435. *
  9436. * Returns a schema bucket if it was already parsed.
  9437. *
  9438. * Returns a schema bucket if it was already parsed from
  9439. * @schemaLocation, NULL otherwise.
  9440. */
  9441. static xmlSchemaBucketPtr
  9442. xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
  9443. const xmlChar *schemaLocation)
  9444. {
  9445. xmlSchemaBucketPtr cur;
  9446. xmlSchemaItemListPtr list;
  9447. list = pctxt->constructor->buckets;
  9448. if (list->nbItems == 0)
  9449. return(NULL);
  9450. else {
  9451. int i;
  9452. for (i = 0; i < list->nbItems; i++) {
  9453. cur = (xmlSchemaBucketPtr) list->items[i];
  9454. /* Pointer comparison! */
  9455. if (cur->schemaLocation == schemaLocation)
  9456. return(cur);
  9457. }
  9458. }
  9459. return(NULL);
  9460. }
  9461. static xmlSchemaBucketPtr
  9462. xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
  9463. const xmlChar *schemaLocation,
  9464. const xmlChar *targetNamespace)
  9465. {
  9466. xmlSchemaBucketPtr cur;
  9467. xmlSchemaItemListPtr list;
  9468. list = pctxt->constructor->buckets;
  9469. if (list->nbItems == 0)
  9470. return(NULL);
  9471. else {
  9472. int i;
  9473. for (i = 0; i < list->nbItems; i++) {
  9474. cur = (xmlSchemaBucketPtr) list->items[i];
  9475. /* Pointer comparison! */
  9476. if ((cur->origTargetNamespace == NULL) &&
  9477. (cur->schemaLocation == schemaLocation) &&
  9478. (cur->targetNamespace == targetNamespace))
  9479. return(cur);
  9480. }
  9481. }
  9482. return(NULL);
  9483. }
  9484. #define IS_BAD_SCHEMA_DOC(b) \
  9485. (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
  9486. static xmlSchemaBucketPtr
  9487. xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
  9488. const xmlChar *targetNamespace,
  9489. int imported)
  9490. {
  9491. xmlSchemaBucketPtr cur;
  9492. xmlSchemaItemListPtr list;
  9493. list = pctxt->constructor->buckets;
  9494. if (list->nbItems == 0)
  9495. return(NULL);
  9496. else {
  9497. int i;
  9498. for (i = 0; i < list->nbItems; i++) {
  9499. cur = (xmlSchemaBucketPtr) list->items[i];
  9500. if ((! IS_BAD_SCHEMA_DOC(cur)) &&
  9501. (cur->origTargetNamespace == targetNamespace) &&
  9502. ((imported && cur->imported) ||
  9503. ((!imported) && (!cur->imported))))
  9504. return(cur);
  9505. }
  9506. }
  9507. return(NULL);
  9508. }
  9509. static int
  9510. xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
  9511. xmlSchemaPtr schema,
  9512. xmlSchemaBucketPtr bucket)
  9513. {
  9514. int oldFlags;
  9515. xmlDocPtr oldDoc;
  9516. xmlNodePtr node;
  9517. int ret, oldErrs;
  9518. xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
  9519. /*
  9520. * Save old values; reset the *main* schema.
  9521. * URGENT TODO: This is not good; move the per-document information
  9522. * to the parser. Get rid of passing the main schema to the
  9523. * parsing functions.
  9524. */
  9525. oldFlags = schema->flags;
  9526. oldDoc = schema->doc;
  9527. if (schema->flags != 0)
  9528. xmlSchemaClearSchemaDefaults(schema);
  9529. schema->doc = bucket->doc;
  9530. pctxt->schema = schema;
  9531. /*
  9532. * Keep the current target namespace on the parser *not* on the
  9533. * main schema.
  9534. */
  9535. pctxt->targetNamespace = bucket->targetNamespace;
  9536. WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
  9537. if ((bucket->targetNamespace != NULL) &&
  9538. xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
  9539. /*
  9540. * We are parsing the schema for schemas!
  9541. */
  9542. pctxt->isS4S = 1;
  9543. }
  9544. /* Mark it as parsed, even if parsing fails. */
  9545. bucket->parsed++;
  9546. /* Compile the schema doc. */
  9547. node = xmlDocGetRootElement(bucket->doc);
  9548. ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
  9549. if (ret != 0)
  9550. goto exit;
  9551. /* An empty schema; just get out. */
  9552. if (node->children == NULL)
  9553. goto exit;
  9554. oldErrs = pctxt->nberrors;
  9555. ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
  9556. if (ret != 0)
  9557. goto exit;
  9558. /*
  9559. * TODO: Not nice, but I'm not 100% sure we will get always an error
  9560. * as a result of the above functions; so better rely on pctxt->err
  9561. * as well.
  9562. */
  9563. if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
  9564. ret = pctxt->err;
  9565. goto exit;
  9566. }
  9567. exit:
  9568. WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
  9569. /* Restore schema values. */
  9570. schema->doc = oldDoc;
  9571. schema->flags = oldFlags;
  9572. return(ret);
  9573. }
  9574. static int
  9575. xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
  9576. xmlSchemaPtr schema,
  9577. xmlSchemaBucketPtr bucket)
  9578. {
  9579. xmlSchemaParserCtxtPtr newpctxt;
  9580. int res = 0;
  9581. if (bucket == NULL)
  9582. return(0);
  9583. if (bucket->parsed) {
  9584. PERROR_INT("xmlSchemaParseNewDoc",
  9585. "reparsing a schema doc");
  9586. return(-1);
  9587. }
  9588. if (bucket->doc == NULL) {
  9589. PERROR_INT("xmlSchemaParseNewDoc",
  9590. "parsing a schema doc, but there's no doc");
  9591. return(-1);
  9592. }
  9593. if (pctxt->constructor == NULL) {
  9594. PERROR_INT("xmlSchemaParseNewDoc",
  9595. "no constructor");
  9596. return(-1);
  9597. }
  9598. /* Create and init the temporary parser context. */
  9599. newpctxt = xmlSchemaNewParserCtxtUseDict(
  9600. (const char *) bucket->schemaLocation, pctxt->dict);
  9601. if (newpctxt == NULL)
  9602. return(-1);
  9603. newpctxt->constructor = pctxt->constructor;
  9604. /*
  9605. * TODO: Can we avoid that the parser knows about the main schema?
  9606. * It would be better if he knows about the current schema bucket
  9607. * only.
  9608. */
  9609. newpctxt->schema = schema;
  9610. xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
  9611. pctxt->errCtxt);
  9612. xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
  9613. pctxt->errCtxt);
  9614. newpctxt->counter = pctxt->counter;
  9615. res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
  9616. /* Channel back errors and cleanup the temporary parser context. */
  9617. if (res != 0)
  9618. pctxt->err = res;
  9619. pctxt->nberrors += newpctxt->nberrors;
  9620. pctxt->counter = newpctxt->counter;
  9621. newpctxt->constructor = NULL;
  9622. /* Free the parser context. */
  9623. xmlSchemaFreeParserCtxt(newpctxt);
  9624. return(res);
  9625. }
  9626. static void
  9627. xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
  9628. xmlSchemaSchemaRelationPtr rel)
  9629. {
  9630. xmlSchemaSchemaRelationPtr cur = bucket->relations;
  9631. if (cur == NULL) {
  9632. bucket->relations = rel;
  9633. return;
  9634. }
  9635. while (cur->next != NULL)
  9636. cur = cur->next;
  9637. cur->next = rel;
  9638. }
  9639. static const xmlChar *
  9640. xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
  9641. xmlNodePtr ctxtNode)
  9642. {
  9643. /*
  9644. * Build an absolute location URI.
  9645. */
  9646. if (location != NULL) {
  9647. if (ctxtNode == NULL)
  9648. return(location);
  9649. else {
  9650. xmlChar *base, *URI;
  9651. const xmlChar *ret = NULL;
  9652. base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
  9653. if (base == NULL) {
  9654. URI = xmlBuildURI(location, ctxtNode->doc->URL);
  9655. } else {
  9656. URI = xmlBuildURI(location, base);
  9657. xmlFree(base);
  9658. }
  9659. if (URI != NULL) {
  9660. ret = xmlDictLookup(dict, URI, -1);
  9661. xmlFree(URI);
  9662. return(ret);
  9663. }
  9664. }
  9665. }
  9666. return(NULL);
  9667. }
  9668. /**
  9669. * xmlSchemaAddSchemaDoc:
  9670. * @pctxt: a schema validation context
  9671. * @schema: the schema being built
  9672. * @node: a subtree containing XML Schema information
  9673. *
  9674. * Parse an included (and to-be-redefined) XML schema document.
  9675. *
  9676. * Returns 0 on success, a positive error code on errors and
  9677. * -1 in case of an internal or API error.
  9678. */
  9679. static int
  9680. xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
  9681. int type, /* import or include or redefine */
  9682. const xmlChar *schemaLocation,
  9683. xmlDocPtr schemaDoc,
  9684. const char *schemaBuffer,
  9685. int schemaBufferLen,
  9686. xmlNodePtr invokingNode,
  9687. const xmlChar *sourceTargetNamespace,
  9688. const xmlChar *importNamespace,
  9689. xmlSchemaBucketPtr *bucket)
  9690. {
  9691. const xmlChar *targetNamespace = NULL;
  9692. xmlSchemaSchemaRelationPtr relation = NULL;
  9693. xmlDocPtr doc = NULL;
  9694. int res = 0, err = 0, located = 0, preserveDoc = 0;
  9695. xmlSchemaBucketPtr bkt = NULL;
  9696. if (bucket != NULL)
  9697. *bucket = NULL;
  9698. switch (type) {
  9699. case XML_SCHEMA_SCHEMA_IMPORT:
  9700. case XML_SCHEMA_SCHEMA_MAIN:
  9701. err = XML_SCHEMAP_SRC_IMPORT;
  9702. break;
  9703. case XML_SCHEMA_SCHEMA_INCLUDE:
  9704. err = XML_SCHEMAP_SRC_INCLUDE;
  9705. break;
  9706. case XML_SCHEMA_SCHEMA_REDEFINE:
  9707. err = XML_SCHEMAP_SRC_REDEFINE;
  9708. break;
  9709. }
  9710. /* Special handling for the main schema:
  9711. * skip the location and relation logic and just parse the doc.
  9712. * We need just a bucket to be returned in this case.
  9713. */
  9714. if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
  9715. goto doc_load;
  9716. /* Note that we expect the location to be an absolute URI. */
  9717. if (schemaLocation != NULL) {
  9718. bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
  9719. if ((bkt != NULL) &&
  9720. (pctxt->constructor->bucket == bkt)) {
  9721. /* Report self-imports/inclusions/redefinitions. */
  9722. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9723. invokingNode, NULL,
  9724. "The schema must not import/include/redefine itself",
  9725. NULL, NULL);
  9726. goto exit;
  9727. }
  9728. }
  9729. /*
  9730. * Create a relation for the graph of schemas.
  9731. */
  9732. relation = xmlSchemaSchemaRelationCreate();
  9733. if (relation == NULL)
  9734. return(-1);
  9735. xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
  9736. relation);
  9737. relation->type = type;
  9738. /*
  9739. * Save the namespace import information.
  9740. */
  9741. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  9742. relation->importNamespace = importNamespace;
  9743. if (schemaLocation == NULL) {
  9744. /*
  9745. * No location; this is just an import of the namespace.
  9746. * Note that we don't assign a bucket to the relation
  9747. * in this case.
  9748. */
  9749. goto exit;
  9750. }
  9751. targetNamespace = importNamespace;
  9752. }
  9753. /* Did we already fetch the doc? */
  9754. if (bkt != NULL) {
  9755. if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
  9756. /*
  9757. * We included/redefined and then try to import a schema,
  9758. * but the new location provided for import was different.
  9759. */
  9760. if (schemaLocation == NULL)
  9761. schemaLocation = BAD_CAST "in_memory_buffer";
  9762. if (!xmlStrEqual(schemaLocation,
  9763. bkt->schemaLocation)) {
  9764. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9765. invokingNode, NULL,
  9766. "The schema document '%s' cannot be imported, since "
  9767. "it was already included or redefined",
  9768. schemaLocation, NULL);
  9769. goto exit;
  9770. }
  9771. } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
  9772. /*
  9773. * We imported and then try to include/redefine a schema,
  9774. * but the new location provided for the include/redefine
  9775. * was different.
  9776. */
  9777. if (schemaLocation == NULL)
  9778. schemaLocation = BAD_CAST "in_memory_buffer";
  9779. if (!xmlStrEqual(schemaLocation,
  9780. bkt->schemaLocation)) {
  9781. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9782. invokingNode, NULL,
  9783. "The schema document '%s' cannot be included or "
  9784. "redefined, since it was already imported",
  9785. schemaLocation, NULL);
  9786. goto exit;
  9787. }
  9788. }
  9789. }
  9790. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  9791. /*
  9792. * Given that the schemaLocation [attribute] is only a hint, it is open
  9793. * to applications to ignore all but the first <import> for a given
  9794. * namespace, regardless of the `actual value` of schemaLocation, but
  9795. * such a strategy risks missing useful information when new
  9796. * schemaLocations are offered.
  9797. *
  9798. * We will use the first <import> that comes with a location.
  9799. * Further <import>s *with* a location, will result in an error.
  9800. * TODO: Better would be to just report a warning here, but
  9801. * we'll try it this way until someone complains.
  9802. *
  9803. * Schema Document Location Strategy:
  9804. * 3 Based on the namespace name, identify an existing schema document,
  9805. * either as a resource which is an XML document or a <schema> element
  9806. * information item, in some local schema repository;
  9807. * 5 Attempt to resolve the namespace name to locate such a resource.
  9808. *
  9809. * NOTE: (3) and (5) are not supported.
  9810. */
  9811. if (bkt != NULL) {
  9812. relation->bucket = bkt;
  9813. goto exit;
  9814. }
  9815. bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
  9816. importNamespace, 1);
  9817. if (bkt != NULL) {
  9818. relation->bucket = bkt;
  9819. if (bkt->schemaLocation == NULL) {
  9820. /* First given location of the schema; load the doc. */
  9821. bkt->schemaLocation = schemaLocation;
  9822. } else {
  9823. if (!xmlStrEqual(schemaLocation,
  9824. bkt->schemaLocation)) {
  9825. /*
  9826. * Additional location given; just skip it.
  9827. * URGENT TODO: We should report a warning here.
  9828. * res = XML_SCHEMAP_SRC_IMPORT;
  9829. */
  9830. if (schemaLocation == NULL)
  9831. schemaLocation = BAD_CAST "in_memory_buffer";
  9832. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  9833. XML_SCHEMAP_WARN_SKIP_SCHEMA,
  9834. invokingNode, NULL,
  9835. "Skipping import of schema located at '%s' for the "
  9836. "namespace '%s', since this namespace was already "
  9837. "imported with the schema located at '%s'",
  9838. schemaLocation, importNamespace, bkt->schemaLocation);
  9839. }
  9840. goto exit;
  9841. }
  9842. }
  9843. /*
  9844. * No bucket + first location: load the doc and create a
  9845. * bucket.
  9846. */
  9847. } else {
  9848. /* <include> and <redefine> */
  9849. if (bkt != NULL) {
  9850. if ((bkt->origTargetNamespace == NULL) &&
  9851. (bkt->targetNamespace != sourceTargetNamespace)) {
  9852. xmlSchemaBucketPtr chamel;
  9853. /*
  9854. * Chameleon include/redefine: skip loading only if it was
  9855. * already build for the targetNamespace of the including
  9856. * schema.
  9857. */
  9858. /*
  9859. * URGENT TODO: If the schema is a chameleon-include then copy
  9860. * the components into the including schema and modify the
  9861. * targetNamespace of those components, do nothing otherwise.
  9862. * NOTE: This is currently worked-around by compiling the
  9863. * chameleon for every distinct including targetNamespace; thus
  9864. * not performant at the moment.
  9865. * TODO: Check when the namespace in wildcards for chameleons
  9866. * needs to be converted: before we built wildcard intersections
  9867. * or after.
  9868. * Answer: after!
  9869. */
  9870. chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
  9871. schemaLocation, sourceTargetNamespace);
  9872. if (chamel != NULL) {
  9873. /* A fitting chameleon was already parsed; NOP. */
  9874. relation->bucket = chamel;
  9875. goto exit;
  9876. }
  9877. /*
  9878. * We need to parse the chameleon again for a different
  9879. * targetNamespace.
  9880. * CHAMELEON TODO: Optimize this by only parsing the
  9881. * chameleon once, and then copying the components to
  9882. * the new targetNamespace.
  9883. */
  9884. bkt = NULL;
  9885. } else {
  9886. relation->bucket = bkt;
  9887. goto exit;
  9888. }
  9889. }
  9890. }
  9891. if ((bkt != NULL) && (bkt->doc != NULL)) {
  9892. PERROR_INT("xmlSchemaAddSchemaDoc",
  9893. "trying to load a schema doc, but a doc is already "
  9894. "assigned to the schema bucket");
  9895. goto exit_failure;
  9896. }
  9897. doc_load:
  9898. /*
  9899. * Load the document.
  9900. */
  9901. if (schemaDoc != NULL) {
  9902. doc = schemaDoc;
  9903. /* Don' free this one, since it was provided by the caller. */
  9904. preserveDoc = 1;
  9905. /* TODO: Does the context or the doc hold the location? */
  9906. if (schemaDoc->URL != NULL)
  9907. schemaLocation = xmlDictLookup(pctxt->dict,
  9908. schemaDoc->URL, -1);
  9909. else
  9910. schemaLocation = BAD_CAST "in_memory_buffer";
  9911. } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
  9912. xmlParserCtxtPtr parserCtxt;
  9913. parserCtxt = xmlNewParserCtxt();
  9914. if (parserCtxt == NULL) {
  9915. xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
  9916. "allocating a parser context", NULL);
  9917. goto exit_failure;
  9918. }
  9919. if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
  9920. /*
  9921. * TODO: Do we have to burden the schema parser dict with all
  9922. * the content of the schema doc?
  9923. */
  9924. xmlDictFree(parserCtxt->dict);
  9925. parserCtxt->dict = pctxt->dict;
  9926. xmlDictReference(parserCtxt->dict);
  9927. }
  9928. if (schemaLocation != NULL) {
  9929. /* Parse from file. */
  9930. doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
  9931. NULL, SCHEMAS_PARSE_OPTIONS);
  9932. } else if (schemaBuffer != NULL) {
  9933. /* Parse from memory buffer. */
  9934. doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
  9935. NULL, NULL, SCHEMAS_PARSE_OPTIONS);
  9936. schemaLocation = BAD_CAST "in_memory_buffer";
  9937. if (doc != NULL)
  9938. doc->URL = xmlStrdup(schemaLocation);
  9939. }
  9940. /*
  9941. * For <import>:
  9942. * 2.1 The referent is (a fragment of) a resource which is an
  9943. * XML document (see clause 1.1), which in turn corresponds to
  9944. * a <schema> element information item in a well-formed information
  9945. * set, which in turn corresponds to a valid schema.
  9946. * TODO: (2.1) fragments of XML documents are not supported.
  9947. *
  9948. * 2.2 The referent is a <schema> element information item in
  9949. * a well-formed information set, which in turn corresponds
  9950. * to a valid schema.
  9951. * TODO: (2.2) is not supported.
  9952. */
  9953. if (doc == NULL) {
  9954. xmlErrorPtr lerr;
  9955. lerr = xmlGetLastError();
  9956. /*
  9957. * Check if this a parser error, or if the document could
  9958. * just not be located.
  9959. * TODO: Try to find specific error codes to react only on
  9960. * localisation failures.
  9961. */
  9962. if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
  9963. /*
  9964. * We assume a parser error here.
  9965. */
  9966. located = 1;
  9967. /* TODO: Error code ?? */
  9968. res = XML_SCHEMAP_SRC_IMPORT_2_1;
  9969. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  9970. invokingNode, NULL,
  9971. "Failed to parse the XML resource '%s'",
  9972. schemaLocation, NULL);
  9973. }
  9974. }
  9975. xmlFreeParserCtxt(parserCtxt);
  9976. if ((doc == NULL) && located)
  9977. goto exit_error;
  9978. } else {
  9979. xmlSchemaPErr(pctxt, NULL,
  9980. XML_SCHEMAP_NOTHING_TO_PARSE,
  9981. "No information for parsing was provided with the "
  9982. "given schema parser context.\n",
  9983. NULL, NULL);
  9984. goto exit_failure;
  9985. }
  9986. /*
  9987. * Preprocess the document.
  9988. */
  9989. if (doc != NULL) {
  9990. xmlNodePtr docElem = NULL;
  9991. located = 1;
  9992. docElem = xmlDocGetRootElement(doc);
  9993. if (docElem == NULL) {
  9994. xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
  9995. invokingNode, NULL,
  9996. "The document '%s' has no document element",
  9997. schemaLocation, NULL);
  9998. goto exit_error;
  9999. }
  10000. /*
  10001. * Remove all the blank text nodes.
  10002. */
  10003. xmlSchemaCleanupDoc(pctxt, docElem);
  10004. /*
  10005. * Check the schema's top level element.
  10006. */
  10007. if (!IS_SCHEMA(docElem, "schema")) {
  10008. xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
  10009. invokingNode, NULL,
  10010. "The XML document '%s' is not a schema document",
  10011. schemaLocation, NULL);
  10012. goto exit_error;
  10013. }
  10014. /*
  10015. * Note that we don't apply a type check for the
  10016. * targetNamespace value here.
  10017. */
  10018. targetNamespace = xmlSchemaGetProp(pctxt, docElem,
  10019. "targetNamespace");
  10020. }
  10021. /* after_doc_loading: */
  10022. if ((bkt == NULL) && located) {
  10023. /* Only create a bucket if the schema was located. */
  10024. bkt = xmlSchemaBucketCreate(pctxt, type,
  10025. targetNamespace);
  10026. if (bkt == NULL)
  10027. goto exit_failure;
  10028. }
  10029. if (bkt != NULL) {
  10030. bkt->schemaLocation = schemaLocation;
  10031. bkt->located = located;
  10032. if (doc != NULL) {
  10033. bkt->doc = doc;
  10034. bkt->targetNamespace = targetNamespace;
  10035. bkt->origTargetNamespace = targetNamespace;
  10036. if (preserveDoc)
  10037. bkt->preserveDoc = 1;
  10038. }
  10039. if (WXS_IS_BUCKET_IMPMAIN(type))
  10040. bkt->imported++;
  10041. /*
  10042. * Add it to the graph of schemas.
  10043. */
  10044. if (relation != NULL)
  10045. relation->bucket = bkt;
  10046. }
  10047. exit:
  10048. /*
  10049. * Return the bucket explicitly; this is needed for the
  10050. * main schema.
  10051. */
  10052. if (bucket != NULL)
  10053. *bucket = bkt;
  10054. return (0);
  10055. exit_error:
  10056. if ((doc != NULL) && (! preserveDoc)) {
  10057. xmlFreeDoc(doc);
  10058. if (bkt != NULL)
  10059. bkt->doc = NULL;
  10060. }
  10061. return(pctxt->err);
  10062. exit_failure:
  10063. if ((doc != NULL) && (! preserveDoc)) {
  10064. xmlFreeDoc(doc);
  10065. if (bkt != NULL)
  10066. bkt->doc = NULL;
  10067. }
  10068. return (-1);
  10069. }
  10070. /**
  10071. * xmlSchemaParseImport:
  10072. * @ctxt: a schema validation context
  10073. * @schema: the schema being built
  10074. * @node: a subtree containing XML Schema information
  10075. *
  10076. * parse a XML schema Import definition
  10077. * *WARNING* this interface is highly subject to change
  10078. *
  10079. * Returns 0 in case of success, a positive error code if
  10080. * not valid and -1 in case of an internal error.
  10081. */
  10082. static int
  10083. xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10084. xmlNodePtr node)
  10085. {
  10086. xmlNodePtr child;
  10087. const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
  10088. const xmlChar *thisTargetNamespace;
  10089. xmlAttrPtr attr;
  10090. int ret = 0;
  10091. xmlSchemaBucketPtr bucket = NULL;
  10092. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  10093. return (-1);
  10094. /*
  10095. * Check for illegal attributes.
  10096. */
  10097. attr = node->properties;
  10098. while (attr != NULL) {
  10099. if (attr->ns == NULL) {
  10100. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10101. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  10102. (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
  10103. xmlSchemaPIllegalAttrErr(pctxt,
  10104. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10105. }
  10106. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10107. xmlSchemaPIllegalAttrErr(pctxt,
  10108. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10109. }
  10110. attr = attr->next;
  10111. }
  10112. /*
  10113. * Extract and validate attributes.
  10114. */
  10115. if (xmlSchemaPValAttr(pctxt, NULL, node,
  10116. "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10117. &namespaceName) != 0) {
  10118. xmlSchemaPSimpleTypeErr(pctxt,
  10119. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  10120. NULL, node,
  10121. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10122. NULL, namespaceName, NULL, NULL, NULL);
  10123. return (pctxt->err);
  10124. }
  10125. if (xmlSchemaPValAttr(pctxt, NULL, node,
  10126. "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10127. &schemaLocation) != 0) {
  10128. xmlSchemaPSimpleTypeErr(pctxt,
  10129. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  10130. NULL, node,
  10131. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10132. NULL, schemaLocation, NULL, NULL, NULL);
  10133. return (pctxt->err);
  10134. }
  10135. /*
  10136. * And now for the children...
  10137. */
  10138. child = node->children;
  10139. if (IS_SCHEMA(child, "annotation")) {
  10140. /*
  10141. * the annotation here is simply discarded ...
  10142. * TODO: really?
  10143. */
  10144. child = child->next;
  10145. }
  10146. if (child != NULL) {
  10147. xmlSchemaPContentErr(pctxt,
  10148. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10149. NULL, node, child, NULL,
  10150. "(annotation?)");
  10151. }
  10152. /*
  10153. * Apply additional constraints.
  10154. *
  10155. * Note that it is important to use the original @targetNamespace
  10156. * (or none at all), to rule out imports of schemas _with_ a
  10157. * @targetNamespace if the importing schema is a chameleon schema
  10158. * (with no @targetNamespace).
  10159. */
  10160. thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
  10161. if (namespaceName != NULL) {
  10162. /*
  10163. * 1.1 If the namespace [attribute] is present, then its `actual value`
  10164. * must not match the `actual value` of the enclosing <schema>'s
  10165. * targetNamespace [attribute].
  10166. */
  10167. if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
  10168. xmlSchemaPCustomErr(pctxt,
  10169. XML_SCHEMAP_SRC_IMPORT_1_1,
  10170. NULL, node,
  10171. "The value of the attribute 'namespace' must not match "
  10172. "the target namespace '%s' of the importing schema",
  10173. thisTargetNamespace);
  10174. return (pctxt->err);
  10175. }
  10176. } else {
  10177. /*
  10178. * 1.2 If the namespace [attribute] is not present, then the enclosing
  10179. * <schema> must have a targetNamespace [attribute].
  10180. */
  10181. if (thisTargetNamespace == NULL) {
  10182. xmlSchemaPCustomErr(pctxt,
  10183. XML_SCHEMAP_SRC_IMPORT_1_2,
  10184. NULL, node,
  10185. "The attribute 'namespace' must be existent if "
  10186. "the importing schema has no target namespace",
  10187. NULL);
  10188. return (pctxt->err);
  10189. }
  10190. }
  10191. /*
  10192. * Locate and acquire the schema document.
  10193. */
  10194. if (schemaLocation != NULL)
  10195. schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
  10196. schemaLocation, node);
  10197. ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
  10198. schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
  10199. namespaceName, &bucket);
  10200. if (ret != 0)
  10201. return(ret);
  10202. /*
  10203. * For <import>: "It is *not* an error for the application
  10204. * schema reference strategy to fail."
  10205. * So just don't parse if no schema document was found.
  10206. * Note that we will get no bucket if the schema could not be
  10207. * located or if there was no schemaLocation.
  10208. */
  10209. if ((bucket == NULL) && (schemaLocation != NULL)) {
  10210. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  10211. XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
  10212. node, NULL,
  10213. "Failed to locate a schema at location '%s'. "
  10214. "Skipping the import", schemaLocation, NULL, NULL);
  10215. }
  10216. if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
  10217. ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
  10218. }
  10219. return (ret);
  10220. }
  10221. static int
  10222. xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
  10223. xmlSchemaPtr schema,
  10224. xmlNodePtr node,
  10225. xmlChar **schemaLocation,
  10226. int type)
  10227. {
  10228. xmlAttrPtr attr;
  10229. if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
  10230. (schemaLocation == NULL))
  10231. return (-1);
  10232. *schemaLocation = NULL;
  10233. /*
  10234. * Check for illegal attributes.
  10235. * Applies for both <include> and <redefine>.
  10236. */
  10237. attr = node->properties;
  10238. while (attr != NULL) {
  10239. if (attr->ns == NULL) {
  10240. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10241. (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
  10242. xmlSchemaPIllegalAttrErr(pctxt,
  10243. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10244. }
  10245. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10246. xmlSchemaPIllegalAttrErr(pctxt,
  10247. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10248. }
  10249. attr = attr->next;
  10250. }
  10251. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  10252. /*
  10253. * Preliminary step, extract the URI-Reference and make an URI
  10254. * from the base.
  10255. */
  10256. /*
  10257. * Attribute "schemaLocation" is mandatory.
  10258. */
  10259. attr = xmlSchemaGetPropNode(node, "schemaLocation");
  10260. if (attr != NULL) {
  10261. xmlChar *base = NULL;
  10262. xmlChar *uri = NULL;
  10263. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  10264. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10265. (const xmlChar **) schemaLocation) != 0)
  10266. goto exit_error;
  10267. base = xmlNodeGetBase(node->doc, node);
  10268. if (base == NULL) {
  10269. uri = xmlBuildURI(*schemaLocation, node->doc->URL);
  10270. } else {
  10271. uri = xmlBuildURI(*schemaLocation, base);
  10272. xmlFree(base);
  10273. }
  10274. if (uri == NULL) {
  10275. PERROR_INT("xmlSchemaParseIncludeOrRedefine",
  10276. "could not build an URI from the schemaLocation")
  10277. goto exit_failure;
  10278. }
  10279. (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
  10280. xmlFree(uri);
  10281. } else {
  10282. xmlSchemaPMissingAttrErr(pctxt,
  10283. XML_SCHEMAP_S4S_ATTR_MISSING,
  10284. NULL, node, "schemaLocation", NULL);
  10285. goto exit_error;
  10286. }
  10287. /*
  10288. * Report self-inclusion and self-redefinition.
  10289. */
  10290. if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
  10291. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10292. xmlSchemaPCustomErr(pctxt,
  10293. XML_SCHEMAP_SRC_REDEFINE,
  10294. NULL, node,
  10295. "The schema document '%s' cannot redefine itself.",
  10296. *schemaLocation);
  10297. } else {
  10298. xmlSchemaPCustomErr(pctxt,
  10299. XML_SCHEMAP_SRC_INCLUDE,
  10300. NULL, node,
  10301. "The schema document '%s' cannot include itself.",
  10302. *schemaLocation);
  10303. }
  10304. goto exit_error;
  10305. }
  10306. return(0);
  10307. exit_error:
  10308. return(pctxt->err);
  10309. exit_failure:
  10310. return(-1);
  10311. }
  10312. static int
  10313. xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
  10314. xmlSchemaPtr schema,
  10315. xmlNodePtr node,
  10316. int type)
  10317. {
  10318. xmlNodePtr child = NULL;
  10319. const xmlChar *schemaLocation = NULL;
  10320. int res = 0; /* hasRedefinitions = 0 */
  10321. int isChameleon = 0, wasChameleon = 0;
  10322. xmlSchemaBucketPtr bucket = NULL;
  10323. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  10324. return (-1);
  10325. /*
  10326. * Parse attributes. Note that the returned schemaLocation will
  10327. * be already converted to an absolute URI.
  10328. */
  10329. res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
  10330. node, (xmlChar **) (&schemaLocation), type);
  10331. if (res != 0)
  10332. return(res);
  10333. /*
  10334. * Load and add the schema document.
  10335. */
  10336. res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
  10337. NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
  10338. if (res != 0)
  10339. return(res);
  10340. /*
  10341. * If we get no schema bucket back, then this means that the schema
  10342. * document could not be located or was broken XML or was not
  10343. * a schema document.
  10344. */
  10345. if ((bucket == NULL) || (bucket->doc == NULL)) {
  10346. if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
  10347. /*
  10348. * WARNING for <include>:
  10349. * We will raise an error if the schema cannot be located
  10350. * for inclusions, since the that was the feedback from the
  10351. * schema people. I.e. the following spec piece will *not* be
  10352. * satisfied:
  10353. * SPEC src-include: "It is not an error for the `actual value` of the
  10354. * schemaLocation [attribute] to fail to resolve it all, in which
  10355. * case no corresponding inclusion is performed.
  10356. * So do we need a warning report here?"
  10357. */
  10358. res = XML_SCHEMAP_SRC_INCLUDE;
  10359. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  10360. node, NULL,
  10361. "Failed to load the document '%s' for inclusion",
  10362. schemaLocation, NULL);
  10363. } else {
  10364. /*
  10365. * NOTE: This was changed to raise an error even if no redefinitions
  10366. * are specified.
  10367. *
  10368. * SPEC src-redefine (1)
  10369. * "If there are any element information items among the [children]
  10370. * other than <annotation> then the `actual value` of the
  10371. * schemaLocation [attribute] must successfully resolve."
  10372. * TODO: Ask the WG if a the location has always to resolve
  10373. * here as well!
  10374. */
  10375. res = XML_SCHEMAP_SRC_REDEFINE;
  10376. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  10377. node, NULL,
  10378. "Failed to load the document '%s' for redefinition",
  10379. schemaLocation, NULL);
  10380. }
  10381. } else {
  10382. /*
  10383. * Check targetNamespace sanity before parsing the new schema.
  10384. * TODO: Note that we won't check further content if the
  10385. * targetNamespace was bad.
  10386. */
  10387. if (bucket->origTargetNamespace != NULL) {
  10388. /*
  10389. * SPEC src-include (2.1)
  10390. * "SII has a targetNamespace [attribute], and its `actual
  10391. * value` is identical to the `actual value` of the targetNamespace
  10392. * [attribute] of SII' (which must have such an [attribute])."
  10393. */
  10394. if (pctxt->targetNamespace == NULL) {
  10395. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  10396. XML_SCHEMAP_SRC_INCLUDE,
  10397. node, NULL,
  10398. "The target namespace of the included/redefined schema "
  10399. "'%s' has to be absent, since the including/redefining "
  10400. "schema has no target namespace",
  10401. schemaLocation, NULL);
  10402. goto exit_error;
  10403. } else if (!xmlStrEqual(bucket->origTargetNamespace,
  10404. pctxt->targetNamespace)) {
  10405. /* TODO: Change error function. */
  10406. xmlSchemaPCustomErrExt(pctxt,
  10407. XML_SCHEMAP_SRC_INCLUDE,
  10408. NULL, node,
  10409. "The target namespace '%s' of the included/redefined "
  10410. "schema '%s' differs from '%s' of the "
  10411. "including/redefining schema",
  10412. bucket->origTargetNamespace, schemaLocation,
  10413. pctxt->targetNamespace);
  10414. goto exit_error;
  10415. }
  10416. } else if (pctxt->targetNamespace != NULL) {
  10417. /*
  10418. * Chameleons: the original target namespace will
  10419. * differ from the resulting namespace.
  10420. */
  10421. isChameleon = 1;
  10422. if (bucket->parsed &&
  10423. bucket->origTargetNamespace != NULL) {
  10424. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  10425. XML_SCHEMAP_SRC_INCLUDE,
  10426. node, NULL,
  10427. "The target namespace of the included/redefined schema "
  10428. "'%s' has to be absent or the same as the "
  10429. "including/redefining schema's target namespace",
  10430. schemaLocation, NULL);
  10431. goto exit_error;
  10432. }
  10433. bucket->targetNamespace = pctxt->targetNamespace;
  10434. }
  10435. }
  10436. /*
  10437. * Parse the schema.
  10438. */
  10439. if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
  10440. if (isChameleon) {
  10441. /* TODO: Get rid of this flag on the schema itself. */
  10442. if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
  10443. schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
  10444. } else
  10445. wasChameleon = 1;
  10446. }
  10447. xmlSchemaParseNewDoc(pctxt, schema, bucket);
  10448. /* Restore chameleon flag. */
  10449. if (isChameleon && (!wasChameleon))
  10450. schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
  10451. }
  10452. /*
  10453. * And now for the children...
  10454. */
  10455. child = node->children;
  10456. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10457. /*
  10458. * Parse (simpleType | complexType | group | attributeGroup))*
  10459. */
  10460. pctxt->redefined = bucket;
  10461. /*
  10462. * How to proceed if the redefined schema was not located?
  10463. */
  10464. pctxt->isRedefine = 1;
  10465. while (IS_SCHEMA(child, "annotation") ||
  10466. IS_SCHEMA(child, "simpleType") ||
  10467. IS_SCHEMA(child, "complexType") ||
  10468. IS_SCHEMA(child, "group") ||
  10469. IS_SCHEMA(child, "attributeGroup")) {
  10470. if (IS_SCHEMA(child, "annotation")) {
  10471. /*
  10472. * TODO: discard or not?
  10473. */
  10474. } else if (IS_SCHEMA(child, "simpleType")) {
  10475. xmlSchemaParseSimpleType(pctxt, schema, child, 1);
  10476. } else if (IS_SCHEMA(child, "complexType")) {
  10477. xmlSchemaParseComplexType(pctxt, schema, child, 1);
  10478. /* hasRedefinitions = 1; */
  10479. } else if (IS_SCHEMA(child, "group")) {
  10480. /* hasRedefinitions = 1; */
  10481. xmlSchemaParseModelGroupDefinition(pctxt,
  10482. schema, child);
  10483. } else if (IS_SCHEMA(child, "attributeGroup")) {
  10484. /* hasRedefinitions = 1; */
  10485. xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
  10486. child);
  10487. }
  10488. child = child->next;
  10489. }
  10490. pctxt->redefined = NULL;
  10491. pctxt->isRedefine = 0;
  10492. } else {
  10493. if (IS_SCHEMA(child, "annotation")) {
  10494. /*
  10495. * TODO: discard or not?
  10496. */
  10497. child = child->next;
  10498. }
  10499. }
  10500. if (child != NULL) {
  10501. res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
  10502. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10503. xmlSchemaPContentErr(pctxt, res,
  10504. NULL, node, child, NULL,
  10505. "(annotation | (simpleType | complexType | group | attributeGroup))*");
  10506. } else {
  10507. xmlSchemaPContentErr(pctxt, res,
  10508. NULL, node, child, NULL,
  10509. "(annotation?)");
  10510. }
  10511. }
  10512. return(res);
  10513. exit_error:
  10514. return(pctxt->err);
  10515. }
  10516. static int
  10517. xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10518. xmlNodePtr node)
  10519. {
  10520. int res;
  10521. #ifndef ENABLE_REDEFINE
  10522. TODO
  10523. return(0);
  10524. #endif
  10525. res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
  10526. XML_SCHEMA_SCHEMA_REDEFINE);
  10527. if (res != 0)
  10528. return(res);
  10529. return(0);
  10530. }
  10531. static int
  10532. xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10533. xmlNodePtr node)
  10534. {
  10535. int res;
  10536. res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
  10537. XML_SCHEMA_SCHEMA_INCLUDE);
  10538. if (res != 0)
  10539. return(res);
  10540. return(0);
  10541. }
  10542. /**
  10543. * xmlSchemaParseModelGroup:
  10544. * @ctxt: a schema validation context
  10545. * @schema: the schema being built
  10546. * @node: a subtree containing XML Schema information
  10547. * @type: the "compositor" type
  10548. * @particleNeeded: if a a model group with a particle
  10549. *
  10550. * parse a XML schema Sequence definition.
  10551. * Applies parts of:
  10552. * Schema Representation Constraint:
  10553. * Redefinition Constraints and Semantics (src-redefine)
  10554. * (6.1), (6.1.1), (6.1.2)
  10555. *
  10556. * Schema Component Constraint:
  10557. * All Group Limited (cos-all-limited) (2)
  10558. * TODO: Actually this should go to component-level checks,
  10559. * but is done here due to performance. Move it to an other layer
  10560. * is schema construction via an API is implemented.
  10561. *
  10562. * *WARNING* this interface is highly subject to change
  10563. *
  10564. * Returns -1 in case of error, 0 if the declaration is improper and
  10565. * 1 in case of success.
  10566. */
  10567. static xmlSchemaTreeItemPtr
  10568. xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  10569. xmlNodePtr node, xmlSchemaTypeType type,
  10570. int withParticle)
  10571. {
  10572. xmlSchemaModelGroupPtr item;
  10573. xmlSchemaParticlePtr particle = NULL;
  10574. xmlNodePtr child = NULL;
  10575. xmlAttrPtr attr;
  10576. int min = 1, max = 1, isElemRef, hasRefs = 0;
  10577. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  10578. return (NULL);
  10579. /*
  10580. * Create a model group with the given compositor.
  10581. */
  10582. item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
  10583. if (item == NULL)
  10584. return (NULL);
  10585. if (withParticle) {
  10586. if (type == XML_SCHEMA_TYPE_ALL) {
  10587. min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
  10588. max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
  10589. } else {
  10590. /* choice + sequence */
  10591. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  10592. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  10593. "(xs:nonNegativeInteger | unbounded)");
  10594. }
  10595. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  10596. /*
  10597. * Create a particle
  10598. */
  10599. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  10600. if (particle == NULL)
  10601. return (NULL);
  10602. particle->children = (xmlSchemaTreeItemPtr) item;
  10603. /*
  10604. * Check for illegal attributes.
  10605. */
  10606. attr = node->properties;
  10607. while (attr != NULL) {
  10608. if (attr->ns == NULL) {
  10609. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10610. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  10611. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
  10612. xmlSchemaPIllegalAttrErr(ctxt,
  10613. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10614. }
  10615. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10616. xmlSchemaPIllegalAttrErr(ctxt,
  10617. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10618. }
  10619. attr = attr->next;
  10620. }
  10621. } else {
  10622. /*
  10623. * Check for illegal attributes.
  10624. */
  10625. attr = node->properties;
  10626. while (attr != NULL) {
  10627. if (attr->ns == NULL) {
  10628. if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
  10629. xmlSchemaPIllegalAttrErr(ctxt,
  10630. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10631. }
  10632. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10633. xmlSchemaPIllegalAttrErr(ctxt,
  10634. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10635. }
  10636. attr = attr->next;
  10637. }
  10638. }
  10639. /*
  10640. * Extract and validate attributes.
  10641. */
  10642. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  10643. /*
  10644. * And now for the children...
  10645. */
  10646. child = node->children;
  10647. if (IS_SCHEMA(child, "annotation")) {
  10648. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  10649. child = child->next;
  10650. }
  10651. if (type == XML_SCHEMA_TYPE_ALL) {
  10652. xmlSchemaParticlePtr part, last = NULL;
  10653. while (IS_SCHEMA(child, "element")) {
  10654. part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
  10655. schema, child, &isElemRef, 0);
  10656. /*
  10657. * SPEC cos-all-limited (2)
  10658. * "The {max occurs} of all the particles in the {particles}
  10659. * of the ('all') group must be 0 or 1.
  10660. */
  10661. if (part != NULL) {
  10662. if (isElemRef)
  10663. hasRefs++;
  10664. if (part->minOccurs > 1) {
  10665. xmlSchemaPCustomErr(ctxt,
  10666. XML_SCHEMAP_COS_ALL_LIMITED,
  10667. NULL, child,
  10668. "Invalid value for minOccurs (must be 0 or 1)",
  10669. NULL);
  10670. /* Reset to 1. */
  10671. part->minOccurs = 1;
  10672. }
  10673. if (part->maxOccurs > 1) {
  10674. xmlSchemaPCustomErr(ctxt,
  10675. XML_SCHEMAP_COS_ALL_LIMITED,
  10676. NULL, child,
  10677. "Invalid value for maxOccurs (must be 0 or 1)",
  10678. NULL);
  10679. /* Reset to 1. */
  10680. part->maxOccurs = 1;
  10681. }
  10682. if (last == NULL)
  10683. item->children = (xmlSchemaTreeItemPtr) part;
  10684. else
  10685. last->next = (xmlSchemaTreeItemPtr) part;
  10686. last = part;
  10687. }
  10688. child = child->next;
  10689. }
  10690. if (child != NULL) {
  10691. xmlSchemaPContentErr(ctxt,
  10692. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10693. NULL, node, child, NULL,
  10694. "(annotation?, (annotation?, element*)");
  10695. }
  10696. } else {
  10697. /* choice + sequence */
  10698. xmlSchemaTreeItemPtr part = NULL, last = NULL;
  10699. while ((IS_SCHEMA(child, "element")) ||
  10700. (IS_SCHEMA(child, "group")) ||
  10701. (IS_SCHEMA(child, "any")) ||
  10702. (IS_SCHEMA(child, "choice")) ||
  10703. (IS_SCHEMA(child, "sequence"))) {
  10704. if (IS_SCHEMA(child, "element")) {
  10705. part = (xmlSchemaTreeItemPtr)
  10706. xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
  10707. if (part && isElemRef)
  10708. hasRefs++;
  10709. } else if (IS_SCHEMA(child, "group")) {
  10710. part =
  10711. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  10712. if (part != NULL)
  10713. hasRefs++;
  10714. /*
  10715. * Handle redefinitions.
  10716. */
  10717. if (ctxt->isRedefine && ctxt->redef &&
  10718. (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
  10719. part && part->children)
  10720. {
  10721. if ((xmlSchemaGetQNameRefName(part->children) ==
  10722. ctxt->redef->refName) &&
  10723. (xmlSchemaGetQNameRefTargetNs(part->children) ==
  10724. ctxt->redef->refTargetNs))
  10725. {
  10726. /*
  10727. * SPEC src-redefine:
  10728. * (6.1) "If it has a <group> among its contents at
  10729. * some level the `actual value` of whose ref
  10730. * [attribute] is the same as the `actual value` of
  10731. * its own name attribute plus target namespace, then
  10732. * all of the following must be true:"
  10733. * (6.1.1) "It must have exactly one such group."
  10734. */
  10735. if (ctxt->redefCounter != 0) {
  10736. xmlChar *str = NULL;
  10737. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  10738. XML_SCHEMAP_SRC_REDEFINE, child, NULL,
  10739. "The redefining model group definition "
  10740. "'%s' must not contain more than one "
  10741. "reference to the redefined definition",
  10742. xmlSchemaFormatQName(&str,
  10743. ctxt->redef->refTargetNs,
  10744. ctxt->redef->refName),
  10745. NULL);
  10746. FREE_AND_NULL(str)
  10747. part = NULL;
  10748. } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
  10749. ((WXS_PARTICLE(part))->maxOccurs != 1))
  10750. {
  10751. xmlChar *str = NULL;
  10752. /*
  10753. * SPEC src-redefine:
  10754. * (6.1.2) "The `actual value` of both that
  10755. * group's minOccurs and maxOccurs [attribute]
  10756. * must be 1 (or `absent`).
  10757. */
  10758. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  10759. XML_SCHEMAP_SRC_REDEFINE, child, NULL,
  10760. "The redefining model group definition "
  10761. "'%s' must not contain a reference to the "
  10762. "redefined definition with a "
  10763. "maxOccurs/minOccurs other than 1",
  10764. xmlSchemaFormatQName(&str,
  10765. ctxt->redef->refTargetNs,
  10766. ctxt->redef->refName),
  10767. NULL);
  10768. FREE_AND_NULL(str)
  10769. part = NULL;
  10770. }
  10771. ctxt->redef->reference = WXS_BASIC_CAST part;
  10772. ctxt->redefCounter++;
  10773. }
  10774. }
  10775. } else if (IS_SCHEMA(child, "any")) {
  10776. part = (xmlSchemaTreeItemPtr)
  10777. xmlSchemaParseAny(ctxt, schema, child);
  10778. } else if (IS_SCHEMA(child, "choice")) {
  10779. part = xmlSchemaParseModelGroup(ctxt, schema, child,
  10780. XML_SCHEMA_TYPE_CHOICE, 1);
  10781. } else if (IS_SCHEMA(child, "sequence")) {
  10782. part = xmlSchemaParseModelGroup(ctxt, schema, child,
  10783. XML_SCHEMA_TYPE_SEQUENCE, 1);
  10784. }
  10785. if (part != NULL) {
  10786. if (last == NULL)
  10787. item->children = part;
  10788. else
  10789. last->next = part;
  10790. last = part;
  10791. }
  10792. child = child->next;
  10793. }
  10794. if (child != NULL) {
  10795. xmlSchemaPContentErr(ctxt,
  10796. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10797. NULL, node, child, NULL,
  10798. "(annotation?, (element | group | choice | sequence | any)*)");
  10799. }
  10800. }
  10801. if ((max == 0) && (min == 0))
  10802. return (NULL);
  10803. if (hasRefs) {
  10804. /*
  10805. * We need to resolve references.
  10806. */
  10807. WXS_ADD_PENDING(ctxt, item);
  10808. }
  10809. if (withParticle)
  10810. return ((xmlSchemaTreeItemPtr) particle);
  10811. else
  10812. return ((xmlSchemaTreeItemPtr) item);
  10813. }
  10814. /**
  10815. * xmlSchemaParseRestriction:
  10816. * @ctxt: a schema validation context
  10817. * @schema: the schema being built
  10818. * @node: a subtree containing XML Schema information
  10819. *
  10820. * parse a XML schema Restriction definition
  10821. * *WARNING* this interface is highly subject to change
  10822. *
  10823. * Returns the type definition or NULL in case of error
  10824. */
  10825. static xmlSchemaTypePtr
  10826. xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  10827. xmlNodePtr node, xmlSchemaTypeType parentType)
  10828. {
  10829. xmlSchemaTypePtr type;
  10830. xmlNodePtr child = NULL;
  10831. xmlAttrPtr attr;
  10832. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  10833. return (NULL);
  10834. /* Not a component, don't create it. */
  10835. type = ctxt->ctxtType;
  10836. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
  10837. /*
  10838. * Check for illegal attributes.
  10839. */
  10840. attr = node->properties;
  10841. while (attr != NULL) {
  10842. if (attr->ns == NULL) {
  10843. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10844. (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
  10845. xmlSchemaPIllegalAttrErr(ctxt,
  10846. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10847. }
  10848. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10849. xmlSchemaPIllegalAttrErr(ctxt,
  10850. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10851. }
  10852. attr = attr->next;
  10853. }
  10854. /*
  10855. * Extract and validate attributes.
  10856. */
  10857. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  10858. /*
  10859. * Attribute
  10860. */
  10861. /*
  10862. * Extract the base type. The "base" attribute is mandatory if inside
  10863. * a complex type or if redefining.
  10864. *
  10865. * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
  10866. * among its [children]), the simple type definition which is
  10867. * the {content type} of the type definition `resolved` to by
  10868. * the `actual value` of the base [attribute]"
  10869. */
  10870. if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
  10871. &(type->baseNs), &(type->base)) == 0)
  10872. {
  10873. if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
  10874. xmlSchemaPMissingAttrErr(ctxt,
  10875. XML_SCHEMAP_S4S_ATTR_MISSING,
  10876. NULL, node, "base", NULL);
  10877. } else if ((ctxt->isRedefine) &&
  10878. (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
  10879. {
  10880. if (type->base == NULL) {
  10881. xmlSchemaPMissingAttrErr(ctxt,
  10882. XML_SCHEMAP_S4S_ATTR_MISSING,
  10883. NULL, node, "base", NULL);
  10884. } else if ((! xmlStrEqual(type->base, type->name)) ||
  10885. (! xmlStrEqual(type->baseNs, type->targetNamespace)))
  10886. {
  10887. xmlChar *str1 = NULL, *str2 = NULL;
  10888. /*
  10889. * REDEFINE: SPEC src-redefine (5)
  10890. * "Within the [children], each <simpleType> must have a
  10891. * <restriction> among its [children] ... the `actual value` of
  10892. * whose base [attribute] must be the same as the `actual value`
  10893. * of its own name attribute plus target namespace;"
  10894. */
  10895. xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  10896. NULL, node, "This is a redefinition, but the QName "
  10897. "value '%s' of the 'base' attribute does not match the "
  10898. "type's designation '%s'",
  10899. xmlSchemaFormatQName(&str1, type->baseNs, type->base),
  10900. xmlSchemaFormatQName(&str2, type->targetNamespace,
  10901. type->name), NULL);
  10902. FREE_AND_NULL(str1);
  10903. FREE_AND_NULL(str2);
  10904. /* Avoid confusion and erase the values. */
  10905. type->base = NULL;
  10906. type->baseNs = NULL;
  10907. }
  10908. }
  10909. }
  10910. /*
  10911. * And now for the children...
  10912. */
  10913. child = node->children;
  10914. if (IS_SCHEMA(child, "annotation")) {
  10915. /*
  10916. * Add the annotation to the simple type ancestor.
  10917. */
  10918. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  10919. xmlSchemaParseAnnotation(ctxt, child, 1));
  10920. child = child->next;
  10921. }
  10922. if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
  10923. /*
  10924. * Corresponds to <simpleType><restriction><simpleType>.
  10925. */
  10926. if (IS_SCHEMA(child, "simpleType")) {
  10927. if (type->base != NULL) {
  10928. /*
  10929. * src-restriction-base-or-simpleType
  10930. * Either the base [attribute] or the simpleType [child] of the
  10931. * <restriction> element must be present, but not both.
  10932. */
  10933. xmlSchemaPContentErr(ctxt,
  10934. XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
  10935. NULL, node, child,
  10936. "The attribute 'base' and the <simpleType> child are "
  10937. "mutually exclusive", NULL);
  10938. } else {
  10939. type->baseType = (xmlSchemaTypePtr)
  10940. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  10941. }
  10942. child = child->next;
  10943. } else if (type->base == NULL) {
  10944. xmlSchemaPContentErr(ctxt,
  10945. XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
  10946. NULL, node, child,
  10947. "Either the attribute 'base' or a <simpleType> child "
  10948. "must be present", NULL);
  10949. }
  10950. } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  10951. /*
  10952. * Corresponds to <complexType><complexContent><restriction>...
  10953. * followed by:
  10954. *
  10955. * Model groups <all>, <choice> and <sequence>.
  10956. */
  10957. if (IS_SCHEMA(child, "all")) {
  10958. type->subtypes = (xmlSchemaTypePtr)
  10959. xmlSchemaParseModelGroup(ctxt, schema, child,
  10960. XML_SCHEMA_TYPE_ALL, 1);
  10961. child = child->next;
  10962. } else if (IS_SCHEMA(child, "choice")) {
  10963. type->subtypes = (xmlSchemaTypePtr)
  10964. xmlSchemaParseModelGroup(ctxt,
  10965. schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
  10966. child = child->next;
  10967. } else if (IS_SCHEMA(child, "sequence")) {
  10968. type->subtypes = (xmlSchemaTypePtr)
  10969. xmlSchemaParseModelGroup(ctxt, schema, child,
  10970. XML_SCHEMA_TYPE_SEQUENCE, 1);
  10971. child = child->next;
  10972. /*
  10973. * Model group reference <group>.
  10974. */
  10975. } else if (IS_SCHEMA(child, "group")) {
  10976. type->subtypes = (xmlSchemaTypePtr)
  10977. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  10978. /*
  10979. * Note that the reference will be resolved in
  10980. * xmlSchemaResolveTypeReferences();
  10981. */
  10982. child = child->next;
  10983. }
  10984. } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
  10985. /*
  10986. * Corresponds to <complexType><simpleContent><restriction>...
  10987. *
  10988. * "1.1 the simple type definition corresponding to the <simpleType>
  10989. * among the [children] of <restriction> if there is one;"
  10990. */
  10991. if (IS_SCHEMA(child, "simpleType")) {
  10992. /*
  10993. * We will store the to-be-restricted simple type in
  10994. * type->contentTypeDef *temporarily*.
  10995. */
  10996. type->contentTypeDef = (xmlSchemaTypePtr)
  10997. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  10998. if ( type->contentTypeDef == NULL)
  10999. return (NULL);
  11000. child = child->next;
  11001. }
  11002. }
  11003. if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
  11004. (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
  11005. xmlSchemaFacetPtr facet, lastfacet = NULL;
  11006. /*
  11007. * Corresponds to <complexType><simpleContent><restriction>...
  11008. * <simpleType><restriction>...
  11009. */
  11010. /*
  11011. * Add the facets to the simple type ancestor.
  11012. */
  11013. /*
  11014. * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
  11015. * Simple Type Definition Schema Representation Constraint:
  11016. * *Single Facet Value*
  11017. */
  11018. while ((IS_SCHEMA(child, "minInclusive")) ||
  11019. (IS_SCHEMA(child, "minExclusive")) ||
  11020. (IS_SCHEMA(child, "maxInclusive")) ||
  11021. (IS_SCHEMA(child, "maxExclusive")) ||
  11022. (IS_SCHEMA(child, "totalDigits")) ||
  11023. (IS_SCHEMA(child, "fractionDigits")) ||
  11024. (IS_SCHEMA(child, "pattern")) ||
  11025. (IS_SCHEMA(child, "enumeration")) ||
  11026. (IS_SCHEMA(child, "whiteSpace")) ||
  11027. (IS_SCHEMA(child, "length")) ||
  11028. (IS_SCHEMA(child, "maxLength")) ||
  11029. (IS_SCHEMA(child, "minLength"))) {
  11030. facet = xmlSchemaParseFacet(ctxt, schema, child);
  11031. if (facet != NULL) {
  11032. if (lastfacet == NULL)
  11033. type->facets = facet;
  11034. else
  11035. lastfacet->next = facet;
  11036. lastfacet = facet;
  11037. lastfacet->next = NULL;
  11038. }
  11039. child = child->next;
  11040. }
  11041. /*
  11042. * Create links for derivation and validation.
  11043. */
  11044. if (type->facets != NULL) {
  11045. xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
  11046. facet = type->facets;
  11047. do {
  11048. facetLink = (xmlSchemaFacetLinkPtr)
  11049. xmlMalloc(sizeof(xmlSchemaFacetLink));
  11050. if (facetLink == NULL) {
  11051. xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
  11052. xmlFree(facetLink);
  11053. return (NULL);
  11054. }
  11055. facetLink->facet = facet;
  11056. facetLink->next = NULL;
  11057. if (lastFacetLink == NULL)
  11058. type->facetSet = facetLink;
  11059. else
  11060. lastFacetLink->next = facetLink;
  11061. lastFacetLink = facetLink;
  11062. facet = facet->next;
  11063. } while (facet != NULL);
  11064. }
  11065. }
  11066. if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
  11067. /*
  11068. * Attribute uses/declarations.
  11069. */
  11070. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11071. (xmlSchemaItemListPtr *) &(type->attrUses),
  11072. XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
  11073. return(NULL);
  11074. /*
  11075. * Attribute wildcard.
  11076. */
  11077. if (IS_SCHEMA(child, "anyAttribute")) {
  11078. type->attributeWildcard =
  11079. xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11080. child = child->next;
  11081. }
  11082. }
  11083. if (child != NULL) {
  11084. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11085. xmlSchemaPContentErr(ctxt,
  11086. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11087. NULL, node, child, NULL,
  11088. "annotation?, (group | all | choice | sequence)?, "
  11089. "((attribute | attributeGroup)*, anyAttribute?))");
  11090. } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
  11091. xmlSchemaPContentErr(ctxt,
  11092. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11093. NULL, node, child, NULL,
  11094. "(annotation?, (simpleType?, (minExclusive | minInclusive | "
  11095. "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
  11096. "length | minLength | maxLength | enumeration | whiteSpace | "
  11097. "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
  11098. } else {
  11099. /* Simple type */
  11100. xmlSchemaPContentErr(ctxt,
  11101. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11102. NULL, node, child, NULL,
  11103. "(annotation?, (simpleType?, (minExclusive | minInclusive | "
  11104. "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
  11105. "length | minLength | maxLength | enumeration | whiteSpace | "
  11106. "pattern)*))");
  11107. }
  11108. }
  11109. return (NULL);
  11110. }
  11111. /**
  11112. * xmlSchemaParseExtension:
  11113. * @ctxt: a schema validation context
  11114. * @schema: the schema being built
  11115. * @node: a subtree containing XML Schema information
  11116. *
  11117. * Parses an <extension>, which is found inside a
  11118. * <simpleContent> or <complexContent>.
  11119. * *WARNING* this interface is highly subject to change.
  11120. *
  11121. * TODO: Returns the type definition or NULL in case of error
  11122. */
  11123. static xmlSchemaTypePtr
  11124. xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  11125. xmlNodePtr node, xmlSchemaTypeType parentType)
  11126. {
  11127. xmlSchemaTypePtr type;
  11128. xmlNodePtr child = NULL;
  11129. xmlAttrPtr attr;
  11130. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  11131. return (NULL);
  11132. /* Not a component, don't create it. */
  11133. type = ctxt->ctxtType;
  11134. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
  11135. /*
  11136. * Check for illegal attributes.
  11137. */
  11138. attr = node->properties;
  11139. while (attr != NULL) {
  11140. if (attr->ns == NULL) {
  11141. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  11142. (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
  11143. xmlSchemaPIllegalAttrErr(ctxt,
  11144. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11145. }
  11146. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11147. xmlSchemaPIllegalAttrErr(ctxt,
  11148. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11149. }
  11150. attr = attr->next;
  11151. }
  11152. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11153. /*
  11154. * Attribute "base" - mandatory.
  11155. */
  11156. if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
  11157. "base", &(type->baseNs), &(type->base)) == 0) &&
  11158. (type->base == NULL)) {
  11159. xmlSchemaPMissingAttrErr(ctxt,
  11160. XML_SCHEMAP_S4S_ATTR_MISSING,
  11161. NULL, node, "base", NULL);
  11162. }
  11163. /*
  11164. * And now for the children...
  11165. */
  11166. child = node->children;
  11167. if (IS_SCHEMA(child, "annotation")) {
  11168. /*
  11169. * Add the annotation to the type ancestor.
  11170. */
  11171. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11172. xmlSchemaParseAnnotation(ctxt, child, 1));
  11173. child = child->next;
  11174. }
  11175. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11176. /*
  11177. * Corresponds to <complexType><complexContent><extension>... and:
  11178. *
  11179. * Model groups <all>, <choice>, <sequence> and <group>.
  11180. */
  11181. if (IS_SCHEMA(child, "all")) {
  11182. type->subtypes = (xmlSchemaTypePtr)
  11183. xmlSchemaParseModelGroup(ctxt, schema,
  11184. child, XML_SCHEMA_TYPE_ALL, 1);
  11185. child = child->next;
  11186. } else if (IS_SCHEMA(child, "choice")) {
  11187. type->subtypes = (xmlSchemaTypePtr)
  11188. xmlSchemaParseModelGroup(ctxt, schema,
  11189. child, XML_SCHEMA_TYPE_CHOICE, 1);
  11190. child = child->next;
  11191. } else if (IS_SCHEMA(child, "sequence")) {
  11192. type->subtypes = (xmlSchemaTypePtr)
  11193. xmlSchemaParseModelGroup(ctxt, schema,
  11194. child, XML_SCHEMA_TYPE_SEQUENCE, 1);
  11195. child = child->next;
  11196. } else if (IS_SCHEMA(child, "group")) {
  11197. type->subtypes = (xmlSchemaTypePtr)
  11198. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  11199. /*
  11200. * Note that the reference will be resolved in
  11201. * xmlSchemaResolveTypeReferences();
  11202. */
  11203. child = child->next;
  11204. }
  11205. }
  11206. if (child != NULL) {
  11207. /*
  11208. * Attribute uses/declarations.
  11209. */
  11210. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11211. (xmlSchemaItemListPtr *) &(type->attrUses),
  11212. XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
  11213. return(NULL);
  11214. /*
  11215. * Attribute wildcard.
  11216. */
  11217. if (IS_SCHEMA(child, "anyAttribute")) {
  11218. ctxt->ctxtType->attributeWildcard =
  11219. xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11220. child = child->next;
  11221. }
  11222. }
  11223. if (child != NULL) {
  11224. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11225. /* Complex content extension. */
  11226. xmlSchemaPContentErr(ctxt,
  11227. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11228. NULL, node, child, NULL,
  11229. "(annotation?, ((group | all | choice | sequence)?, "
  11230. "((attribute | attributeGroup)*, anyAttribute?)))");
  11231. } else {
  11232. /* Simple content extension. */
  11233. xmlSchemaPContentErr(ctxt,
  11234. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11235. NULL, node, child, NULL,
  11236. "(annotation?, ((attribute | attributeGroup)*, "
  11237. "anyAttribute?))");
  11238. }
  11239. }
  11240. return (NULL);
  11241. }
  11242. /**
  11243. * xmlSchemaParseSimpleContent:
  11244. * @ctxt: a schema validation context
  11245. * @schema: the schema being built
  11246. * @node: a subtree containing XML Schema information
  11247. *
  11248. * parse a XML schema SimpleContent definition
  11249. * *WARNING* this interface is highly subject to change
  11250. *
  11251. * Returns the type definition or NULL in case of error
  11252. */
  11253. static int
  11254. xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
  11255. xmlSchemaPtr schema, xmlNodePtr node,
  11256. int *hasRestrictionOrExtension)
  11257. {
  11258. xmlSchemaTypePtr type;
  11259. xmlNodePtr child = NULL;
  11260. xmlAttrPtr attr;
  11261. if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
  11262. (hasRestrictionOrExtension == NULL))
  11263. return (-1);
  11264. *hasRestrictionOrExtension = 0;
  11265. /* Not a component, don't create it. */
  11266. type = ctxt->ctxtType;
  11267. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  11268. /*
  11269. * Check for illegal attributes.
  11270. */
  11271. attr = node->properties;
  11272. while (attr != NULL) {
  11273. if (attr->ns == NULL) {
  11274. if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
  11275. xmlSchemaPIllegalAttrErr(ctxt,
  11276. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11277. }
  11278. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11279. xmlSchemaPIllegalAttrErr(ctxt,
  11280. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11281. }
  11282. attr = attr->next;
  11283. }
  11284. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11285. /*
  11286. * And now for the children...
  11287. */
  11288. child = node->children;
  11289. if (IS_SCHEMA(child, "annotation")) {
  11290. /*
  11291. * Add the annotation to the complex type ancestor.
  11292. */
  11293. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11294. xmlSchemaParseAnnotation(ctxt, child, 1));
  11295. child = child->next;
  11296. }
  11297. if (child == NULL) {
  11298. xmlSchemaPContentErr(ctxt,
  11299. XML_SCHEMAP_S4S_ELEM_MISSING,
  11300. NULL, node, NULL, NULL,
  11301. "(annotation?, (restriction | extension))");
  11302. }
  11303. if (child == NULL) {
  11304. xmlSchemaPContentErr(ctxt,
  11305. XML_SCHEMAP_S4S_ELEM_MISSING,
  11306. NULL, node, NULL, NULL,
  11307. "(annotation?, (restriction | extension))");
  11308. }
  11309. if (IS_SCHEMA(child, "restriction")) {
  11310. xmlSchemaParseRestriction(ctxt, schema, child,
  11311. XML_SCHEMA_TYPE_SIMPLE_CONTENT);
  11312. (*hasRestrictionOrExtension) = 1;
  11313. child = child->next;
  11314. } else if (IS_SCHEMA(child, "extension")) {
  11315. xmlSchemaParseExtension(ctxt, schema, child,
  11316. XML_SCHEMA_TYPE_SIMPLE_CONTENT);
  11317. (*hasRestrictionOrExtension) = 1;
  11318. child = child->next;
  11319. }
  11320. if (child != NULL) {
  11321. xmlSchemaPContentErr(ctxt,
  11322. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11323. NULL, node, child, NULL,
  11324. "(annotation?, (restriction | extension))");
  11325. }
  11326. return (0);
  11327. }
  11328. /**
  11329. * xmlSchemaParseComplexContent:
  11330. * @ctxt: a schema validation context
  11331. * @schema: the schema being built
  11332. * @node: a subtree containing XML Schema information
  11333. *
  11334. * parse a XML schema ComplexContent definition
  11335. * *WARNING* this interface is highly subject to change
  11336. *
  11337. * Returns the type definition or NULL in case of error
  11338. */
  11339. static int
  11340. xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
  11341. xmlSchemaPtr schema, xmlNodePtr node,
  11342. int *hasRestrictionOrExtension)
  11343. {
  11344. xmlSchemaTypePtr type;
  11345. xmlNodePtr child = NULL;
  11346. xmlAttrPtr attr;
  11347. if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
  11348. (hasRestrictionOrExtension == NULL))
  11349. return (-1);
  11350. *hasRestrictionOrExtension = 0;
  11351. /* Not a component, don't create it. */
  11352. type = ctxt->ctxtType;
  11353. /*
  11354. * Check for illegal attributes.
  11355. */
  11356. attr = node->properties;
  11357. while (attr != NULL) {
  11358. if (attr->ns == NULL) {
  11359. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  11360. (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
  11361. {
  11362. xmlSchemaPIllegalAttrErr(ctxt,
  11363. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11364. }
  11365. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11366. xmlSchemaPIllegalAttrErr(ctxt,
  11367. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11368. }
  11369. attr = attr->next;
  11370. }
  11371. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11372. /*
  11373. * Set the 'mixed' on the complex type ancestor.
  11374. */
  11375. if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) {
  11376. if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
  11377. type->flags |= XML_SCHEMAS_TYPE_MIXED;
  11378. }
  11379. child = node->children;
  11380. if (IS_SCHEMA(child, "annotation")) {
  11381. /*
  11382. * Add the annotation to the complex type ancestor.
  11383. */
  11384. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11385. xmlSchemaParseAnnotation(ctxt, child, 1));
  11386. child = child->next;
  11387. }
  11388. if (child == NULL) {
  11389. xmlSchemaPContentErr(ctxt,
  11390. XML_SCHEMAP_S4S_ELEM_MISSING,
  11391. NULL, node, NULL,
  11392. NULL, "(annotation?, (restriction | extension))");
  11393. }
  11394. if (child == NULL) {
  11395. xmlSchemaPContentErr(ctxt,
  11396. XML_SCHEMAP_S4S_ELEM_MISSING,
  11397. NULL, node, NULL,
  11398. NULL, "(annotation?, (restriction | extension))");
  11399. }
  11400. if (IS_SCHEMA(child, "restriction")) {
  11401. xmlSchemaParseRestriction(ctxt, schema, child,
  11402. XML_SCHEMA_TYPE_COMPLEX_CONTENT);
  11403. (*hasRestrictionOrExtension) = 1;
  11404. child = child->next;
  11405. } else if (IS_SCHEMA(child, "extension")) {
  11406. xmlSchemaParseExtension(ctxt, schema, child,
  11407. XML_SCHEMA_TYPE_COMPLEX_CONTENT);
  11408. (*hasRestrictionOrExtension) = 1;
  11409. child = child->next;
  11410. }
  11411. if (child != NULL) {
  11412. xmlSchemaPContentErr(ctxt,
  11413. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11414. NULL, node, child,
  11415. NULL, "(annotation?, (restriction | extension))");
  11416. }
  11417. return (0);
  11418. }
  11419. /**
  11420. * xmlSchemaParseComplexType:
  11421. * @ctxt: a schema validation context
  11422. * @schema: the schema being built
  11423. * @node: a subtree containing XML Schema information
  11424. *
  11425. * parse a XML schema Complex Type definition
  11426. * *WARNING* this interface is highly subject to change
  11427. *
  11428. * Returns the type definition or NULL in case of error
  11429. */
  11430. static xmlSchemaTypePtr
  11431. xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  11432. xmlNodePtr node, int topLevel)
  11433. {
  11434. xmlSchemaTypePtr type, ctxtType;
  11435. xmlNodePtr child = NULL;
  11436. const xmlChar *name = NULL;
  11437. xmlAttrPtr attr;
  11438. const xmlChar *attrValue;
  11439. #ifdef ENABLE_NAMED_LOCALS
  11440. char buf[40];
  11441. #endif
  11442. int final = 0, block = 0, hasRestrictionOrExtension = 0;
  11443. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  11444. return (NULL);
  11445. ctxtType = ctxt->ctxtType;
  11446. if (topLevel) {
  11447. attr = xmlSchemaGetPropNode(node, "name");
  11448. if (attr == NULL) {
  11449. xmlSchemaPMissingAttrErr(ctxt,
  11450. XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
  11451. return (NULL);
  11452. } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
  11453. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  11454. return (NULL);
  11455. }
  11456. }
  11457. if (topLevel == 0) {
  11458. /*
  11459. * Parse as local complex type definition.
  11460. */
  11461. #ifdef ENABLE_NAMED_LOCALS
  11462. snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
  11463. type = xmlSchemaAddType(ctxt, schema,
  11464. XML_SCHEMA_TYPE_COMPLEX,
  11465. xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
  11466. ctxt->targetNamespace, node, 0);
  11467. #else
  11468. type = xmlSchemaAddType(ctxt, schema,
  11469. XML_SCHEMA_TYPE_COMPLEX,
  11470. NULL, ctxt->targetNamespace, node, 0);
  11471. #endif
  11472. if (type == NULL)
  11473. return (NULL);
  11474. name = type->name;
  11475. type->node = node;
  11476. type->type = XML_SCHEMA_TYPE_COMPLEX;
  11477. /*
  11478. * TODO: We need the target namespace.
  11479. */
  11480. } else {
  11481. /*
  11482. * Parse as global complex type definition.
  11483. */
  11484. type = xmlSchemaAddType(ctxt, schema,
  11485. XML_SCHEMA_TYPE_COMPLEX,
  11486. name, ctxt->targetNamespace, node, 1);
  11487. if (type == NULL)
  11488. return (NULL);
  11489. type->node = node;
  11490. type->type = XML_SCHEMA_TYPE_COMPLEX;
  11491. type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
  11492. }
  11493. type->targetNamespace = ctxt->targetNamespace;
  11494. /*
  11495. * Handle attributes.
  11496. */
  11497. attr = node->properties;
  11498. while (attr != NULL) {
  11499. if (attr->ns == NULL) {
  11500. if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  11501. /*
  11502. * Attribute "id".
  11503. */
  11504. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11505. } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
  11506. /*
  11507. * Attribute "mixed".
  11508. */
  11509. if (xmlSchemaPGetBoolNodeValue(ctxt,
  11510. NULL, (xmlNodePtr) attr))
  11511. type->flags |= XML_SCHEMAS_TYPE_MIXED;
  11512. } else if (topLevel) {
  11513. /*
  11514. * Attributes of global complex type definitions.
  11515. */
  11516. if (xmlStrEqual(attr->name, BAD_CAST "name")) {
  11517. /* Pass. */
  11518. } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
  11519. /*
  11520. * Attribute "abstract".
  11521. */
  11522. if (xmlSchemaPGetBoolNodeValue(ctxt,
  11523. NULL, (xmlNodePtr) attr))
  11524. type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
  11525. } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
  11526. /*
  11527. * Attribute "final".
  11528. */
  11529. attrValue = xmlSchemaGetNodeContent(ctxt,
  11530. (xmlNodePtr) attr);
  11531. if (xmlSchemaPValAttrBlockFinal(attrValue,
  11532. &(type->flags),
  11533. -1,
  11534. XML_SCHEMAS_TYPE_FINAL_EXTENSION,
  11535. XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
  11536. -1, -1, -1) != 0)
  11537. {
  11538. xmlSchemaPSimpleTypeErr(ctxt,
  11539. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  11540. NULL, (xmlNodePtr) attr, NULL,
  11541. "(#all | List of (extension | restriction))",
  11542. attrValue, NULL, NULL, NULL);
  11543. } else
  11544. final = 1;
  11545. } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
  11546. /*
  11547. * Attribute "block".
  11548. */
  11549. attrValue = xmlSchemaGetNodeContent(ctxt,
  11550. (xmlNodePtr) attr);
  11551. if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
  11552. -1,
  11553. XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
  11554. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
  11555. -1, -1, -1) != 0) {
  11556. xmlSchemaPSimpleTypeErr(ctxt,
  11557. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  11558. NULL, (xmlNodePtr) attr, NULL,
  11559. "(#all | List of (extension | restriction)) ",
  11560. attrValue, NULL, NULL, NULL);
  11561. } else
  11562. block = 1;
  11563. } else {
  11564. xmlSchemaPIllegalAttrErr(ctxt,
  11565. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11566. }
  11567. } else {
  11568. xmlSchemaPIllegalAttrErr(ctxt,
  11569. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11570. }
  11571. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11572. xmlSchemaPIllegalAttrErr(ctxt,
  11573. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11574. }
  11575. attr = attr->next;
  11576. }
  11577. if (! block) {
  11578. /*
  11579. * Apply default "block" values.
  11580. */
  11581. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  11582. type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  11583. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  11584. type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  11585. }
  11586. if (! final) {
  11587. /*
  11588. * Apply default "block" values.
  11589. */
  11590. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  11591. type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
  11592. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  11593. type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
  11594. }
  11595. /*
  11596. * And now for the children...
  11597. */
  11598. child = node->children;
  11599. if (IS_SCHEMA(child, "annotation")) {
  11600. type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  11601. child = child->next;
  11602. }
  11603. ctxt->ctxtType = type;
  11604. if (IS_SCHEMA(child, "simpleContent")) {
  11605. /*
  11606. * <complexType><simpleContent>...
  11607. * 3.4.3 : 2.2
  11608. * Specifying mixed='true' when the <simpleContent>
  11609. * alternative is chosen has no effect
  11610. */
  11611. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  11612. type->flags ^= XML_SCHEMAS_TYPE_MIXED;
  11613. xmlSchemaParseSimpleContent(ctxt, schema, child,
  11614. &hasRestrictionOrExtension);
  11615. child = child->next;
  11616. } else if (IS_SCHEMA(child, "complexContent")) {
  11617. /*
  11618. * <complexType><complexContent>...
  11619. */
  11620. type->contentType = XML_SCHEMA_CONTENT_EMPTY;
  11621. xmlSchemaParseComplexContent(ctxt, schema, child,
  11622. &hasRestrictionOrExtension);
  11623. child = child->next;
  11624. } else {
  11625. /*
  11626. * E.g <complexType><sequence>... or <complexType><attribute>... etc.
  11627. *
  11628. * SPEC
  11629. * "...the third alternative (neither <simpleContent> nor
  11630. * <complexContent>) is chosen. This case is understood as shorthand
  11631. * for complex content restricting the `ur-type definition`, and the
  11632. * details of the mappings should be modified as necessary.
  11633. */
  11634. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  11635. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
  11636. /*
  11637. * Parse model groups.
  11638. */
  11639. if (IS_SCHEMA(child, "all")) {
  11640. type->subtypes = (xmlSchemaTypePtr)
  11641. xmlSchemaParseModelGroup(ctxt, schema, child,
  11642. XML_SCHEMA_TYPE_ALL, 1);
  11643. child = child->next;
  11644. } else if (IS_SCHEMA(child, "choice")) {
  11645. type->subtypes = (xmlSchemaTypePtr)
  11646. xmlSchemaParseModelGroup(ctxt, schema, child,
  11647. XML_SCHEMA_TYPE_CHOICE, 1);
  11648. child = child->next;
  11649. } else if (IS_SCHEMA(child, "sequence")) {
  11650. type->subtypes = (xmlSchemaTypePtr)
  11651. xmlSchemaParseModelGroup(ctxt, schema, child,
  11652. XML_SCHEMA_TYPE_SEQUENCE, 1);
  11653. child = child->next;
  11654. } else if (IS_SCHEMA(child, "group")) {
  11655. type->subtypes = (xmlSchemaTypePtr)
  11656. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  11657. /*
  11658. * Note that the reference will be resolved in
  11659. * xmlSchemaResolveTypeReferences();
  11660. */
  11661. child = child->next;
  11662. }
  11663. /*
  11664. * Parse attribute decls/refs.
  11665. */
  11666. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11667. (xmlSchemaItemListPtr *) &(type->attrUses),
  11668. XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
  11669. return(NULL);
  11670. /*
  11671. * Parse attribute wildcard.
  11672. */
  11673. if (IS_SCHEMA(child, "anyAttribute")) {
  11674. type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11675. child = child->next;
  11676. }
  11677. }
  11678. if (child != NULL) {
  11679. xmlSchemaPContentErr(ctxt,
  11680. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11681. NULL, node, child,
  11682. NULL, "(annotation?, (simpleContent | complexContent | "
  11683. "((group | all | choice | sequence)?, ((attribute | "
  11684. "attributeGroup)*, anyAttribute?))))");
  11685. }
  11686. /*
  11687. * REDEFINE: SPEC src-redefine (5)
  11688. */
  11689. if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
  11690. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  11691. NULL, node, "This is a redefinition, thus the "
  11692. "<complexType> must have a <restriction> or <extension> "
  11693. "grand-child", NULL);
  11694. }
  11695. ctxt->ctxtType = ctxtType;
  11696. return (type);
  11697. }
  11698. /************************************************************************
  11699. * *
  11700. * Validating using Schemas *
  11701. * *
  11702. ************************************************************************/
  11703. /************************************************************************
  11704. * *
  11705. * Reading/Writing Schemas *
  11706. * *
  11707. ************************************************************************/
  11708. #if 0 /* Will be enabled if it is clear what options are needed. */
  11709. /**
  11710. * xmlSchemaParserCtxtSetOptions:
  11711. * @ctxt: a schema parser context
  11712. * @options: a combination of xmlSchemaParserOption
  11713. *
  11714. * Sets the options to be used during the parse.
  11715. *
  11716. * Returns 0 in case of success, -1 in case of an
  11717. * API error.
  11718. */
  11719. static int
  11720. xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
  11721. int options)
  11722. {
  11723. int i;
  11724. if (ctxt == NULL)
  11725. return (-1);
  11726. /*
  11727. * WARNING: Change the start value if adding to the
  11728. * xmlSchemaParseOption.
  11729. */
  11730. for (i = 1; i < (int) sizeof(int) * 8; i++) {
  11731. if (options & 1<<i) {
  11732. return (-1);
  11733. }
  11734. }
  11735. ctxt->options = options;
  11736. return (0);
  11737. }
  11738. /**
  11739. * xmlSchemaValidCtxtGetOptions:
  11740. * @ctxt: a schema parser context
  11741. *
  11742. * Returns the option combination of the parser context.
  11743. */
  11744. static int
  11745. xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
  11746. {
  11747. if (ctxt == NULL)
  11748. return (-1);
  11749. else
  11750. return (ctxt->options);
  11751. }
  11752. #endif
  11753. /**
  11754. * xmlSchemaNewParserCtxt:
  11755. * @URL: the location of the schema
  11756. *
  11757. * Create an XML Schemas parse context for that file/resource expected
  11758. * to contain an XML Schemas file.
  11759. *
  11760. * Returns the parser context or NULL in case of error
  11761. */
  11762. xmlSchemaParserCtxtPtr
  11763. xmlSchemaNewParserCtxt(const char *URL)
  11764. {
  11765. xmlSchemaParserCtxtPtr ret;
  11766. if (URL == NULL)
  11767. return (NULL);
  11768. ret = xmlSchemaParserCtxtCreate();
  11769. if (ret == NULL)
  11770. return(NULL);
  11771. ret->dict = xmlDictCreate();
  11772. ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
  11773. return (ret);
  11774. }
  11775. /**
  11776. * xmlSchemaNewMemParserCtxt:
  11777. * @buffer: a pointer to a char array containing the schemas
  11778. * @size: the size of the array
  11779. *
  11780. * Create an XML Schemas parse context for that memory buffer expected
  11781. * to contain an XML Schemas file.
  11782. *
  11783. * Returns the parser context or NULL in case of error
  11784. */
  11785. xmlSchemaParserCtxtPtr
  11786. xmlSchemaNewMemParserCtxt(const char *buffer, int size)
  11787. {
  11788. xmlSchemaParserCtxtPtr ret;
  11789. if ((buffer == NULL) || (size <= 0))
  11790. return (NULL);
  11791. ret = xmlSchemaParserCtxtCreate();
  11792. if (ret == NULL)
  11793. return(NULL);
  11794. ret->buffer = buffer;
  11795. ret->size = size;
  11796. ret->dict = xmlDictCreate();
  11797. return (ret);
  11798. }
  11799. /**
  11800. * xmlSchemaNewDocParserCtxt:
  11801. * @doc: a preparsed document tree
  11802. *
  11803. * Create an XML Schemas parse context for that document.
  11804. * NB. The document may be modified during the parsing process.
  11805. *
  11806. * Returns the parser context or NULL in case of error
  11807. */
  11808. xmlSchemaParserCtxtPtr
  11809. xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
  11810. {
  11811. xmlSchemaParserCtxtPtr ret;
  11812. if (doc == NULL)
  11813. return (NULL);
  11814. ret = xmlSchemaParserCtxtCreate();
  11815. if (ret == NULL)
  11816. return(NULL);
  11817. ret->doc = doc;
  11818. ret->dict = xmlDictCreate();
  11819. /* The application has responsibility for the document */
  11820. ret->preserve = 1;
  11821. return (ret);
  11822. }
  11823. /**
  11824. * xmlSchemaFreeParserCtxt:
  11825. * @ctxt: the schema parser context
  11826. *
  11827. * Free the resources associated to the schema parser context
  11828. */
  11829. void
  11830. xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
  11831. {
  11832. if (ctxt == NULL)
  11833. return;
  11834. if (ctxt->doc != NULL && !ctxt->preserve)
  11835. xmlFreeDoc(ctxt->doc);
  11836. if (ctxt->vctxt != NULL) {
  11837. xmlSchemaFreeValidCtxt(ctxt->vctxt);
  11838. }
  11839. if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
  11840. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  11841. ctxt->constructor = NULL;
  11842. ctxt->ownsConstructor = 0;
  11843. }
  11844. if (ctxt->attrProhibs != NULL)
  11845. xmlSchemaItemListFree(ctxt->attrProhibs);
  11846. xmlDictFree(ctxt->dict);
  11847. xmlFree(ctxt);
  11848. }
  11849. /************************************************************************
  11850. * *
  11851. * Building the content models *
  11852. * *
  11853. ************************************************************************/
  11854. /**
  11855. * xmlSchemaBuildContentModelForSubstGroup:
  11856. *
  11857. * Returns 1 if nillable, 0 otherwise
  11858. */
  11859. static int
  11860. xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
  11861. xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
  11862. {
  11863. xmlAutomataStatePtr start, tmp;
  11864. xmlSchemaElementPtr elemDecl, member;
  11865. xmlSchemaSubstGroupPtr substGroup;
  11866. int i;
  11867. int ret = 0;
  11868. elemDecl = (xmlSchemaElementPtr) particle->children;
  11869. /*
  11870. * Wrap the substitution group with a CHOICE.
  11871. */
  11872. start = pctxt->state;
  11873. if (end == NULL)
  11874. end = xmlAutomataNewState(pctxt->am);
  11875. substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
  11876. if (substGroup == NULL) {
  11877. xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
  11878. XML_SCHEMAP_INTERNAL,
  11879. "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
  11880. "declaration is marked having a subst. group but none "
  11881. "available.\n", elemDecl->name, NULL);
  11882. return(0);
  11883. }
  11884. if (counter >= 0) {
  11885. /*
  11886. * NOTE that we put the declaration in, even if it's abstract.
  11887. * However, an error will be raised during *validation* if an element
  11888. * information item shall be validated against an abstract element
  11889. * declaration.
  11890. */
  11891. tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
  11892. xmlAutomataNewTransition2(pctxt->am, tmp, end,
  11893. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11894. /*
  11895. * Add subst. group members.
  11896. */
  11897. for (i = 0; i < substGroup->members->nbItems; i++) {
  11898. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11899. xmlAutomataNewTransition2(pctxt->am, tmp, end,
  11900. member->name, member->targetNamespace, member);
  11901. }
  11902. } else if (particle->maxOccurs == 1) {
  11903. /*
  11904. * NOTE that we put the declaration in, even if it's abstract,
  11905. */
  11906. xmlAutomataNewEpsilon(pctxt->am,
  11907. xmlAutomataNewTransition2(pctxt->am,
  11908. start, NULL,
  11909. elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
  11910. /*
  11911. * Add subst. group members.
  11912. */
  11913. for (i = 0; i < substGroup->members->nbItems; i++) {
  11914. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11915. /*
  11916. * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
  11917. * was incorrectly used instead of xmlAutomataNewTransition2()
  11918. * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
  11919. * section in xmlSchemaBuildAContentModel() ).
  11920. * TODO: Check if xmlAutomataNewOnceTrans2() was instead
  11921. * intended for the above "counter" section originally. I.e.,
  11922. * check xs:all with subst-groups.
  11923. *
  11924. * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
  11925. * member->name, member->targetNamespace,
  11926. * 1, 1, member);
  11927. */
  11928. tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
  11929. member->name, member->targetNamespace, member);
  11930. xmlAutomataNewEpsilon(pctxt->am, tmp, end);
  11931. }
  11932. } else {
  11933. xmlAutomataStatePtr hop;
  11934. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  11935. UNBOUNDED : particle->maxOccurs - 1;
  11936. int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  11937. counter =
  11938. xmlAutomataNewCounter(pctxt->am, minOccurs,
  11939. maxOccurs);
  11940. hop = xmlAutomataNewState(pctxt->am);
  11941. xmlAutomataNewEpsilon(pctxt->am,
  11942. xmlAutomataNewTransition2(pctxt->am,
  11943. start, NULL,
  11944. elemDecl->name, elemDecl->targetNamespace, elemDecl),
  11945. hop);
  11946. /*
  11947. * Add subst. group members.
  11948. */
  11949. for (i = 0; i < substGroup->members->nbItems; i++) {
  11950. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11951. xmlAutomataNewEpsilon(pctxt->am,
  11952. xmlAutomataNewTransition2(pctxt->am,
  11953. start, NULL,
  11954. member->name, member->targetNamespace, member),
  11955. hop);
  11956. }
  11957. xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
  11958. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  11959. }
  11960. if (particle->minOccurs == 0) {
  11961. xmlAutomataNewEpsilon(pctxt->am, start, end);
  11962. ret = 1;
  11963. }
  11964. pctxt->state = end;
  11965. return(ret);
  11966. }
  11967. /**
  11968. * xmlSchemaBuildContentModelForElement:
  11969. *
  11970. * Returns 1 if nillable, 0 otherwise
  11971. */
  11972. static int
  11973. xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
  11974. xmlSchemaParticlePtr particle)
  11975. {
  11976. int ret = 0;
  11977. if (((xmlSchemaElementPtr) particle->children)->flags &
  11978. XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
  11979. /*
  11980. * Substitution groups.
  11981. */
  11982. ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
  11983. } else {
  11984. xmlSchemaElementPtr elemDecl;
  11985. xmlAutomataStatePtr start;
  11986. elemDecl = (xmlSchemaElementPtr) particle->children;
  11987. if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
  11988. return(0);
  11989. if (particle->maxOccurs == 1) {
  11990. start = ctxt->state;
  11991. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11992. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11993. } else if ((particle->maxOccurs >= UNBOUNDED) &&
  11994. (particle->minOccurs < 2)) {
  11995. /* Special case. */
  11996. start = ctxt->state;
  11997. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11998. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11999. ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
  12000. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  12001. } else {
  12002. int counter;
  12003. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  12004. UNBOUNDED : particle->maxOccurs - 1;
  12005. int minOccurs = particle->minOccurs < 1 ?
  12006. 0 : particle->minOccurs - 1;
  12007. start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
  12008. counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
  12009. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  12010. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  12011. xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
  12012. ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
  12013. NULL, counter);
  12014. }
  12015. if (particle->minOccurs == 0) {
  12016. xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
  12017. ret = 1;
  12018. }
  12019. }
  12020. return(ret);
  12021. }
  12022. /**
  12023. * xmlSchemaBuildAContentModel:
  12024. * @ctxt: the schema parser context
  12025. * @particle: the particle component
  12026. * @name: the complex type's name whose content is being built
  12027. *
  12028. * Create the automaton for the {content type} of a complex type.
  12029. *
  12030. * Returns 1 if the content is nillable, 0 otherwise
  12031. */
  12032. static int
  12033. xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
  12034. xmlSchemaParticlePtr particle)
  12035. {
  12036. int ret = 0, tmp2;
  12037. if (particle == NULL) {
  12038. PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
  12039. return(1);
  12040. }
  12041. if (particle->children == NULL) {
  12042. /*
  12043. * Just return in this case. A missing "term" of the particle
  12044. * might arise due to an invalid "term" component.
  12045. */
  12046. return(1);
  12047. }
  12048. switch (particle->children->type) {
  12049. case XML_SCHEMA_TYPE_ANY: {
  12050. xmlAutomataStatePtr start, end;
  12051. xmlSchemaWildcardPtr wild;
  12052. xmlSchemaWildcardNsPtr ns;
  12053. wild = (xmlSchemaWildcardPtr) particle->children;
  12054. start = pctxt->state;
  12055. end = xmlAutomataNewState(pctxt->am);
  12056. if (particle->maxOccurs == 1) {
  12057. if (wild->any == 1) {
  12058. /*
  12059. * We need to add both transitions:
  12060. *
  12061. * 1. the {"*", "*"} for elements in a namespace.
  12062. */
  12063. pctxt->state =
  12064. xmlAutomataNewTransition2(pctxt->am,
  12065. start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
  12066. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12067. /*
  12068. * 2. the {"*"} for elements in no namespace.
  12069. */
  12070. pctxt->state =
  12071. xmlAutomataNewTransition2(pctxt->am,
  12072. start, NULL, BAD_CAST "*", NULL, wild);
  12073. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12074. } else if (wild->nsSet != NULL) {
  12075. ns = wild->nsSet;
  12076. do {
  12077. pctxt->state = start;
  12078. pctxt->state = xmlAutomataNewTransition2(pctxt->am,
  12079. pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
  12080. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12081. ns = ns->next;
  12082. } while (ns != NULL);
  12083. } else if (wild->negNsSet != NULL) {
  12084. pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
  12085. start, end, BAD_CAST "*", wild->negNsSet->value,
  12086. wild);
  12087. }
  12088. } else {
  12089. int counter;
  12090. xmlAutomataStatePtr hop;
  12091. int maxOccurs =
  12092. particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
  12093. particle->maxOccurs - 1;
  12094. int minOccurs =
  12095. particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  12096. counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
  12097. hop = xmlAutomataNewState(pctxt->am);
  12098. if (wild->any == 1) {
  12099. pctxt->state =
  12100. xmlAutomataNewTransition2(pctxt->am,
  12101. start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
  12102. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12103. pctxt->state =
  12104. xmlAutomataNewTransition2(pctxt->am,
  12105. start, NULL, BAD_CAST "*", NULL, wild);
  12106. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12107. } else if (wild->nsSet != NULL) {
  12108. ns = wild->nsSet;
  12109. do {
  12110. pctxt->state =
  12111. xmlAutomataNewTransition2(pctxt->am,
  12112. start, NULL, BAD_CAST "*", ns->value, wild);
  12113. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12114. ns = ns->next;
  12115. } while (ns != NULL);
  12116. } else if (wild->negNsSet != NULL) {
  12117. pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
  12118. start, hop, BAD_CAST "*", wild->negNsSet->value,
  12119. wild);
  12120. }
  12121. xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
  12122. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  12123. }
  12124. if (particle->minOccurs == 0) {
  12125. xmlAutomataNewEpsilon(pctxt->am, start, end);
  12126. ret = 1;
  12127. }
  12128. pctxt->state = end;
  12129. break;
  12130. }
  12131. case XML_SCHEMA_TYPE_ELEMENT:
  12132. ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
  12133. break;
  12134. case XML_SCHEMA_TYPE_SEQUENCE:{
  12135. xmlSchemaTreeItemPtr sub;
  12136. ret = 1;
  12137. /*
  12138. * If max and min occurrences are default (1) then
  12139. * simply iterate over the particles of the <sequence>.
  12140. */
  12141. if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
  12142. sub = particle->children->children;
  12143. while (sub != NULL) {
  12144. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12145. (xmlSchemaParticlePtr) sub);
  12146. if (tmp2 != 1) ret = 0;
  12147. sub = sub->next;
  12148. }
  12149. } else {
  12150. xmlAutomataStatePtr oldstate = pctxt->state;
  12151. if (particle->maxOccurs >= UNBOUNDED) {
  12152. if (particle->minOccurs > 1) {
  12153. xmlAutomataStatePtr tmp;
  12154. int counter;
  12155. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12156. oldstate, NULL);
  12157. oldstate = pctxt->state;
  12158. counter = xmlAutomataNewCounter(pctxt->am,
  12159. particle->minOccurs - 1, UNBOUNDED);
  12160. sub = particle->children->children;
  12161. while (sub != NULL) {
  12162. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12163. (xmlSchemaParticlePtr) sub);
  12164. if (tmp2 != 1) ret = 0;
  12165. sub = sub->next;
  12166. }
  12167. tmp = pctxt->state;
  12168. xmlAutomataNewCountedTrans(pctxt->am, tmp,
  12169. oldstate, counter);
  12170. pctxt->state =
  12171. xmlAutomataNewCounterTrans(pctxt->am, tmp,
  12172. NULL, counter);
  12173. if (ret == 1)
  12174. xmlAutomataNewEpsilon(pctxt->am,
  12175. oldstate, pctxt->state);
  12176. } else {
  12177. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12178. oldstate, NULL);
  12179. oldstate = pctxt->state;
  12180. sub = particle->children->children;
  12181. while (sub != NULL) {
  12182. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12183. (xmlSchemaParticlePtr) sub);
  12184. if (tmp2 != 1) ret = 0;
  12185. sub = sub->next;
  12186. }
  12187. xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
  12188. oldstate);
  12189. /*
  12190. * epsilon needed to block previous trans from
  12191. * being allowed to enter back from another
  12192. * construct
  12193. */
  12194. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12195. pctxt->state, NULL);
  12196. if (particle->minOccurs == 0) {
  12197. xmlAutomataNewEpsilon(pctxt->am,
  12198. oldstate, pctxt->state);
  12199. ret = 1;
  12200. }
  12201. }
  12202. } else if ((particle->maxOccurs > 1)
  12203. || (particle->minOccurs > 1)) {
  12204. xmlAutomataStatePtr tmp;
  12205. int counter;
  12206. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12207. oldstate, NULL);
  12208. oldstate = pctxt->state;
  12209. counter = xmlAutomataNewCounter(pctxt->am,
  12210. particle->minOccurs - 1,
  12211. particle->maxOccurs - 1);
  12212. sub = particle->children->children;
  12213. while (sub != NULL) {
  12214. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12215. (xmlSchemaParticlePtr) sub);
  12216. if (tmp2 != 1) ret = 0;
  12217. sub = sub->next;
  12218. }
  12219. tmp = pctxt->state;
  12220. xmlAutomataNewCountedTrans(pctxt->am,
  12221. tmp, oldstate, counter);
  12222. pctxt->state =
  12223. xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
  12224. counter);
  12225. if ((particle->minOccurs == 0) || (ret == 1)) {
  12226. xmlAutomataNewEpsilon(pctxt->am,
  12227. oldstate, pctxt->state);
  12228. ret = 1;
  12229. }
  12230. } else {
  12231. sub = particle->children->children;
  12232. while (sub != NULL) {
  12233. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12234. (xmlSchemaParticlePtr) sub);
  12235. if (tmp2 != 1) ret = 0;
  12236. sub = sub->next;
  12237. }
  12238. /*
  12239. * epsilon needed to block previous trans from
  12240. * being allowed to enter back from another
  12241. * construct
  12242. */
  12243. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12244. pctxt->state, NULL);
  12245. if (particle->minOccurs == 0) {
  12246. xmlAutomataNewEpsilon(pctxt->am, oldstate,
  12247. pctxt->state);
  12248. ret = 1;
  12249. }
  12250. }
  12251. }
  12252. break;
  12253. }
  12254. case XML_SCHEMA_TYPE_CHOICE:{
  12255. xmlSchemaTreeItemPtr sub;
  12256. xmlAutomataStatePtr start, end;
  12257. ret = 0;
  12258. start = pctxt->state;
  12259. end = xmlAutomataNewState(pctxt->am);
  12260. /*
  12261. * iterate over the subtypes and remerge the end with an
  12262. * epsilon transition
  12263. */
  12264. if (particle->maxOccurs == 1) {
  12265. sub = particle->children->children;
  12266. while (sub != NULL) {
  12267. pctxt->state = start;
  12268. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12269. (xmlSchemaParticlePtr) sub);
  12270. if (tmp2 == 1) ret = 1;
  12271. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12272. sub = sub->next;
  12273. }
  12274. } else {
  12275. int counter;
  12276. xmlAutomataStatePtr hop, base;
  12277. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  12278. UNBOUNDED : particle->maxOccurs - 1;
  12279. int minOccurs =
  12280. particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  12281. /*
  12282. * use a counter to keep track of the number of transitions
  12283. * which went through the choice.
  12284. */
  12285. counter =
  12286. xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
  12287. hop = xmlAutomataNewState(pctxt->am);
  12288. base = xmlAutomataNewState(pctxt->am);
  12289. sub = particle->children->children;
  12290. while (sub != NULL) {
  12291. pctxt->state = base;
  12292. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12293. (xmlSchemaParticlePtr) sub);
  12294. if (tmp2 == 1) ret = 1;
  12295. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12296. sub = sub->next;
  12297. }
  12298. xmlAutomataNewEpsilon(pctxt->am, start, base);
  12299. xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
  12300. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  12301. if (ret == 1)
  12302. xmlAutomataNewEpsilon(pctxt->am, base, end);
  12303. }
  12304. if (particle->minOccurs == 0) {
  12305. xmlAutomataNewEpsilon(pctxt->am, start, end);
  12306. ret = 1;
  12307. }
  12308. pctxt->state = end;
  12309. break;
  12310. }
  12311. case XML_SCHEMA_TYPE_ALL:{
  12312. xmlAutomataStatePtr start, tmp;
  12313. xmlSchemaParticlePtr sub;
  12314. xmlSchemaElementPtr elemDecl;
  12315. ret = 1;
  12316. sub = (xmlSchemaParticlePtr) particle->children->children;
  12317. if (sub == NULL)
  12318. break;
  12319. ret = 0;
  12320. start = pctxt->state;
  12321. tmp = xmlAutomataNewState(pctxt->am);
  12322. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
  12323. pctxt->state = tmp;
  12324. while (sub != NULL) {
  12325. pctxt->state = tmp;
  12326. elemDecl = (xmlSchemaElementPtr) sub->children;
  12327. if (elemDecl == NULL) {
  12328. PERROR_INT("xmlSchemaBuildAContentModel",
  12329. "<element> particle has no term");
  12330. return(ret);
  12331. };
  12332. /*
  12333. * NOTE: The {max occurs} of all the particles in the
  12334. * {particles} of the group must be 0 or 1; this is
  12335. * already ensured during the parse of the content of
  12336. * <all>.
  12337. */
  12338. if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
  12339. int counter;
  12340. /*
  12341. * This is an abstract group, we need to share
  12342. * the same counter for all the element transitions
  12343. * derived from the group
  12344. */
  12345. counter = xmlAutomataNewCounter(pctxt->am,
  12346. sub->minOccurs, sub->maxOccurs);
  12347. xmlSchemaBuildContentModelForSubstGroup(pctxt,
  12348. sub, counter, pctxt->state);
  12349. } else {
  12350. if ((sub->minOccurs == 1) &&
  12351. (sub->maxOccurs == 1)) {
  12352. xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
  12353. pctxt->state,
  12354. elemDecl->name,
  12355. elemDecl->targetNamespace,
  12356. 1, 1, elemDecl);
  12357. } else if ((sub->minOccurs == 0) &&
  12358. (sub->maxOccurs == 1)) {
  12359. xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
  12360. pctxt->state,
  12361. elemDecl->name,
  12362. elemDecl->targetNamespace,
  12363. 0,
  12364. 1,
  12365. elemDecl);
  12366. }
  12367. }
  12368. sub = (xmlSchemaParticlePtr) sub->next;
  12369. }
  12370. pctxt->state =
  12371. xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
  12372. if (particle->minOccurs == 0) {
  12373. xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
  12374. ret = 1;
  12375. }
  12376. break;
  12377. }
  12378. case XML_SCHEMA_TYPE_GROUP:
  12379. /*
  12380. * If we hit a model group definition, then this means that
  12381. * it was empty, thus was not substituted for the containing
  12382. * model group. Just do nothing in this case.
  12383. * TODO: But the group should be substituted and not occur at
  12384. * all in the content model at this point. Fix this.
  12385. */
  12386. ret = 1;
  12387. break;
  12388. default:
  12389. xmlSchemaInternalErr2(ACTXT_CAST pctxt,
  12390. "xmlSchemaBuildAContentModel",
  12391. "found unexpected term of type '%s' in content model",
  12392. WXS_ITEM_TYPE_NAME(particle->children), NULL);
  12393. return(ret);
  12394. }
  12395. return(ret);
  12396. }
  12397. /**
  12398. * xmlSchemaBuildContentModel:
  12399. * @ctxt: the schema parser context
  12400. * @type: the complex type definition
  12401. * @name: the element name
  12402. *
  12403. * Builds the content model of the complex type.
  12404. */
  12405. static void
  12406. xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
  12407. xmlSchemaParserCtxtPtr ctxt)
  12408. {
  12409. if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
  12410. (type->contModel != NULL) ||
  12411. ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
  12412. (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
  12413. return;
  12414. #ifdef DEBUG_CONTENT
  12415. xmlGenericError(xmlGenericErrorContext,
  12416. "Building content model for %s\n", name);
  12417. #endif
  12418. ctxt->am = NULL;
  12419. ctxt->am = xmlNewAutomata();
  12420. if (ctxt->am == NULL) {
  12421. xmlGenericError(xmlGenericErrorContext,
  12422. "Cannot create automata for complex type %s\n", type->name);
  12423. return;
  12424. }
  12425. ctxt->state = xmlAutomataGetInitState(ctxt->am);
  12426. /*
  12427. * Build the automaton.
  12428. */
  12429. xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
  12430. xmlAutomataSetFinalState(ctxt->am, ctxt->state);
  12431. type->contModel = xmlAutomataCompile(ctxt->am);
  12432. if (type->contModel == NULL) {
  12433. xmlSchemaPCustomErr(ctxt,
  12434. XML_SCHEMAP_INTERNAL,
  12435. WXS_BASIC_CAST type, type->node,
  12436. "Failed to compile the content model", NULL);
  12437. } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
  12438. xmlSchemaPCustomErr(ctxt,
  12439. XML_SCHEMAP_NOT_DETERMINISTIC,
  12440. /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
  12441. WXS_BASIC_CAST type, type->node,
  12442. "The content model is not determinist", NULL);
  12443. } else {
  12444. #ifdef DEBUG_CONTENT_REGEXP
  12445. xmlGenericError(xmlGenericErrorContext,
  12446. "Content model of %s:\n", type->name);
  12447. xmlRegexpPrint(stderr, type->contModel);
  12448. #endif
  12449. }
  12450. ctxt->state = NULL;
  12451. xmlFreeAutomata(ctxt->am);
  12452. ctxt->am = NULL;
  12453. }
  12454. /**
  12455. * xmlSchemaResolveElementReferences:
  12456. * @elem: the schema element context
  12457. * @ctxt: the schema parser context
  12458. *
  12459. * Resolves the references of an element declaration
  12460. * or particle, which has an element declaration as it's
  12461. * term.
  12462. */
  12463. static void
  12464. xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
  12465. xmlSchemaParserCtxtPtr ctxt)
  12466. {
  12467. if ((ctxt == NULL) || (elemDecl == NULL) ||
  12468. ((elemDecl != NULL) &&
  12469. (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
  12470. return;
  12471. elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
  12472. if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
  12473. xmlSchemaTypePtr type;
  12474. /* (type definition) ... otherwise the type definition `resolved`
  12475. * to by the `actual value` of the type [attribute] ...
  12476. */
  12477. type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
  12478. elemDecl->namedTypeNs);
  12479. if (type == NULL) {
  12480. xmlSchemaPResCompAttrErr(ctxt,
  12481. XML_SCHEMAP_SRC_RESOLVE,
  12482. WXS_BASIC_CAST elemDecl, elemDecl->node,
  12483. "type", elemDecl->namedType, elemDecl->namedTypeNs,
  12484. XML_SCHEMA_TYPE_BASIC, "type definition");
  12485. } else
  12486. elemDecl->subtypes = type;
  12487. }
  12488. if (elemDecl->substGroup != NULL) {
  12489. xmlSchemaElementPtr substHead;
  12490. /*
  12491. * FIXME TODO: Do we need a new field in _xmlSchemaElement for
  12492. * substitutionGroup?
  12493. */
  12494. substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
  12495. elemDecl->substGroupNs);
  12496. if (substHead == NULL) {
  12497. xmlSchemaPResCompAttrErr(ctxt,
  12498. XML_SCHEMAP_SRC_RESOLVE,
  12499. WXS_BASIC_CAST elemDecl, NULL,
  12500. "substitutionGroup", elemDecl->substGroup,
  12501. elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
  12502. } else {
  12503. xmlSchemaResolveElementReferences(substHead, ctxt);
  12504. /*
  12505. * Set the "substitution group affiliation".
  12506. * NOTE that now we use the "refDecl" field for this.
  12507. */
  12508. WXS_SUBST_HEAD(elemDecl) = substHead;
  12509. /*
  12510. * The type definitions is set to:
  12511. * SPEC "...the {type definition} of the element
  12512. * declaration `resolved` to by the `actual value`
  12513. * of the substitutionGroup [attribute], if present"
  12514. */
  12515. if (elemDecl->subtypes == NULL)
  12516. elemDecl->subtypes = substHead->subtypes;
  12517. }
  12518. }
  12519. /*
  12520. * SPEC "The definition of anyType serves as the default type definition
  12521. * for element declarations whose XML representation does not specify one."
  12522. */
  12523. if ((elemDecl->subtypes == NULL) &&
  12524. (elemDecl->namedType == NULL) &&
  12525. (elemDecl->substGroup == NULL))
  12526. elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  12527. }
  12528. /**
  12529. * xmlSchemaResolveUnionMemberTypes:
  12530. * @ctxt: the schema parser context
  12531. * @type: the schema simple type definition
  12532. *
  12533. * Checks and builds the "member type definitions" property of the union
  12534. * simple type. This handles part (1), part (2) is done in
  12535. * xmlSchemaFinishMemberTypeDefinitionsProperty()
  12536. *
  12537. * Returns -1 in case of an internal error, 0 otherwise.
  12538. */
  12539. static int
  12540. xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
  12541. xmlSchemaTypePtr type)
  12542. {
  12543. xmlSchemaTypeLinkPtr link, lastLink, newLink;
  12544. xmlSchemaTypePtr memberType;
  12545. /*
  12546. * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
  12547. * define the explicit members as the type definitions `resolved`
  12548. * to by the items in the `actual value` of the memberTypes [attribute],
  12549. * if any, followed by the type definitions corresponding to the
  12550. * <simpleType>s among the [children] of <union>, if any."
  12551. */
  12552. /*
  12553. * Resolve references.
  12554. */
  12555. link = type->memberTypes;
  12556. lastLink = NULL;
  12557. while (link != NULL) {
  12558. const xmlChar *name, *nsName;
  12559. name = ((xmlSchemaQNameRefPtr) link->type)->name;
  12560. nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
  12561. memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
  12562. if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
  12563. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  12564. WXS_BASIC_CAST type, type->node, "memberTypes",
  12565. name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
  12566. /*
  12567. * Remove the member type link.
  12568. */
  12569. if (lastLink == NULL)
  12570. type->memberTypes = link->next;
  12571. else
  12572. lastLink->next = link->next;
  12573. newLink = link;
  12574. link = link->next;
  12575. xmlFree(newLink);
  12576. } else {
  12577. link->type = memberType;
  12578. lastLink = link;
  12579. link = link->next;
  12580. }
  12581. }
  12582. /*
  12583. * Add local simple types,
  12584. */
  12585. memberType = type->subtypes;
  12586. while (memberType != NULL) {
  12587. link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
  12588. if (link == NULL) {
  12589. xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
  12590. return (-1);
  12591. }
  12592. link->type = memberType;
  12593. link->next = NULL;
  12594. if (lastLink == NULL)
  12595. type->memberTypes = link;
  12596. else
  12597. lastLink->next = link;
  12598. lastLink = link;
  12599. memberType = memberType->next;
  12600. }
  12601. return (0);
  12602. }
  12603. /**
  12604. * xmlSchemaIsDerivedFromBuiltInType:
  12605. * @ctxt: the schema parser context
  12606. * @type: the type definition
  12607. * @valType: the value type
  12608. *
  12609. *
  12610. * Returns 1 if the type has the given value type, or
  12611. * is derived from such a type.
  12612. */
  12613. static int
  12614. xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
  12615. {
  12616. if (type == NULL)
  12617. return (0);
  12618. if (WXS_IS_COMPLEX(type))
  12619. return (0);
  12620. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  12621. if (type->builtInType == valType)
  12622. return(1);
  12623. if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
  12624. (type->builtInType == XML_SCHEMAS_ANYTYPE))
  12625. return (0);
  12626. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12627. }
  12628. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12629. }
  12630. #if 0
  12631. /**
  12632. * xmlSchemaIsDerivedFromBuiltInType:
  12633. * @ctxt: the schema parser context
  12634. * @type: the type definition
  12635. * @valType: the value type
  12636. *
  12637. *
  12638. * Returns 1 if the type has the given value type, or
  12639. * is derived from such a type.
  12640. */
  12641. static int
  12642. xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
  12643. {
  12644. if (type == NULL)
  12645. return (0);
  12646. if (WXS_IS_COMPLEX(type))
  12647. return (0);
  12648. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  12649. if (type->builtInType == valType)
  12650. return(1);
  12651. return (0);
  12652. } else
  12653. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12654. return (0);
  12655. }
  12656. static xmlSchemaTypePtr
  12657. xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
  12658. {
  12659. if (type == NULL)
  12660. return (NULL);
  12661. if (WXS_IS_COMPLEX(type))
  12662. return (NULL);
  12663. if (type->type == XML_SCHEMA_TYPE_BASIC)
  12664. return(type);
  12665. return(xmlSchemaQueryBuiltInType(type->subtypes));
  12666. }
  12667. #endif
  12668. /**
  12669. * xmlSchemaGetPrimitiveType:
  12670. * @type: the simpleType definition
  12671. *
  12672. * Returns the primitive type of the given type or
  12673. * NULL in case of error.
  12674. */
  12675. static xmlSchemaTypePtr
  12676. xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
  12677. {
  12678. while (type != NULL) {
  12679. /*
  12680. * Note that anySimpleType is actually not a primitive type
  12681. * but we need that here.
  12682. */
  12683. if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
  12684. (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
  12685. return (type);
  12686. type = type->baseType;
  12687. }
  12688. return (NULL);
  12689. }
  12690. #if 0
  12691. /**
  12692. * xmlSchemaGetBuiltInTypeAncestor:
  12693. * @type: the simpleType definition
  12694. *
  12695. * Returns the primitive type of the given type or
  12696. * NULL in case of error.
  12697. */
  12698. static xmlSchemaTypePtr
  12699. xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
  12700. {
  12701. if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
  12702. return (0);
  12703. while (type != NULL) {
  12704. if (type->type == XML_SCHEMA_TYPE_BASIC)
  12705. return (type);
  12706. type = type->baseType;
  12707. }
  12708. return (NULL);
  12709. }
  12710. #endif
  12711. /**
  12712. * xmlSchemaCloneWildcardNsConstraints:
  12713. * @ctxt: the schema parser context
  12714. * @dest: the destination wildcard
  12715. * @source: the source wildcard
  12716. *
  12717. * Clones the namespace constraints of source
  12718. * and assigns them to dest.
  12719. * Returns -1 on internal error, 0 otherwise.
  12720. */
  12721. static int
  12722. xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
  12723. xmlSchemaWildcardPtr dest,
  12724. xmlSchemaWildcardPtr source)
  12725. {
  12726. xmlSchemaWildcardNsPtr cur, tmp, last;
  12727. if ((source == NULL) || (dest == NULL))
  12728. return(-1);
  12729. dest->any = source->any;
  12730. cur = source->nsSet;
  12731. last = NULL;
  12732. while (cur != NULL) {
  12733. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  12734. if (tmp == NULL)
  12735. return(-1);
  12736. tmp->value = cur->value;
  12737. if (last == NULL)
  12738. dest->nsSet = tmp;
  12739. else
  12740. last->next = tmp;
  12741. last = tmp;
  12742. cur = cur->next;
  12743. }
  12744. if (dest->negNsSet != NULL)
  12745. xmlSchemaFreeWildcardNsSet(dest->negNsSet);
  12746. if (source->negNsSet != NULL) {
  12747. dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12748. if (dest->negNsSet == NULL)
  12749. return(-1);
  12750. dest->negNsSet->value = source->negNsSet->value;
  12751. } else
  12752. dest->negNsSet = NULL;
  12753. return(0);
  12754. }
  12755. /**
  12756. * xmlSchemaUnionWildcards:
  12757. * @ctxt: the schema parser context
  12758. * @completeWild: the first wildcard
  12759. * @curWild: the second wildcard
  12760. *
  12761. * Unions the namespace constraints of the given wildcards.
  12762. * @completeWild will hold the resulting union.
  12763. * Returns a positive error code on failure, -1 in case of an
  12764. * internal error, 0 otherwise.
  12765. */
  12766. static int
  12767. xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
  12768. xmlSchemaWildcardPtr completeWild,
  12769. xmlSchemaWildcardPtr curWild)
  12770. {
  12771. xmlSchemaWildcardNsPtr cur, curB, tmp;
  12772. /*
  12773. * 1 If O1 and O2 are the same value, then that value must be the
  12774. * value.
  12775. */
  12776. if ((completeWild->any == curWild->any) &&
  12777. ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
  12778. ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
  12779. if ((completeWild->negNsSet == NULL) ||
  12780. (completeWild->negNsSet->value == curWild->negNsSet->value)) {
  12781. if (completeWild->nsSet != NULL) {
  12782. int found = 0;
  12783. /*
  12784. * Check equality of sets.
  12785. */
  12786. cur = completeWild->nsSet;
  12787. while (cur != NULL) {
  12788. found = 0;
  12789. curB = curWild->nsSet;
  12790. while (curB != NULL) {
  12791. if (cur->value == curB->value) {
  12792. found = 1;
  12793. break;
  12794. }
  12795. curB = curB->next;
  12796. }
  12797. if (!found)
  12798. break;
  12799. cur = cur->next;
  12800. }
  12801. if (found)
  12802. return(0);
  12803. } else
  12804. return(0);
  12805. }
  12806. }
  12807. /*
  12808. * 2 If either O1 or O2 is any, then any must be the value
  12809. */
  12810. if (completeWild->any != curWild->any) {
  12811. if (completeWild->any == 0) {
  12812. completeWild->any = 1;
  12813. if (completeWild->nsSet != NULL) {
  12814. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12815. completeWild->nsSet = NULL;
  12816. }
  12817. if (completeWild->negNsSet != NULL) {
  12818. xmlFree(completeWild->negNsSet);
  12819. completeWild->negNsSet = NULL;
  12820. }
  12821. }
  12822. return (0);
  12823. }
  12824. /*
  12825. * 3 If both O1 and O2 are sets of (namespace names or `absent`),
  12826. * then the union of those sets must be the value.
  12827. */
  12828. if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
  12829. int found;
  12830. xmlSchemaWildcardNsPtr start;
  12831. cur = curWild->nsSet;
  12832. start = completeWild->nsSet;
  12833. while (cur != NULL) {
  12834. found = 0;
  12835. curB = start;
  12836. while (curB != NULL) {
  12837. if (cur->value == curB->value) {
  12838. found = 1;
  12839. break;
  12840. }
  12841. curB = curB->next;
  12842. }
  12843. if (!found) {
  12844. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  12845. if (tmp == NULL)
  12846. return (-1);
  12847. tmp->value = cur->value;
  12848. tmp->next = completeWild->nsSet;
  12849. completeWild->nsSet = tmp;
  12850. }
  12851. cur = cur->next;
  12852. }
  12853. return(0);
  12854. }
  12855. /*
  12856. * 4 If the two are negations of different values (namespace names
  12857. * or `absent`), then a pair of not and `absent` must be the value.
  12858. */
  12859. if ((completeWild->negNsSet != NULL) &&
  12860. (curWild->negNsSet != NULL) &&
  12861. (completeWild->negNsSet->value != curWild->negNsSet->value)) {
  12862. completeWild->negNsSet->value = NULL;
  12863. return(0);
  12864. }
  12865. /*
  12866. * 5.
  12867. */
  12868. if (((completeWild->negNsSet != NULL) &&
  12869. (completeWild->negNsSet->value != NULL) &&
  12870. (curWild->nsSet != NULL)) ||
  12871. ((curWild->negNsSet != NULL) &&
  12872. (curWild->negNsSet->value != NULL) &&
  12873. (completeWild->nsSet != NULL))) {
  12874. int nsFound, absentFound = 0;
  12875. if (completeWild->nsSet != NULL) {
  12876. cur = completeWild->nsSet;
  12877. curB = curWild->negNsSet;
  12878. } else {
  12879. cur = curWild->nsSet;
  12880. curB = completeWild->negNsSet;
  12881. }
  12882. nsFound = 0;
  12883. while (cur != NULL) {
  12884. if (cur->value == NULL)
  12885. absentFound = 1;
  12886. else if (cur->value == curB->value)
  12887. nsFound = 1;
  12888. if (nsFound && absentFound)
  12889. break;
  12890. cur = cur->next;
  12891. }
  12892. if (nsFound && absentFound) {
  12893. /*
  12894. * 5.1 If the set S includes both the negated namespace
  12895. * name and `absent`, then any must be the value.
  12896. */
  12897. completeWild->any = 1;
  12898. if (completeWild->nsSet != NULL) {
  12899. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12900. completeWild->nsSet = NULL;
  12901. }
  12902. if (completeWild->negNsSet != NULL) {
  12903. xmlFree(completeWild->negNsSet);
  12904. completeWild->negNsSet = NULL;
  12905. }
  12906. } else if (nsFound && (!absentFound)) {
  12907. /*
  12908. * 5.2 If the set S includes the negated namespace name
  12909. * but not `absent`, then a pair of not and `absent` must
  12910. * be the value.
  12911. */
  12912. if (completeWild->nsSet != NULL) {
  12913. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12914. completeWild->nsSet = NULL;
  12915. }
  12916. if (completeWild->negNsSet == NULL) {
  12917. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12918. if (completeWild->negNsSet == NULL)
  12919. return (-1);
  12920. }
  12921. completeWild->negNsSet->value = NULL;
  12922. } else if ((!nsFound) && absentFound) {
  12923. /*
  12924. * 5.3 If the set S includes `absent` but not the negated
  12925. * namespace name, then the union is not expressible.
  12926. */
  12927. xmlSchemaPErr(ctxt, completeWild->node,
  12928. XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
  12929. "The union of the wildcard is not expressible.\n",
  12930. NULL, NULL);
  12931. return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
  12932. } else if ((!nsFound) && (!absentFound)) {
  12933. /*
  12934. * 5.4 If the set S does not include either the negated namespace
  12935. * name or `absent`, then whichever of O1 or O2 is a pair of not
  12936. * and a namespace name must be the value.
  12937. */
  12938. if (completeWild->negNsSet == NULL) {
  12939. if (completeWild->nsSet != NULL) {
  12940. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12941. completeWild->nsSet = NULL;
  12942. }
  12943. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12944. if (completeWild->negNsSet == NULL)
  12945. return (-1);
  12946. completeWild->negNsSet->value = curWild->negNsSet->value;
  12947. }
  12948. }
  12949. return (0);
  12950. }
  12951. /*
  12952. * 6.
  12953. */
  12954. if (((completeWild->negNsSet != NULL) &&
  12955. (completeWild->negNsSet->value == NULL) &&
  12956. (curWild->nsSet != NULL)) ||
  12957. ((curWild->negNsSet != NULL) &&
  12958. (curWild->negNsSet->value == NULL) &&
  12959. (completeWild->nsSet != NULL))) {
  12960. if (completeWild->nsSet != NULL) {
  12961. cur = completeWild->nsSet;
  12962. } else {
  12963. cur = curWild->nsSet;
  12964. }
  12965. while (cur != NULL) {
  12966. if (cur->value == NULL) {
  12967. /*
  12968. * 6.1 If the set S includes `absent`, then any must be the
  12969. * value.
  12970. */
  12971. completeWild->any = 1;
  12972. if (completeWild->nsSet != NULL) {
  12973. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12974. completeWild->nsSet = NULL;
  12975. }
  12976. if (completeWild->negNsSet != NULL) {
  12977. xmlFree(completeWild->negNsSet);
  12978. completeWild->negNsSet = NULL;
  12979. }
  12980. return (0);
  12981. }
  12982. cur = cur->next;
  12983. }
  12984. if (completeWild->negNsSet == NULL) {
  12985. /*
  12986. * 6.2 If the set S does not include `absent`, then a pair of not
  12987. * and `absent` must be the value.
  12988. */
  12989. if (completeWild->nsSet != NULL) {
  12990. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12991. completeWild->nsSet = NULL;
  12992. }
  12993. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12994. if (completeWild->negNsSet == NULL)
  12995. return (-1);
  12996. completeWild->negNsSet->value = NULL;
  12997. }
  12998. return (0);
  12999. }
  13000. return (0);
  13001. }
  13002. /**
  13003. * xmlSchemaIntersectWildcards:
  13004. * @ctxt: the schema parser context
  13005. * @completeWild: the first wildcard
  13006. * @curWild: the second wildcard
  13007. *
  13008. * Intersects the namespace constraints of the given wildcards.
  13009. * @completeWild will hold the resulting intersection.
  13010. * Returns a positive error code on failure, -1 in case of an
  13011. * internal error, 0 otherwise.
  13012. */
  13013. static int
  13014. xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
  13015. xmlSchemaWildcardPtr completeWild,
  13016. xmlSchemaWildcardPtr curWild)
  13017. {
  13018. xmlSchemaWildcardNsPtr cur, curB, prev, tmp;
  13019. /*
  13020. * 1 If O1 and O2 are the same value, then that value must be the
  13021. * value.
  13022. */
  13023. if ((completeWild->any == curWild->any) &&
  13024. ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
  13025. ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
  13026. if ((completeWild->negNsSet == NULL) ||
  13027. (completeWild->negNsSet->value == curWild->negNsSet->value)) {
  13028. if (completeWild->nsSet != NULL) {
  13029. int found = 0;
  13030. /*
  13031. * Check equality of sets.
  13032. */
  13033. cur = completeWild->nsSet;
  13034. while (cur != NULL) {
  13035. found = 0;
  13036. curB = curWild->nsSet;
  13037. while (curB != NULL) {
  13038. if (cur->value == curB->value) {
  13039. found = 1;
  13040. break;
  13041. }
  13042. curB = curB->next;
  13043. }
  13044. if (!found)
  13045. break;
  13046. cur = cur->next;
  13047. }
  13048. if (found)
  13049. return(0);
  13050. } else
  13051. return(0);
  13052. }
  13053. }
  13054. /*
  13055. * 2 If either O1 or O2 is any, then the other must be the value.
  13056. */
  13057. if ((completeWild->any != curWild->any) && (completeWild->any)) {
  13058. if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
  13059. return(-1);
  13060. return(0);
  13061. }
  13062. /*
  13063. * 3 If either O1 or O2 is a pair of not and a value (a namespace
  13064. * name or `absent`) and the other is a set of (namespace names or
  13065. * `absent`), then that set, minus the negated value if it was in
  13066. * the set, minus `absent` if it was in the set, must be the value.
  13067. */
  13068. if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
  13069. ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
  13070. const xmlChar *neg;
  13071. if (completeWild->nsSet == NULL) {
  13072. neg = completeWild->negNsSet->value;
  13073. if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
  13074. return(-1);
  13075. } else
  13076. neg = curWild->negNsSet->value;
  13077. /*
  13078. * Remove absent and negated.
  13079. */
  13080. prev = NULL;
  13081. cur = completeWild->nsSet;
  13082. while (cur != NULL) {
  13083. if (cur->value == NULL) {
  13084. if (prev == NULL)
  13085. completeWild->nsSet = cur->next;
  13086. else
  13087. prev->next = cur->next;
  13088. xmlFree(cur);
  13089. break;
  13090. }
  13091. prev = cur;
  13092. cur = cur->next;
  13093. }
  13094. if (neg != NULL) {
  13095. prev = NULL;
  13096. cur = completeWild->nsSet;
  13097. while (cur != NULL) {
  13098. if (cur->value == neg) {
  13099. if (prev == NULL)
  13100. completeWild->nsSet = cur->next;
  13101. else
  13102. prev->next = cur->next;
  13103. xmlFree(cur);
  13104. break;
  13105. }
  13106. prev = cur;
  13107. cur = cur->next;
  13108. }
  13109. }
  13110. return(0);
  13111. }
  13112. /*
  13113. * 4 If both O1 and O2 are sets of (namespace names or `absent`),
  13114. * then the intersection of those sets must be the value.
  13115. */
  13116. if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
  13117. int found;
  13118. cur = completeWild->nsSet;
  13119. prev = NULL;
  13120. while (cur != NULL) {
  13121. found = 0;
  13122. curB = curWild->nsSet;
  13123. while (curB != NULL) {
  13124. if (cur->value == curB->value) {
  13125. found = 1;
  13126. break;
  13127. }
  13128. curB = curB->next;
  13129. }
  13130. if (!found) {
  13131. if (prev == NULL)
  13132. completeWild->nsSet = cur->next;
  13133. else
  13134. prev->next = cur->next;
  13135. tmp = cur->next;
  13136. xmlFree(cur);
  13137. cur = tmp;
  13138. continue;
  13139. }
  13140. prev = cur;
  13141. cur = cur->next;
  13142. }
  13143. return(0);
  13144. }
  13145. /* 5 If the two are negations of different namespace names,
  13146. * then the intersection is not expressible
  13147. */
  13148. if ((completeWild->negNsSet != NULL) &&
  13149. (curWild->negNsSet != NULL) &&
  13150. (completeWild->negNsSet->value != curWild->negNsSet->value) &&
  13151. (completeWild->negNsSet->value != NULL) &&
  13152. (curWild->negNsSet->value != NULL)) {
  13153. xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
  13154. "The intersection of the wildcard is not expressible.\n",
  13155. NULL, NULL);
  13156. return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
  13157. }
  13158. /*
  13159. * 6 If the one is a negation of a namespace name and the other
  13160. * is a negation of `absent`, then the one which is the negation
  13161. * of a namespace name must be the value.
  13162. */
  13163. if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
  13164. (completeWild->negNsSet->value != curWild->negNsSet->value) &&
  13165. (completeWild->negNsSet->value == NULL)) {
  13166. completeWild->negNsSet->value = curWild->negNsSet->value;
  13167. }
  13168. return(0);
  13169. }
  13170. /**
  13171. * xmlSchemaIsWildcardNsConstraintSubset:
  13172. * @ctxt: the schema parser context
  13173. * @sub: the first wildcard
  13174. * @super: the second wildcard
  13175. *
  13176. * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
  13177. *
  13178. * Returns 0 if the namespace constraint of @sub is an intensional
  13179. * subset of @super, 1 otherwise.
  13180. */
  13181. static int
  13182. xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
  13183. xmlSchemaWildcardPtr super)
  13184. {
  13185. /*
  13186. * 1 super must be any.
  13187. */
  13188. if (super->any)
  13189. return (0);
  13190. /*
  13191. * 2.1 sub must be a pair of not and a namespace name or `absent`.
  13192. * 2.2 super must be a pair of not and the same value.
  13193. */
  13194. if ((sub->negNsSet != NULL) &&
  13195. (super->negNsSet != NULL) &&
  13196. (sub->negNsSet->value == super->negNsSet->value))
  13197. return (0);
  13198. /*
  13199. * 3.1 sub must be a set whose members are either namespace names or `absent`.
  13200. */
  13201. if (sub->nsSet != NULL) {
  13202. /*
  13203. * 3.2.1 super must be the same set or a superset thereof.
  13204. */
  13205. if (super->nsSet != NULL) {
  13206. xmlSchemaWildcardNsPtr cur, curB;
  13207. int found = 0;
  13208. cur = sub->nsSet;
  13209. while (cur != NULL) {
  13210. found = 0;
  13211. curB = super->nsSet;
  13212. while (curB != NULL) {
  13213. if (cur->value == curB->value) {
  13214. found = 1;
  13215. break;
  13216. }
  13217. curB = curB->next;
  13218. }
  13219. if (!found)
  13220. return (1);
  13221. cur = cur->next;
  13222. }
  13223. if (found)
  13224. return (0);
  13225. } else if (super->negNsSet != NULL) {
  13226. xmlSchemaWildcardNsPtr cur;
  13227. /*
  13228. * 3.2.2 super must be a pair of not and a namespace name or
  13229. * `absent` and that value must not be in sub's set.
  13230. */
  13231. cur = sub->nsSet;
  13232. while (cur != NULL) {
  13233. if (cur->value == super->negNsSet->value)
  13234. return (1);
  13235. cur = cur->next;
  13236. }
  13237. return (0);
  13238. }
  13239. }
  13240. return (1);
  13241. }
  13242. static int
  13243. xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
  13244. int *fixed,
  13245. const xmlChar **value,
  13246. xmlSchemaValPtr *val)
  13247. {
  13248. *fixed = 0;
  13249. *value = NULL;
  13250. if (val != 0)
  13251. *val = NULL;
  13252. if (attruse->defValue != NULL) {
  13253. *value = attruse->defValue;
  13254. if (val != NULL)
  13255. *val = attruse->defVal;
  13256. if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
  13257. *fixed = 1;
  13258. return(1);
  13259. } else if ((attruse->attrDecl != NULL) &&
  13260. (attruse->attrDecl->defValue != NULL)) {
  13261. *value = attruse->attrDecl->defValue;
  13262. if (val != NULL)
  13263. *val = attruse->attrDecl->defVal;
  13264. if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
  13265. *fixed = 1;
  13266. return(1);
  13267. }
  13268. return(0);
  13269. }
  13270. /**
  13271. * xmlSchemaCheckCVCWildcardNamespace:
  13272. * @wild: the wildcard
  13273. * @ns: the namespace
  13274. *
  13275. * Validation Rule: Wildcard allows Namespace Name
  13276. * (cvc-wildcard-namespace)
  13277. *
  13278. * Returns 0 if the given namespace matches the wildcard,
  13279. * 1 otherwise and -1 on API errors.
  13280. */
  13281. static int
  13282. xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
  13283. const xmlChar* ns)
  13284. {
  13285. if (wild == NULL)
  13286. return(-1);
  13287. if (wild->any)
  13288. return(0);
  13289. else if (wild->nsSet != NULL) {
  13290. xmlSchemaWildcardNsPtr cur;
  13291. cur = wild->nsSet;
  13292. while (cur != NULL) {
  13293. if (xmlStrEqual(cur->value, ns))
  13294. return(0);
  13295. cur = cur->next;
  13296. }
  13297. } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
  13298. (!xmlStrEqual(wild->negNsSet->value, ns)))
  13299. return(0);
  13300. return(1);
  13301. }
  13302. #define XML_SCHEMA_ACTION_DERIVE 0
  13303. #define XML_SCHEMA_ACTION_REDEFINE 1
  13304. #define WXS_ACTION_STR(a) \
  13305. ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
  13306. /*
  13307. * Schema Component Constraint:
  13308. * Derivation Valid (Restriction, Complex)
  13309. * derivation-ok-restriction (2) - (4)
  13310. *
  13311. * ATTENTION:
  13312. * In XML Schema 1.1 this will be:
  13313. * Validation Rule:
  13314. * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
  13315. *
  13316. */
  13317. static int
  13318. xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
  13319. int action,
  13320. xmlSchemaBasicItemPtr item,
  13321. xmlSchemaBasicItemPtr baseItem,
  13322. xmlSchemaItemListPtr uses,
  13323. xmlSchemaItemListPtr baseUses,
  13324. xmlSchemaWildcardPtr wild,
  13325. xmlSchemaWildcardPtr baseWild)
  13326. {
  13327. xmlSchemaAttributeUsePtr cur = NULL, bcur;
  13328. int i, j, found; /* err = 0; */
  13329. const xmlChar *bEffValue;
  13330. int effFixed;
  13331. if (uses != NULL) {
  13332. for (i = 0; i < uses->nbItems; i++) {
  13333. cur = uses->items[i];
  13334. found = 0;
  13335. if (baseUses == NULL)
  13336. goto not_found;
  13337. for (j = 0; j < baseUses->nbItems; j++) {
  13338. bcur = baseUses->items[j];
  13339. if ((WXS_ATTRUSE_DECL_NAME(cur) ==
  13340. WXS_ATTRUSE_DECL_NAME(bcur)) &&
  13341. (WXS_ATTRUSE_DECL_TNS(cur) ==
  13342. WXS_ATTRUSE_DECL_TNS(bcur)))
  13343. {
  13344. /*
  13345. * (2.1) "If there is an attribute use in the {attribute
  13346. * uses} of the {base type definition} (call this B) whose
  13347. * {attribute declaration} has the same {name} and {target
  13348. * namespace}, then all of the following must be true:"
  13349. */
  13350. found = 1;
  13351. if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
  13352. (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
  13353. {
  13354. xmlChar *str = NULL;
  13355. /*
  13356. * (2.1.1) "one of the following must be true:"
  13357. * (2.1.1.1) "B's {required} is false."
  13358. * (2.1.1.2) "R's {required} is true."
  13359. */
  13360. xmlSchemaPAttrUseErr4(pctxt,
  13361. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
  13362. WXS_ITEM_NODE(item), item, cur,
  13363. "The 'optional' attribute use is inconsistent "
  13364. "with the corresponding 'required' attribute use of "
  13365. "the %s %s",
  13366. WXS_ACTION_STR(action),
  13367. xmlSchemaGetComponentDesignation(&str, baseItem),
  13368. NULL, NULL);
  13369. FREE_AND_NULL(str);
  13370. /* err = pctxt->err; */
  13371. } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
  13372. WXS_ATTRUSE_TYPEDEF(cur),
  13373. WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
  13374. {
  13375. xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
  13376. /*
  13377. * SPEC (2.1.2) "R's {attribute declaration}'s
  13378. * {type definition} must be validly derived from
  13379. * B's {type definition} given the empty set as
  13380. * defined in Type Derivation OK (Simple) ($3.14.6)."
  13381. */
  13382. xmlSchemaPAttrUseErr4(pctxt,
  13383. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
  13384. WXS_ITEM_NODE(item), item, cur,
  13385. "The attribute declaration's %s "
  13386. "is not validly derived from "
  13387. "the corresponding %s of the "
  13388. "attribute declaration in the %s %s",
  13389. xmlSchemaGetComponentDesignation(&strA,
  13390. WXS_ATTRUSE_TYPEDEF(cur)),
  13391. xmlSchemaGetComponentDesignation(&strB,
  13392. WXS_ATTRUSE_TYPEDEF(bcur)),
  13393. WXS_ACTION_STR(action),
  13394. xmlSchemaGetComponentDesignation(&strC, baseItem));
  13395. /* xmlSchemaGetComponentDesignation(&str, baseItem), */
  13396. FREE_AND_NULL(strA);
  13397. FREE_AND_NULL(strB);
  13398. FREE_AND_NULL(strC);
  13399. /* err = pctxt->err; */
  13400. } else {
  13401. /*
  13402. * 2.1.3 [Definition:] Let the effective value
  13403. * constraint of an attribute use be its {value
  13404. * constraint}, if present, otherwise its {attribute
  13405. * declaration}'s {value constraint} .
  13406. */
  13407. xmlSchemaGetEffectiveValueConstraint(bcur,
  13408. &effFixed, &bEffValue, NULL);
  13409. /*
  13410. * 2.1.3 ... one of the following must be true
  13411. *
  13412. * 2.1.3.1 B's `effective value constraint` is
  13413. * `absent` or default.
  13414. */
  13415. if ((bEffValue != NULL) &&
  13416. (effFixed == 1)) {
  13417. const xmlChar *rEffValue = NULL;
  13418. xmlSchemaGetEffectiveValueConstraint(bcur,
  13419. &effFixed, &rEffValue, NULL);
  13420. /*
  13421. * 2.1.3.2 R's `effective value constraint` is
  13422. * fixed with the same string as B's.
  13423. * MAYBE TODO: Compare the computed values.
  13424. * Hmm, it says "same string" so
  13425. * string-equality might really be sufficient.
  13426. */
  13427. if ((effFixed == 0) ||
  13428. (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
  13429. {
  13430. xmlChar *str = NULL;
  13431. xmlSchemaPAttrUseErr4(pctxt,
  13432. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
  13433. WXS_ITEM_NODE(item), item, cur,
  13434. "The effective value constraint of the "
  13435. "attribute use is inconsistent with "
  13436. "its correspondent in the %s %s",
  13437. WXS_ACTION_STR(action),
  13438. xmlSchemaGetComponentDesignation(&str,
  13439. baseItem),
  13440. NULL, NULL);
  13441. FREE_AND_NULL(str);
  13442. /* err = pctxt->err; */
  13443. }
  13444. }
  13445. }
  13446. break;
  13447. }
  13448. }
  13449. not_found:
  13450. if (!found) {
  13451. /*
  13452. * (2.2) "otherwise the {base type definition} must have an
  13453. * {attribute wildcard} and the {target namespace} of the
  13454. * R's {attribute declaration} must be `valid` with respect
  13455. * to that wildcard, as defined in Wildcard allows Namespace
  13456. * Name ($3.10.4)."
  13457. */
  13458. if ((baseWild == NULL) ||
  13459. (xmlSchemaCheckCVCWildcardNamespace(baseWild,
  13460. (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
  13461. {
  13462. xmlChar *str = NULL;
  13463. xmlSchemaPAttrUseErr4(pctxt,
  13464. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
  13465. WXS_ITEM_NODE(item), item, cur,
  13466. "Neither a matching attribute use, "
  13467. "nor a matching wildcard exists in the %s %s",
  13468. WXS_ACTION_STR(action),
  13469. xmlSchemaGetComponentDesignation(&str, baseItem),
  13470. NULL, NULL);
  13471. FREE_AND_NULL(str);
  13472. /* err = pctxt->err; */
  13473. }
  13474. }
  13475. }
  13476. }
  13477. /*
  13478. * SPEC derivation-ok-restriction (3):
  13479. * (3) "For each attribute use in the {attribute uses} of the {base type
  13480. * definition} whose {required} is true, there must be an attribute
  13481. * use with an {attribute declaration} with the same {name} and
  13482. * {target namespace} as its {attribute declaration} in the {attribute
  13483. * uses} of the complex type definition itself whose {required} is true.
  13484. */
  13485. if (baseUses != NULL) {
  13486. for (j = 0; j < baseUses->nbItems; j++) {
  13487. bcur = baseUses->items[j];
  13488. if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
  13489. continue;
  13490. found = 0;
  13491. if (uses != NULL) {
  13492. for (i = 0; i < uses->nbItems; i++) {
  13493. cur = uses->items[i];
  13494. if ((WXS_ATTRUSE_DECL_NAME(cur) ==
  13495. WXS_ATTRUSE_DECL_NAME(bcur)) &&
  13496. (WXS_ATTRUSE_DECL_TNS(cur) ==
  13497. WXS_ATTRUSE_DECL_TNS(bcur))) {
  13498. found = 1;
  13499. break;
  13500. }
  13501. }
  13502. }
  13503. if (!found) {
  13504. xmlChar *strA = NULL, *strB = NULL;
  13505. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13506. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
  13507. NULL, item,
  13508. "A matching attribute use for the "
  13509. "'required' %s of the %s %s is missing",
  13510. xmlSchemaGetComponentDesignation(&strA, bcur),
  13511. WXS_ACTION_STR(action),
  13512. xmlSchemaGetComponentDesignation(&strB, baseItem),
  13513. NULL);
  13514. FREE_AND_NULL(strA);
  13515. FREE_AND_NULL(strB);
  13516. }
  13517. }
  13518. }
  13519. /*
  13520. * derivation-ok-restriction (4)
  13521. */
  13522. if (wild != NULL) {
  13523. /*
  13524. * (4) "If there is an {attribute wildcard}, all of the
  13525. * following must be true:"
  13526. */
  13527. if (baseWild == NULL) {
  13528. xmlChar *str = NULL;
  13529. /*
  13530. * (4.1) "The {base type definition} must also have one."
  13531. */
  13532. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13533. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
  13534. NULL, item,
  13535. "The %s has an attribute wildcard, "
  13536. "but the %s %s '%s' does not have one",
  13537. WXS_ITEM_TYPE_NAME(item),
  13538. WXS_ACTION_STR(action),
  13539. WXS_ITEM_TYPE_NAME(baseItem),
  13540. xmlSchemaGetComponentQName(&str, baseItem));
  13541. FREE_AND_NULL(str);
  13542. return(pctxt->err);
  13543. } else if ((baseWild->any == 0) &&
  13544. xmlSchemaCheckCOSNSSubset(wild, baseWild))
  13545. {
  13546. xmlChar *str = NULL;
  13547. /*
  13548. * (4.2) "The complex type definition's {attribute wildcard}'s
  13549. * {namespace constraint} must be a subset of the {base type
  13550. * definition}'s {attribute wildcard}'s {namespace constraint},
  13551. * as defined by Wildcard Subset ($3.10.6)."
  13552. */
  13553. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13554. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
  13555. NULL, item,
  13556. "The attribute wildcard is not a valid "
  13557. "subset of the wildcard in the %s %s '%s'",
  13558. WXS_ACTION_STR(action),
  13559. WXS_ITEM_TYPE_NAME(baseItem),
  13560. xmlSchemaGetComponentQName(&str, baseItem),
  13561. NULL);
  13562. FREE_AND_NULL(str);
  13563. return(pctxt->err);
  13564. }
  13565. /* 4.3 Unless the {base type definition} is the `ur-type
  13566. * definition`, the complex type definition's {attribute
  13567. * wildcard}'s {process contents} must be identical to or
  13568. * stronger than the {base type definition}'s {attribute
  13569. * wildcard}'s {process contents}, where strict is stronger
  13570. * than lax is stronger than skip.
  13571. */
  13572. if ((! WXS_IS_ANYTYPE(baseItem)) &&
  13573. (wild->processContents < baseWild->processContents)) {
  13574. xmlChar *str = NULL;
  13575. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13576. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
  13577. NULL, baseItem,
  13578. "The {process contents} of the attribute wildcard is "
  13579. "weaker than the one in the %s %s '%s'",
  13580. WXS_ACTION_STR(action),
  13581. WXS_ITEM_TYPE_NAME(baseItem),
  13582. xmlSchemaGetComponentQName(&str, baseItem),
  13583. NULL);
  13584. FREE_AND_NULL(str)
  13585. return(pctxt->err);
  13586. }
  13587. }
  13588. return(0);
  13589. }
  13590. static int
  13591. xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
  13592. xmlSchemaBasicItemPtr item,
  13593. xmlSchemaWildcardPtr *completeWild,
  13594. xmlSchemaItemListPtr list,
  13595. xmlSchemaItemListPtr prohibs);
  13596. /**
  13597. * xmlSchemaFixupTypeAttributeUses:
  13598. * @ctxt: the schema parser context
  13599. * @type: the complex type definition
  13600. *
  13601. *
  13602. * Builds the wildcard and the attribute uses on the given complex type.
  13603. * Returns -1 if an internal error occurs, 0 otherwise.
  13604. *
  13605. * ATTENTION TODO: Experimentally this uses pointer comparisons for
  13606. * strings, so recheck this if we start to hardcode some schemata, since
  13607. * they might not be in the same dict.
  13608. * NOTE: It is allowed to "extend" the xs:anyType type.
  13609. */
  13610. static int
  13611. xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
  13612. xmlSchemaTypePtr type)
  13613. {
  13614. xmlSchemaTypePtr baseType = NULL;
  13615. xmlSchemaAttributeUsePtr use;
  13616. xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
  13617. if (type->baseType == NULL) {
  13618. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13619. "no base type");
  13620. return (-1);
  13621. }
  13622. baseType = type->baseType;
  13623. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  13624. if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
  13625. return(-1);
  13626. uses = type->attrUses;
  13627. baseUses = baseType->attrUses;
  13628. /*
  13629. * Expand attribute group references. And build the 'complete'
  13630. * wildcard, i.e. intersect multiple wildcards.
  13631. * Move attribute prohibitions into a separate list.
  13632. */
  13633. if (uses != NULL) {
  13634. if (WXS_IS_RESTRICTION(type)) {
  13635. /*
  13636. * This one will transfer all attr. prohibitions
  13637. * into pctxt->attrProhibs.
  13638. */
  13639. if (xmlSchemaExpandAttributeGroupRefs(pctxt,
  13640. WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
  13641. pctxt->attrProhibs) == -1)
  13642. {
  13643. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13644. "failed to expand attributes");
  13645. }
  13646. if (pctxt->attrProhibs->nbItems != 0)
  13647. prohibs = pctxt->attrProhibs;
  13648. } else {
  13649. if (xmlSchemaExpandAttributeGroupRefs(pctxt,
  13650. WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
  13651. NULL) == -1)
  13652. {
  13653. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13654. "failed to expand attributes");
  13655. }
  13656. }
  13657. }
  13658. /*
  13659. * Inherit the attribute uses of the base type.
  13660. */
  13661. if (baseUses != NULL) {
  13662. int i, j;
  13663. xmlSchemaAttributeUseProhibPtr pro;
  13664. if (WXS_IS_RESTRICTION(type)) {
  13665. int usesCount;
  13666. xmlSchemaAttributeUsePtr tmp;
  13667. if (uses != NULL)
  13668. usesCount = uses->nbItems;
  13669. else
  13670. usesCount = 0;
  13671. /* Restriction. */
  13672. for (i = 0; i < baseUses->nbItems; i++) {
  13673. use = baseUses->items[i];
  13674. if (prohibs) {
  13675. /*
  13676. * Filter out prohibited uses.
  13677. */
  13678. for (j = 0; j < prohibs->nbItems; j++) {
  13679. pro = prohibs->items[j];
  13680. if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
  13681. (WXS_ATTRUSE_DECL_TNS(use) ==
  13682. pro->targetNamespace))
  13683. {
  13684. goto inherit_next;
  13685. }
  13686. }
  13687. }
  13688. if (usesCount) {
  13689. /*
  13690. * Filter out existing uses.
  13691. */
  13692. for (j = 0; j < usesCount; j++) {
  13693. tmp = uses->items[j];
  13694. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  13695. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  13696. (WXS_ATTRUSE_DECL_TNS(use) ==
  13697. WXS_ATTRUSE_DECL_TNS(tmp)))
  13698. {
  13699. goto inherit_next;
  13700. }
  13701. }
  13702. }
  13703. if (uses == NULL) {
  13704. type->attrUses = xmlSchemaItemListCreate();
  13705. if (type->attrUses == NULL)
  13706. goto exit_failure;
  13707. uses = type->attrUses;
  13708. }
  13709. xmlSchemaItemListAddSize(uses, 2, use);
  13710. inherit_next: {}
  13711. }
  13712. } else {
  13713. /* Extension. */
  13714. for (i = 0; i < baseUses->nbItems; i++) {
  13715. use = baseUses->items[i];
  13716. if (uses == NULL) {
  13717. type->attrUses = xmlSchemaItemListCreate();
  13718. if (type->attrUses == NULL)
  13719. goto exit_failure;
  13720. uses = type->attrUses;
  13721. }
  13722. xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
  13723. }
  13724. }
  13725. }
  13726. /*
  13727. * Shrink attr. uses.
  13728. */
  13729. if (uses) {
  13730. if (uses->nbItems == 0) {
  13731. xmlSchemaItemListFree(uses);
  13732. type->attrUses = NULL;
  13733. }
  13734. /*
  13735. * TODO: We could shrink the size of the array
  13736. * to fit the actual number of items.
  13737. */
  13738. }
  13739. /*
  13740. * Compute the complete wildcard.
  13741. */
  13742. if (WXS_IS_EXTENSION(type)) {
  13743. if (baseType->attributeWildcard != NULL) {
  13744. /*
  13745. * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
  13746. * the appropriate case among the following:"
  13747. */
  13748. if (type->attributeWildcard != NULL) {
  13749. /*
  13750. * Union the complete wildcard with the base wildcard.
  13751. * SPEC {attribute wildcard}
  13752. * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
  13753. * and {annotation} are those of the `complete wildcard`,
  13754. * and whose {namespace constraint} is the intensional union
  13755. * of the {namespace constraint} of the `complete wildcard`
  13756. * and of the `base wildcard`, as defined in Attribute
  13757. * Wildcard Union ($3.10.6)."
  13758. */
  13759. if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
  13760. baseType->attributeWildcard) == -1)
  13761. goto exit_failure;
  13762. } else {
  13763. /*
  13764. * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
  13765. * then the `base wildcard`."
  13766. */
  13767. type->attributeWildcard = baseType->attributeWildcard;
  13768. }
  13769. } else {
  13770. /*
  13771. * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
  13772. * `complete wildcard`"
  13773. * NOOP
  13774. */
  13775. }
  13776. } else {
  13777. /*
  13778. * SPEC {attribute wildcard}
  13779. * (3.1) "If the <restriction> alternative is chosen, then the
  13780. * `complete wildcard`;"
  13781. * NOOP
  13782. */
  13783. }
  13784. return (0);
  13785. exit_failure:
  13786. return(-1);
  13787. }
  13788. /**
  13789. * xmlSchemaTypeFinalContains:
  13790. * @schema: the schema
  13791. * @type: the type definition
  13792. * @final: the final
  13793. *
  13794. * Evaluates if a type definition contains the given "final".
  13795. * This does take "finalDefault" into account as well.
  13796. *
  13797. * Returns 1 if the type does contain the given "final",
  13798. * 0 otherwise.
  13799. */
  13800. static int
  13801. xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
  13802. {
  13803. if (type == NULL)
  13804. return (0);
  13805. if (type->flags & final)
  13806. return (1);
  13807. else
  13808. return (0);
  13809. }
  13810. /**
  13811. * xmlSchemaGetUnionSimpleTypeMemberTypes:
  13812. * @type: the Union Simple Type
  13813. *
  13814. * Returns a list of member types of @type if existing,
  13815. * returns NULL otherwise.
  13816. */
  13817. static xmlSchemaTypeLinkPtr
  13818. xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
  13819. {
  13820. while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
  13821. if (type->memberTypes != NULL)
  13822. return (type->memberTypes);
  13823. else
  13824. type = type->baseType;
  13825. }
  13826. return (NULL);
  13827. }
  13828. #if 0
  13829. /**
  13830. * xmlSchemaGetParticleTotalRangeMin:
  13831. * @particle: the particle
  13832. *
  13833. * Schema Component Constraint: Effective Total Range
  13834. * (all and sequence) + (choice)
  13835. *
  13836. * Returns the minimum Effective Total Range.
  13837. */
  13838. static int
  13839. xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
  13840. {
  13841. if ((particle->children == NULL) ||
  13842. (particle->minOccurs == 0))
  13843. return (0);
  13844. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13845. int min = -1, cur;
  13846. xmlSchemaParticlePtr part =
  13847. (xmlSchemaParticlePtr) particle->children->children;
  13848. if (part == NULL)
  13849. return (0);
  13850. while (part != NULL) {
  13851. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13852. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13853. cur = part->minOccurs;
  13854. else
  13855. cur = xmlSchemaGetParticleTotalRangeMin(part);
  13856. if (cur == 0)
  13857. return (0);
  13858. if ((min > cur) || (min == -1))
  13859. min = cur;
  13860. part = (xmlSchemaParticlePtr) part->next;
  13861. }
  13862. return (particle->minOccurs * min);
  13863. } else {
  13864. /* <all> and <sequence> */
  13865. int sum = 0;
  13866. xmlSchemaParticlePtr part =
  13867. (xmlSchemaParticlePtr) particle->children->children;
  13868. if (part == NULL)
  13869. return (0);
  13870. do {
  13871. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13872. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13873. sum += part->minOccurs;
  13874. else
  13875. sum += xmlSchemaGetParticleTotalRangeMin(part);
  13876. part = (xmlSchemaParticlePtr) part->next;
  13877. } while (part != NULL);
  13878. return (particle->minOccurs * sum);
  13879. }
  13880. }
  13881. /**
  13882. * xmlSchemaGetParticleTotalRangeMax:
  13883. * @particle: the particle
  13884. *
  13885. * Schema Component Constraint: Effective Total Range
  13886. * (all and sequence) + (choice)
  13887. *
  13888. * Returns the maximum Effective Total Range.
  13889. */
  13890. static int
  13891. xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
  13892. {
  13893. if ((particle->children == NULL) ||
  13894. (particle->children->children == NULL))
  13895. return (0);
  13896. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13897. int max = -1, cur;
  13898. xmlSchemaParticlePtr part =
  13899. (xmlSchemaParticlePtr) particle->children->children;
  13900. for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
  13901. if (part->children == NULL)
  13902. continue;
  13903. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13904. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13905. cur = part->maxOccurs;
  13906. else
  13907. cur = xmlSchemaGetParticleTotalRangeMax(part);
  13908. if (cur == UNBOUNDED)
  13909. return (UNBOUNDED);
  13910. if ((max < cur) || (max == -1))
  13911. max = cur;
  13912. }
  13913. /* TODO: Handle overflows? */
  13914. return (particle->maxOccurs * max);
  13915. } else {
  13916. /* <all> and <sequence> */
  13917. int sum = 0, cur;
  13918. xmlSchemaParticlePtr part =
  13919. (xmlSchemaParticlePtr) particle->children->children;
  13920. for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
  13921. if (part->children == NULL)
  13922. continue;
  13923. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13924. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13925. cur = part->maxOccurs;
  13926. else
  13927. cur = xmlSchemaGetParticleTotalRangeMax(part);
  13928. if (cur == UNBOUNDED)
  13929. return (UNBOUNDED);
  13930. if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
  13931. return (UNBOUNDED);
  13932. sum += cur;
  13933. }
  13934. /* TODO: Handle overflows? */
  13935. return (particle->maxOccurs * sum);
  13936. }
  13937. }
  13938. #endif
  13939. /**
  13940. * xmlSchemaGetParticleEmptiable:
  13941. * @particle: the particle
  13942. *
  13943. * Returns 1 if emptiable, 0 otherwise.
  13944. */
  13945. static int
  13946. xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
  13947. {
  13948. xmlSchemaParticlePtr part;
  13949. int emptiable;
  13950. if ((particle->children == NULL) || (particle->minOccurs == 0))
  13951. return (1);
  13952. part = (xmlSchemaParticlePtr) particle->children->children;
  13953. if (part == NULL)
  13954. return (1);
  13955. while (part != NULL) {
  13956. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13957. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13958. emptiable = (part->minOccurs == 0);
  13959. else
  13960. emptiable = xmlSchemaGetParticleEmptiable(part);
  13961. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13962. if (emptiable)
  13963. return (1);
  13964. } else {
  13965. /* <all> and <sequence> */
  13966. if (!emptiable)
  13967. return (0);
  13968. }
  13969. part = (xmlSchemaParticlePtr) part->next;
  13970. }
  13971. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
  13972. return (0);
  13973. else
  13974. return (1);
  13975. }
  13976. /**
  13977. * xmlSchemaIsParticleEmptiable:
  13978. * @particle: the particle
  13979. *
  13980. * Schema Component Constraint: Particle Emptiable
  13981. * Checks whether the given particle is emptiable.
  13982. *
  13983. * Returns 1 if emptiable, 0 otherwise.
  13984. */
  13985. static int
  13986. xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
  13987. {
  13988. /*
  13989. * SPEC (1) "Its {min occurs} is 0."
  13990. */
  13991. if ((particle == NULL) || (particle->minOccurs == 0) ||
  13992. (particle->children == NULL))
  13993. return (1);
  13994. /*
  13995. * SPEC (2) "Its {term} is a group and the minimum part of the
  13996. * effective total range of that group, [...] is 0."
  13997. */
  13998. if (WXS_IS_MODEL_GROUP(particle->children))
  13999. return (xmlSchemaGetParticleEmptiable(particle));
  14000. return (0);
  14001. }
  14002. /**
  14003. * xmlSchemaCheckCOSSTDerivedOK:
  14004. * @actxt: a context
  14005. * @type: the derived simple type definition
  14006. * @baseType: the base type definition
  14007. * @subset: the subset of ('restriction', etc.)
  14008. *
  14009. * Schema Component Constraint:
  14010. * Type Derivation OK (Simple) (cos-st-derived-OK)
  14011. *
  14012. * Checks whether @type can be validly
  14013. * derived from @baseType.
  14014. *
  14015. * Returns 0 on success, an positive error code otherwise.
  14016. */
  14017. static int
  14018. xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  14019. xmlSchemaTypePtr type,
  14020. xmlSchemaTypePtr baseType,
  14021. int subset)
  14022. {
  14023. /*
  14024. * 1 They are the same type definition.
  14025. * TODO: The identity check might have to be more complex than this.
  14026. */
  14027. if (type == baseType)
  14028. return (0);
  14029. /*
  14030. * 2.1 restriction is not in the subset, or in the {final}
  14031. * of its own {base type definition};
  14032. *
  14033. * NOTE that this will be used also via "xsi:type".
  14034. *
  14035. * TODO: Revise this, it looks strange. How can the "type"
  14036. * not be fixed or *in* fixing?
  14037. */
  14038. if (WXS_IS_TYPE_NOT_FIXED(type))
  14039. if (xmlSchemaTypeFixup(type, actxt) == -1)
  14040. return(-1);
  14041. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  14042. if (xmlSchemaTypeFixup(baseType, actxt) == -1)
  14043. return(-1);
  14044. if ((subset & SUBSET_RESTRICTION) ||
  14045. (xmlSchemaTypeFinalContains(type->baseType,
  14046. XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
  14047. return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
  14048. }
  14049. /* 2.2 */
  14050. if (type->baseType == baseType) {
  14051. /*
  14052. * 2.2.1 D's `base type definition` is B.
  14053. */
  14054. return (0);
  14055. }
  14056. /*
  14057. * 2.2.2 D's `base type definition` is not the `ur-type definition`
  14058. * and is validly derived from B given the subset, as defined by this
  14059. * constraint.
  14060. */
  14061. if ((! WXS_IS_ANYTYPE(type->baseType)) &&
  14062. (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
  14063. baseType, subset) == 0)) {
  14064. return (0);
  14065. }
  14066. /*
  14067. * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
  14068. * definition`.
  14069. */
  14070. if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
  14071. (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
  14072. return (0);
  14073. }
  14074. /*
  14075. * 2.2.4 B's {variety} is union and D is validly derived from a type
  14076. * definition in B's {member type definitions} given the subset, as
  14077. * defined by this constraint.
  14078. *
  14079. * NOTE: This seems not to involve built-in types, since there is no
  14080. * built-in Union Simple Type.
  14081. */
  14082. if (WXS_IS_UNION(baseType)) {
  14083. xmlSchemaTypeLinkPtr cur;
  14084. cur = baseType->memberTypes;
  14085. while (cur != NULL) {
  14086. if (WXS_IS_TYPE_NOT_FIXED(cur->type))
  14087. if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
  14088. return(-1);
  14089. if (xmlSchemaCheckCOSSTDerivedOK(actxt,
  14090. type, cur->type, subset) == 0)
  14091. {
  14092. /*
  14093. * It just has to be validly derived from at least one
  14094. * member-type.
  14095. */
  14096. return (0);
  14097. }
  14098. cur = cur->next;
  14099. }
  14100. }
  14101. return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
  14102. }
  14103. /**
  14104. * xmlSchemaCheckTypeDefCircularInternal:
  14105. * @pctxt: the schema parser context
  14106. * @ctxtType: the type definition
  14107. * @ancestor: an ancestor of @ctxtType
  14108. *
  14109. * Checks st-props-correct (2) + ct-props-correct (3).
  14110. * Circular type definitions are not allowed.
  14111. *
  14112. * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
  14113. * circular, 0 otherwise.
  14114. */
  14115. static int
  14116. xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
  14117. xmlSchemaTypePtr ctxtType,
  14118. xmlSchemaTypePtr ancestor)
  14119. {
  14120. int ret;
  14121. if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
  14122. return (0);
  14123. if (ctxtType == ancestor) {
  14124. xmlSchemaPCustomErr(pctxt,
  14125. XML_SCHEMAP_ST_PROPS_CORRECT_2,
  14126. WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
  14127. "The definition is circular", NULL);
  14128. return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
  14129. }
  14130. if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
  14131. /*
  14132. * Avoid infinite recursion on circular types not yet checked.
  14133. */
  14134. return (0);
  14135. }
  14136. ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
  14137. ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
  14138. ancestor->baseType);
  14139. ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
  14140. return (ret);
  14141. }
  14142. /**
  14143. * xmlSchemaCheckTypeDefCircular:
  14144. * @item: the complex/simple type definition
  14145. * @ctxt: the parser context
  14146. * @name: the name
  14147. *
  14148. * Checks for circular type definitions.
  14149. */
  14150. static void
  14151. xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
  14152. xmlSchemaParserCtxtPtr ctxt)
  14153. {
  14154. if ((item == NULL) ||
  14155. (item->type == XML_SCHEMA_TYPE_BASIC) ||
  14156. (item->baseType == NULL))
  14157. return;
  14158. xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
  14159. item->baseType);
  14160. }
  14161. /*
  14162. * Simple Type Definition Representation OK (src-simple-type) 4
  14163. *
  14164. * "4 Circular union type definition is disallowed. That is, if the
  14165. * <union> alternative is chosen, there must not be any entries in the
  14166. * memberTypes [attribute] at any depth which resolve to the component
  14167. * corresponding to the <simpleType>."
  14168. *
  14169. * Note that this should work on the *representation* of a component,
  14170. * thus assumes any union types in the member types not being yet
  14171. * substituted. At this stage we need the variety of the types
  14172. * to be already computed.
  14173. */
  14174. static int
  14175. xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
  14176. xmlSchemaTypePtr ctxType,
  14177. xmlSchemaTypeLinkPtr members)
  14178. {
  14179. xmlSchemaTypeLinkPtr member;
  14180. xmlSchemaTypePtr memberType;
  14181. member = members;
  14182. while (member != NULL) {
  14183. memberType = member->type;
  14184. while ((memberType != NULL) &&
  14185. (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
  14186. if (memberType == ctxType) {
  14187. xmlSchemaPCustomErr(pctxt,
  14188. XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
  14189. WXS_BASIC_CAST ctxType, NULL,
  14190. "The union type definition is circular", NULL);
  14191. return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
  14192. }
  14193. if ((WXS_IS_UNION(memberType)) &&
  14194. ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
  14195. {
  14196. int res;
  14197. memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
  14198. res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
  14199. ctxType,
  14200. xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
  14201. memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
  14202. if (res != 0)
  14203. return(res);
  14204. }
  14205. memberType = memberType->baseType;
  14206. }
  14207. member = member->next;
  14208. }
  14209. return(0);
  14210. }
  14211. static int
  14212. xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
  14213. xmlSchemaTypePtr type)
  14214. {
  14215. if (! WXS_IS_UNION(type))
  14216. return(0);
  14217. return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
  14218. type->memberTypes));
  14219. }
  14220. /**
  14221. * xmlSchemaResolveTypeReferences:
  14222. * @item: the complex/simple type definition
  14223. * @ctxt: the parser context
  14224. * @name: the name
  14225. *
  14226. * Resolves type definition references
  14227. */
  14228. static void
  14229. xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
  14230. xmlSchemaParserCtxtPtr ctxt)
  14231. {
  14232. if (typeDef == NULL)
  14233. return;
  14234. /*
  14235. * Resolve the base type.
  14236. */
  14237. if (typeDef->baseType == NULL) {
  14238. typeDef->baseType = xmlSchemaGetType(ctxt->schema,
  14239. typeDef->base, typeDef->baseNs);
  14240. if (typeDef->baseType == NULL) {
  14241. xmlSchemaPResCompAttrErr(ctxt,
  14242. XML_SCHEMAP_SRC_RESOLVE,
  14243. WXS_BASIC_CAST typeDef, typeDef->node,
  14244. "base", typeDef->base, typeDef->baseNs,
  14245. XML_SCHEMA_TYPE_SIMPLE, NULL);
  14246. return;
  14247. }
  14248. }
  14249. if (WXS_IS_SIMPLE(typeDef)) {
  14250. if (WXS_IS_UNION(typeDef)) {
  14251. /*
  14252. * Resolve the memberTypes.
  14253. */
  14254. xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
  14255. return;
  14256. } else if (WXS_IS_LIST(typeDef)) {
  14257. /*
  14258. * Resolve the itemType.
  14259. */
  14260. if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
  14261. typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
  14262. typeDef->base, typeDef->baseNs);
  14263. if ((typeDef->subtypes == NULL) ||
  14264. (! WXS_IS_SIMPLE(typeDef->subtypes)))
  14265. {
  14266. typeDef->subtypes = NULL;
  14267. xmlSchemaPResCompAttrErr(ctxt,
  14268. XML_SCHEMAP_SRC_RESOLVE,
  14269. WXS_BASIC_CAST typeDef, typeDef->node,
  14270. "itemType", typeDef->base, typeDef->baseNs,
  14271. XML_SCHEMA_TYPE_SIMPLE, NULL);
  14272. }
  14273. }
  14274. return;
  14275. }
  14276. }
  14277. /*
  14278. * The ball of letters below means, that if we have a particle
  14279. * which has a QName-helper component as its {term}, we want
  14280. * to resolve it...
  14281. */
  14282. else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
  14283. ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
  14284. XML_SCHEMA_TYPE_PARTICLE) &&
  14285. (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
  14286. ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
  14287. XML_SCHEMA_EXTRA_QNAMEREF))
  14288. {
  14289. xmlSchemaQNameRefPtr ref =
  14290. WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
  14291. xmlSchemaModelGroupDefPtr groupDef;
  14292. /*
  14293. * URGENT TODO: Test this.
  14294. */
  14295. WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
  14296. /*
  14297. * Resolve the MG definition reference.
  14298. */
  14299. groupDef =
  14300. WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
  14301. ref->itemType, ref->name, ref->targetNamespace);
  14302. if (groupDef == NULL) {
  14303. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  14304. NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
  14305. "ref", ref->name, ref->targetNamespace, ref->itemType,
  14306. NULL);
  14307. /* Remove the particle. */
  14308. WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
  14309. } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
  14310. /* Remove the particle. */
  14311. WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
  14312. else {
  14313. /*
  14314. * Assign the MG definition's {model group} to the
  14315. * particle's {term}.
  14316. */
  14317. WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
  14318. if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
  14319. /*
  14320. * SPEC cos-all-limited (1.2)
  14321. * "1.2 the {term} property of a particle with
  14322. * {max occurs}=1 which is part of a pair which constitutes
  14323. * the {content type} of a complex type definition."
  14324. */
  14325. if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
  14326. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  14327. /* TODO: error code */
  14328. XML_SCHEMAP_COS_ALL_LIMITED,
  14329. WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
  14330. "The particle's {max occurs} must be 1, since the "
  14331. "reference resolves to an 'all' model group",
  14332. NULL, NULL);
  14333. }
  14334. }
  14335. }
  14336. }
  14337. }
  14338. /**
  14339. * xmlSchemaCheckSTPropsCorrect:
  14340. * @ctxt: the schema parser context
  14341. * @type: the simple type definition
  14342. *
  14343. * Checks st-props-correct.
  14344. *
  14345. * Returns 0 if the properties are correct,
  14346. * if not, a positive error code and -1 on internal
  14347. * errors.
  14348. */
  14349. static int
  14350. xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
  14351. xmlSchemaTypePtr type)
  14352. {
  14353. xmlSchemaTypePtr baseType = type->baseType;
  14354. xmlChar *str = NULL;
  14355. /* STATE: error funcs converted. */
  14356. /*
  14357. * Schema Component Constraint: Simple Type Definition Properties Correct
  14358. *
  14359. * NOTE: This is somehow redundant, since we actually built a simple type
  14360. * to have all the needed information; this acts as an self test.
  14361. */
  14362. /* Base type: If the datatype has been `derived` by `restriction`
  14363. * then the Simple Type Definition component from which it is `derived`,
  14364. * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
  14365. */
  14366. if (baseType == NULL) {
  14367. /*
  14368. * TODO: Think about: "modulo the impact of Missing
  14369. * Sub-components ($5.3)."
  14370. */
  14371. xmlSchemaPCustomErr(ctxt,
  14372. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14373. WXS_BASIC_CAST type, NULL,
  14374. "No base type existent", NULL);
  14375. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14376. }
  14377. if (! WXS_IS_SIMPLE(baseType)) {
  14378. xmlSchemaPCustomErr(ctxt,
  14379. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14380. WXS_BASIC_CAST type, NULL,
  14381. "The base type '%s' is not a simple type",
  14382. xmlSchemaGetComponentQName(&str, baseType));
  14383. FREE_AND_NULL(str)
  14384. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14385. }
  14386. if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
  14387. (WXS_IS_RESTRICTION(type) == 0) &&
  14388. ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
  14389. (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
  14390. xmlSchemaPCustomErr(ctxt,
  14391. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14392. WXS_BASIC_CAST type, NULL,
  14393. "A type, derived by list or union, must have "
  14394. "the simple ur-type definition as base type, not '%s'",
  14395. xmlSchemaGetComponentQName(&str, baseType));
  14396. FREE_AND_NULL(str)
  14397. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14398. }
  14399. /*
  14400. * Variety: One of {atomic, list, union}.
  14401. */
  14402. if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
  14403. (! WXS_IS_LIST(type))) {
  14404. xmlSchemaPCustomErr(ctxt,
  14405. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14406. WXS_BASIC_CAST type, NULL,
  14407. "The variety is absent", NULL);
  14408. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14409. }
  14410. /* TODO: Finish this. Hmm, is this finished? */
  14411. /*
  14412. * 3 The {final} of the {base type definition} must not contain restriction.
  14413. */
  14414. if (xmlSchemaTypeFinalContains(baseType,
  14415. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14416. xmlSchemaPCustomErr(ctxt,
  14417. XML_SCHEMAP_ST_PROPS_CORRECT_3,
  14418. WXS_BASIC_CAST type, NULL,
  14419. "The 'final' of its base type '%s' must not contain "
  14420. "'restriction'",
  14421. xmlSchemaGetComponentQName(&str, baseType));
  14422. FREE_AND_NULL(str)
  14423. return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
  14424. }
  14425. /*
  14426. * 2 All simple type definitions must be derived ultimately from the `simple
  14427. * ur-type definition` (so circular definitions are disallowed). That is, it
  14428. * must be possible to reach a built-in primitive datatype or the `simple
  14429. * ur-type definition` by repeatedly following the {base type definition}.
  14430. *
  14431. * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
  14432. */
  14433. return (0);
  14434. }
  14435. /**
  14436. * xmlSchemaCheckCOSSTRestricts:
  14437. * @ctxt: the schema parser context
  14438. * @type: the simple type definition
  14439. *
  14440. * Schema Component Constraint:
  14441. * Derivation Valid (Restriction, Simple) (cos-st-restricts)
  14442. * Checks if the given @type (simpleType) is derived validly by restriction.
  14443. * STATUS:
  14444. *
  14445. * Returns -1 on internal errors, 0 if the type is validly derived,
  14446. * a positive error code otherwise.
  14447. */
  14448. static int
  14449. xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
  14450. xmlSchemaTypePtr type)
  14451. {
  14452. xmlChar *str = NULL;
  14453. if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
  14454. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14455. "given type is not a user-derived simpleType");
  14456. return (-1);
  14457. }
  14458. if (WXS_IS_ATOMIC(type)) {
  14459. xmlSchemaTypePtr primitive;
  14460. /*
  14461. * 1.1 The {base type definition} must be an atomic simple
  14462. * type definition or a built-in primitive datatype.
  14463. */
  14464. if (! WXS_IS_ATOMIC(type->baseType)) {
  14465. xmlSchemaPCustomErr(pctxt,
  14466. XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
  14467. WXS_BASIC_CAST type, NULL,
  14468. "The base type '%s' is not an atomic simple type",
  14469. xmlSchemaGetComponentQName(&str, type->baseType));
  14470. FREE_AND_NULL(str)
  14471. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
  14472. }
  14473. /* 1.2 The {final} of the {base type definition} must not contain
  14474. * restriction.
  14475. */
  14476. /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
  14477. if (xmlSchemaTypeFinalContains(type->baseType,
  14478. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14479. xmlSchemaPCustomErr(pctxt,
  14480. XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
  14481. WXS_BASIC_CAST type, NULL,
  14482. "The final of its base type '%s' must not contain 'restriction'",
  14483. xmlSchemaGetComponentQName(&str, type->baseType));
  14484. FREE_AND_NULL(str)
  14485. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
  14486. }
  14487. /*
  14488. * 1.3.1 DF must be an allowed constraining facet for the {primitive
  14489. * type definition}, as specified in the appropriate subsection of 3.2
  14490. * Primitive datatypes.
  14491. */
  14492. if (type->facets != NULL) {
  14493. xmlSchemaFacetPtr facet;
  14494. int ok = 1;
  14495. primitive = xmlSchemaGetPrimitiveType(type);
  14496. if (primitive == NULL) {
  14497. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14498. "failed to get primitive type");
  14499. return (-1);
  14500. }
  14501. facet = type->facets;
  14502. do {
  14503. if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
  14504. ok = 0;
  14505. xmlSchemaPIllegalFacetAtomicErr(pctxt,
  14506. XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
  14507. type, primitive, facet);
  14508. }
  14509. facet = facet->next;
  14510. } while (facet != NULL);
  14511. if (ok == 0)
  14512. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
  14513. }
  14514. /*
  14515. * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
  14516. * of the {base type definition} (call this BF),then the DF's {value}
  14517. * must be a valid restriction of BF's {value} as defined in
  14518. * [XML Schemas: Datatypes]."
  14519. *
  14520. * NOTE (1.3.2) Facet derivation constraints are currently handled in
  14521. * xmlSchemaDeriveAndValidateFacets()
  14522. */
  14523. } else if (WXS_IS_LIST(type)) {
  14524. xmlSchemaTypePtr itemType = NULL;
  14525. itemType = type->subtypes;
  14526. if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
  14527. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14528. "failed to evaluate the item type");
  14529. return (-1);
  14530. }
  14531. if (WXS_IS_TYPE_NOT_FIXED(itemType))
  14532. xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
  14533. /*
  14534. * 2.1 The {item type definition} must have a {variety} of atomic or
  14535. * union (in which case all the {member type definitions}
  14536. * must be atomic).
  14537. */
  14538. if ((! WXS_IS_ATOMIC(itemType)) &&
  14539. (! WXS_IS_UNION(itemType))) {
  14540. xmlSchemaPCustomErr(pctxt,
  14541. XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
  14542. WXS_BASIC_CAST type, NULL,
  14543. "The item type '%s' does not have a variety of atomic or union",
  14544. xmlSchemaGetComponentQName(&str, itemType));
  14545. FREE_AND_NULL(str)
  14546. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
  14547. } else if (WXS_IS_UNION(itemType)) {
  14548. xmlSchemaTypeLinkPtr member;
  14549. member = itemType->memberTypes;
  14550. while (member != NULL) {
  14551. if (! WXS_IS_ATOMIC(member->type)) {
  14552. xmlSchemaPCustomErr(pctxt,
  14553. XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
  14554. WXS_BASIC_CAST type, NULL,
  14555. "The item type is a union type, but the "
  14556. "member type '%s' of this item type is not atomic",
  14557. xmlSchemaGetComponentQName(&str, member->type));
  14558. FREE_AND_NULL(str)
  14559. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
  14560. }
  14561. member = member->next;
  14562. }
  14563. }
  14564. if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
  14565. xmlSchemaFacetPtr facet;
  14566. /*
  14567. * This is the case if we have: <simpleType><list ..
  14568. */
  14569. /*
  14570. * 2.3.1
  14571. * 2.3.1.1 The {final} of the {item type definition} must not
  14572. * contain list.
  14573. */
  14574. if (xmlSchemaTypeFinalContains(itemType,
  14575. XML_SCHEMAS_TYPE_FINAL_LIST)) {
  14576. xmlSchemaPCustomErr(pctxt,
  14577. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
  14578. WXS_BASIC_CAST type, NULL,
  14579. "The final of its item type '%s' must not contain 'list'",
  14580. xmlSchemaGetComponentQName(&str, itemType));
  14581. FREE_AND_NULL(str)
  14582. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
  14583. }
  14584. /*
  14585. * 2.3.1.2 The {facets} must only contain the whiteSpace
  14586. * facet component.
  14587. * OPTIMIZE TODO: the S4S already disallows any facet
  14588. * to be specified.
  14589. */
  14590. if (type->facets != NULL) {
  14591. facet = type->facets;
  14592. do {
  14593. if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
  14594. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14595. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
  14596. type, facet);
  14597. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
  14598. }
  14599. facet = facet->next;
  14600. } while (facet != NULL);
  14601. }
  14602. /*
  14603. * MAYBE TODO: (Hmm, not really) Datatypes states:
  14604. * A `list` datatype can be `derived` from an `atomic` datatype
  14605. * whose `lexical space` allows space (such as string or anyURI)or
  14606. * a `union` datatype any of whose {member type definitions}'s
  14607. * `lexical space` allows space.
  14608. */
  14609. } else {
  14610. /*
  14611. * This is the case if we have: <simpleType><restriction ...
  14612. * I.e. the variety of "list" is inherited.
  14613. */
  14614. /*
  14615. * 2.3.2
  14616. * 2.3.2.1 The {base type definition} must have a {variety} of list.
  14617. */
  14618. if (! WXS_IS_LIST(type->baseType)) {
  14619. xmlSchemaPCustomErr(pctxt,
  14620. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
  14621. WXS_BASIC_CAST type, NULL,
  14622. "The base type '%s' must be a list type",
  14623. xmlSchemaGetComponentQName(&str, type->baseType));
  14624. FREE_AND_NULL(str)
  14625. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
  14626. }
  14627. /*
  14628. * 2.3.2.2 The {final} of the {base type definition} must not
  14629. * contain restriction.
  14630. */
  14631. if (xmlSchemaTypeFinalContains(type->baseType,
  14632. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14633. xmlSchemaPCustomErr(pctxt,
  14634. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
  14635. WXS_BASIC_CAST type, NULL,
  14636. "The 'final' of the base type '%s' must not contain 'restriction'",
  14637. xmlSchemaGetComponentQName(&str, type->baseType));
  14638. FREE_AND_NULL(str)
  14639. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
  14640. }
  14641. /*
  14642. * 2.3.2.3 The {item type definition} must be validly derived
  14643. * from the {base type definition}'s {item type definition} given
  14644. * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
  14645. */
  14646. {
  14647. xmlSchemaTypePtr baseItemType;
  14648. baseItemType = type->baseType->subtypes;
  14649. if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
  14650. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14651. "failed to eval the item type of a base type");
  14652. return (-1);
  14653. }
  14654. if ((itemType != baseItemType) &&
  14655. (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
  14656. baseItemType, 0) != 0)) {
  14657. xmlChar *strBIT = NULL, *strBT = NULL;
  14658. xmlSchemaPCustomErrExt(pctxt,
  14659. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
  14660. WXS_BASIC_CAST type, NULL,
  14661. "The item type '%s' is not validly derived from "
  14662. "the item type '%s' of the base type '%s'",
  14663. xmlSchemaGetComponentQName(&str, itemType),
  14664. xmlSchemaGetComponentQName(&strBIT, baseItemType),
  14665. xmlSchemaGetComponentQName(&strBT, type->baseType));
  14666. FREE_AND_NULL(str)
  14667. FREE_AND_NULL(strBIT)
  14668. FREE_AND_NULL(strBT)
  14669. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
  14670. }
  14671. }
  14672. if (type->facets != NULL) {
  14673. xmlSchemaFacetPtr facet;
  14674. int ok = 1;
  14675. /*
  14676. * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
  14677. * and enumeration facet components are allowed among the {facets}.
  14678. */
  14679. facet = type->facets;
  14680. do {
  14681. switch (facet->type) {
  14682. case XML_SCHEMA_FACET_LENGTH:
  14683. case XML_SCHEMA_FACET_MINLENGTH:
  14684. case XML_SCHEMA_FACET_MAXLENGTH:
  14685. case XML_SCHEMA_FACET_WHITESPACE:
  14686. /*
  14687. * TODO: 2.5.1.2 List datatypes
  14688. * The value of `whiteSpace` is fixed to the value collapse.
  14689. */
  14690. case XML_SCHEMA_FACET_PATTERN:
  14691. case XML_SCHEMA_FACET_ENUMERATION:
  14692. break;
  14693. default: {
  14694. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14695. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
  14696. type, facet);
  14697. /*
  14698. * We could return, but it's nicer to report all
  14699. * invalid facets.
  14700. */
  14701. ok = 0;
  14702. }
  14703. }
  14704. facet = facet->next;
  14705. } while (facet != NULL);
  14706. if (ok == 0)
  14707. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
  14708. /*
  14709. * SPEC (2.3.2.5) (same as 1.3.2)
  14710. *
  14711. * NOTE (2.3.2.5) This is currently done in
  14712. * xmlSchemaDeriveAndValidateFacets()
  14713. */
  14714. }
  14715. }
  14716. } else if (WXS_IS_UNION(type)) {
  14717. /*
  14718. * 3.1 The {member type definitions} must all have {variety} of
  14719. * atomic or list.
  14720. */
  14721. xmlSchemaTypeLinkPtr member;
  14722. member = type->memberTypes;
  14723. while (member != NULL) {
  14724. if (WXS_IS_TYPE_NOT_FIXED(member->type))
  14725. xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
  14726. if ((! WXS_IS_ATOMIC(member->type)) &&
  14727. (! WXS_IS_LIST(member->type))) {
  14728. xmlSchemaPCustomErr(pctxt,
  14729. XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
  14730. WXS_BASIC_CAST type, NULL,
  14731. "The member type '%s' is neither an atomic, nor a list type",
  14732. xmlSchemaGetComponentQName(&str, member->type));
  14733. FREE_AND_NULL(str)
  14734. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
  14735. }
  14736. member = member->next;
  14737. }
  14738. /*
  14739. * 3.3.1 If the {base type definition} is the `simple ur-type
  14740. * definition`
  14741. */
  14742. if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
  14743. /*
  14744. * 3.3.1.1 All of the {member type definitions} must have a
  14745. * {final} which does not contain union.
  14746. */
  14747. member = type->memberTypes;
  14748. while (member != NULL) {
  14749. if (xmlSchemaTypeFinalContains(member->type,
  14750. XML_SCHEMAS_TYPE_FINAL_UNION)) {
  14751. xmlSchemaPCustomErr(pctxt,
  14752. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
  14753. WXS_BASIC_CAST type, NULL,
  14754. "The 'final' of member type '%s' contains 'union'",
  14755. xmlSchemaGetComponentQName(&str, member->type));
  14756. FREE_AND_NULL(str)
  14757. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
  14758. }
  14759. member = member->next;
  14760. }
  14761. /*
  14762. * 3.3.1.2 The {facets} must be empty.
  14763. */
  14764. if (type->facetSet != NULL) {
  14765. xmlSchemaPCustomErr(pctxt,
  14766. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
  14767. WXS_BASIC_CAST type, NULL,
  14768. "No facets allowed", NULL);
  14769. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
  14770. }
  14771. } else {
  14772. /*
  14773. * 3.3.2.1 The {base type definition} must have a {variety} of union.
  14774. * I.e. the variety of "list" is inherited.
  14775. */
  14776. if (! WXS_IS_UNION(type->baseType)) {
  14777. xmlSchemaPCustomErr(pctxt,
  14778. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
  14779. WXS_BASIC_CAST type, NULL,
  14780. "The base type '%s' is not a union type",
  14781. xmlSchemaGetComponentQName(&str, type->baseType));
  14782. FREE_AND_NULL(str)
  14783. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
  14784. }
  14785. /*
  14786. * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
  14787. */
  14788. if (xmlSchemaTypeFinalContains(type->baseType,
  14789. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14790. xmlSchemaPCustomErr(pctxt,
  14791. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
  14792. WXS_BASIC_CAST type, NULL,
  14793. "The 'final' of its base type '%s' must not contain 'restriction'",
  14794. xmlSchemaGetComponentQName(&str, type->baseType));
  14795. FREE_AND_NULL(str)
  14796. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
  14797. }
  14798. /*
  14799. * 3.3.2.3 The {member type definitions}, in order, must be validly
  14800. * derived from the corresponding type definitions in the {base
  14801. * type definition}'s {member type definitions} given the empty set,
  14802. * as defined in Type Derivation OK (Simple) ($3.14.6).
  14803. */
  14804. {
  14805. xmlSchemaTypeLinkPtr baseMember;
  14806. /*
  14807. * OPTIMIZE: if the type is restricting, it has no local defined
  14808. * member types and inherits the member types of the base type;
  14809. * thus a check for equality can be skipped.
  14810. */
  14811. /*
  14812. * Even worse: I cannot see a scenario where a restricting
  14813. * union simple type can have other member types as the member
  14814. * types of it's base type. This check seems not necessary with
  14815. * respect to the derivation process in libxml2.
  14816. * But necessary if constructing types with an API.
  14817. */
  14818. if (type->memberTypes != NULL) {
  14819. member = type->memberTypes;
  14820. baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
  14821. if ((member == NULL) && (baseMember != NULL)) {
  14822. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14823. "different number of member types in base");
  14824. }
  14825. while (member != NULL) {
  14826. if (baseMember == NULL) {
  14827. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14828. "different number of member types in base");
  14829. } else if ((member->type != baseMember->type) &&
  14830. (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
  14831. member->type, baseMember->type, 0) != 0)) {
  14832. xmlChar *strBMT = NULL, *strBT = NULL;
  14833. xmlSchemaPCustomErrExt(pctxt,
  14834. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
  14835. WXS_BASIC_CAST type, NULL,
  14836. "The member type %s is not validly "
  14837. "derived from its corresponding member "
  14838. "type %s of the base type %s",
  14839. xmlSchemaGetComponentQName(&str, member->type),
  14840. xmlSchemaGetComponentQName(&strBMT, baseMember->type),
  14841. xmlSchemaGetComponentQName(&strBT, type->baseType));
  14842. FREE_AND_NULL(str)
  14843. FREE_AND_NULL(strBMT)
  14844. FREE_AND_NULL(strBT)
  14845. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
  14846. }
  14847. member = member->next;
  14848. if (baseMember != NULL)
  14849. baseMember = baseMember->next;
  14850. }
  14851. }
  14852. }
  14853. /*
  14854. * 3.3.2.4 Only pattern and enumeration facet components are
  14855. * allowed among the {facets}.
  14856. */
  14857. if (type->facets != NULL) {
  14858. xmlSchemaFacetPtr facet;
  14859. int ok = 1;
  14860. facet = type->facets;
  14861. do {
  14862. if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
  14863. (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
  14864. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14865. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
  14866. type, facet);
  14867. ok = 0;
  14868. }
  14869. facet = facet->next;
  14870. } while (facet != NULL);
  14871. if (ok == 0)
  14872. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
  14873. }
  14874. /*
  14875. * SPEC (3.3.2.5) (same as 1.3.2)
  14876. *
  14877. * NOTE (3.3.2.5) This is currently done in
  14878. * xmlSchemaDeriveAndValidateFacets()
  14879. */
  14880. }
  14881. }
  14882. return (0);
  14883. }
  14884. /**
  14885. * xmlSchemaCheckSRCSimpleType:
  14886. * @ctxt: the schema parser context
  14887. * @type: the simple type definition
  14888. *
  14889. * Checks crc-simple-type constraints.
  14890. *
  14891. * Returns 0 if the constraints are satisfied,
  14892. * if not a positive error code and -1 on internal
  14893. * errors.
  14894. */
  14895. #if 0
  14896. static int
  14897. xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
  14898. xmlSchemaTypePtr type)
  14899. {
  14900. /*
  14901. * src-simple-type.1 The corresponding simple type definition, if any,
  14902. * must satisfy the conditions set out in Constraints on Simple Type
  14903. * Definition Schema Components ($3.14.6).
  14904. */
  14905. if (WXS_IS_RESTRICTION(type)) {
  14906. /*
  14907. * src-simple-type.2 "If the <restriction> alternative is chosen,
  14908. * either it must have a base [attribute] or a <simpleType> among its
  14909. * [children], but not both."
  14910. * NOTE: This is checked in the parse function of <restriction>.
  14911. */
  14912. /*
  14913. *
  14914. */
  14915. } else if (WXS_IS_LIST(type)) {
  14916. /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
  14917. * an itemType [attribute] or a <simpleType> among its [children],
  14918. * but not both."
  14919. *
  14920. * NOTE: This is checked in the parse function of <list>.
  14921. */
  14922. } else if (WXS_IS_UNION(type)) {
  14923. /*
  14924. * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
  14925. */
  14926. }
  14927. return (0);
  14928. }
  14929. #endif
  14930. static int
  14931. xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
  14932. {
  14933. if (ctxt->vctxt == NULL) {
  14934. ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
  14935. if (ctxt->vctxt == NULL) {
  14936. xmlSchemaPErr(ctxt, NULL,
  14937. XML_SCHEMAP_INTERNAL,
  14938. "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
  14939. "failed to create a temp. validation context.\n",
  14940. NULL, NULL);
  14941. return (-1);
  14942. }
  14943. /* TODO: Pass user data. */
  14944. xmlSchemaSetValidErrors(ctxt->vctxt,
  14945. ctxt->error, ctxt->warning, ctxt->errCtxt);
  14946. xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
  14947. ctxt->serror, ctxt->errCtxt);
  14948. }
  14949. return (0);
  14950. }
  14951. static int
  14952. xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
  14953. xmlNodePtr node,
  14954. xmlSchemaTypePtr type,
  14955. const xmlChar *value,
  14956. xmlSchemaValPtr *retVal,
  14957. int fireErrors,
  14958. int normalize,
  14959. int isNormalized);
  14960. /**
  14961. * xmlSchemaParseCheckCOSValidDefault:
  14962. * @pctxt: the schema parser context
  14963. * @type: the simple type definition
  14964. * @value: the default value
  14965. * @node: an optional node (the holder of the value)
  14966. *
  14967. * Schema Component Constraint: Element Default Valid (Immediate)
  14968. * (cos-valid-default)
  14969. * This will be used by the parser only. For the validator there's
  14970. * an other version.
  14971. *
  14972. * Returns 0 if the constraints are satisfied,
  14973. * if not, a positive error code and -1 on internal
  14974. * errors.
  14975. */
  14976. static int
  14977. xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
  14978. xmlNodePtr node,
  14979. xmlSchemaTypePtr type,
  14980. const xmlChar *value,
  14981. xmlSchemaValPtr *val)
  14982. {
  14983. int ret = 0;
  14984. /*
  14985. * cos-valid-default:
  14986. * Schema Component Constraint: Element Default Valid (Immediate)
  14987. * For a string to be a valid default with respect to a type
  14988. * definition the appropriate case among the following must be true:
  14989. */
  14990. if WXS_IS_COMPLEX(type) {
  14991. /*
  14992. * Complex type.
  14993. *
  14994. * SPEC (2.1) "its {content type} must be a simple type definition
  14995. * or mixed."
  14996. * SPEC (2.2.2) "If the {content type} is mixed, then the {content
  14997. * type}'s particle must be `emptiable` as defined by
  14998. * Particle Emptiable ($3.9.6)."
  14999. */
  15000. if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
  15001. ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
  15002. /* NOTE that this covers (2.2.2) as well. */
  15003. xmlSchemaPCustomErr(pctxt,
  15004. XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
  15005. WXS_BASIC_CAST type, type->node,
  15006. "For a string to be a valid default, the type definition "
  15007. "must be a simple type or a complex type with mixed content "
  15008. "and a particle emptiable", NULL);
  15009. return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
  15010. }
  15011. }
  15012. /*
  15013. * 1 If the type definition is a simple type definition, then the string
  15014. * must be `valid` with respect to that definition as defined by String
  15015. * Valid ($3.14.4).
  15016. *
  15017. * AND
  15018. *
  15019. * 2.2.1 If the {content type} is a simple type definition, then the
  15020. * string must be `valid` with respect to that simple type definition
  15021. * as defined by String Valid ($3.14.4).
  15022. */
  15023. if (WXS_IS_SIMPLE(type))
  15024. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
  15025. type, value, val, 1, 1, 0);
  15026. else if (WXS_HAS_SIMPLE_CONTENT(type))
  15027. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
  15028. type->contentTypeDef, value, val, 1, 1, 0);
  15029. else
  15030. return (ret);
  15031. if (ret < 0) {
  15032. PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
  15033. "calling xmlSchemaVCheckCVCSimpleType()");
  15034. }
  15035. return (ret);
  15036. }
  15037. /**
  15038. * xmlSchemaCheckCTPropsCorrect:
  15039. * @ctxt: the schema parser context
  15040. * @type: the complex type definition
  15041. *
  15042. *.(4.6) Constraints on Complex Type Definition Schema Components
  15043. * Schema Component Constraint:
  15044. * Complex Type Definition Properties Correct (ct-props-correct)
  15045. * STATUS: (seems) complete
  15046. *
  15047. * Returns 0 if the constraints are satisfied, a positive
  15048. * error code if not and -1 if an internal error occurred.
  15049. */
  15050. static int
  15051. xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  15052. xmlSchemaTypePtr type)
  15053. {
  15054. /*
  15055. * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
  15056. *
  15057. * SPEC (1) "The values of the properties of a complex type definition must
  15058. * be as described in the property tableau in The Complex Type Definition
  15059. * Schema Component ($3.4.1), modulo the impact of Missing
  15060. * Sub-components ($5.3)."
  15061. */
  15062. if ((type->baseType != NULL) &&
  15063. (WXS_IS_SIMPLE(type->baseType)) &&
  15064. (WXS_IS_EXTENSION(type) == 0)) {
  15065. /*
  15066. * SPEC (2) "If the {base type definition} is a simple type definition,
  15067. * the {derivation method} must be extension."
  15068. */
  15069. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15070. XML_SCHEMAP_SRC_CT_1,
  15071. NULL, WXS_BASIC_CAST type,
  15072. "If the base type is a simple type, the derivation method must be "
  15073. "'extension'", NULL, NULL);
  15074. return (XML_SCHEMAP_SRC_CT_1);
  15075. }
  15076. /*
  15077. * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
  15078. * definition`. That is, it must be possible to reach the `ur-type
  15079. * definition` by repeatedly following the {base type definition}."
  15080. *
  15081. * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
  15082. */
  15083. /*
  15084. * NOTE that (4) and (5) need the following:
  15085. * - attribute uses need to be already inherited (apply attr. prohibitions)
  15086. * - attribute group references need to be expanded already
  15087. * - simple types need to be typefixed already
  15088. */
  15089. if (type->attrUses &&
  15090. (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
  15091. {
  15092. xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
  15093. xmlSchemaAttributeUsePtr use, tmp;
  15094. int i, j, hasId = 0;
  15095. for (i = uses->nbItems -1; i >= 0; i--) {
  15096. use = uses->items[i];
  15097. /*
  15098. * SPEC ct-props-correct
  15099. * (4) "Two distinct attribute declarations in the
  15100. * {attribute uses} must not have identical {name}s and
  15101. * {target namespace}s."
  15102. */
  15103. if (i > 0) {
  15104. for (j = i -1; j >= 0; j--) {
  15105. tmp = uses->items[j];
  15106. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  15107. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  15108. (WXS_ATTRUSE_DECL_TNS(use) ==
  15109. WXS_ATTRUSE_DECL_TNS(tmp)))
  15110. {
  15111. xmlChar *str = NULL;
  15112. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15113. XML_SCHEMAP_AG_PROPS_CORRECT,
  15114. NULL, WXS_BASIC_CAST type,
  15115. "Duplicate %s",
  15116. xmlSchemaGetComponentDesignation(&str, use),
  15117. NULL);
  15118. FREE_AND_NULL(str);
  15119. /*
  15120. * Remove the duplicate.
  15121. */
  15122. if (xmlSchemaItemListRemove(uses, i) == -1)
  15123. goto exit_failure;
  15124. goto next_use;
  15125. }
  15126. }
  15127. }
  15128. /*
  15129. * SPEC ct-props-correct
  15130. * (5) "Two distinct attribute declarations in the
  15131. * {attribute uses} must not have {type definition}s which
  15132. * are or are derived from ID."
  15133. */
  15134. if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
  15135. if (xmlSchemaIsDerivedFromBuiltInType(
  15136. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  15137. {
  15138. if (hasId) {
  15139. xmlChar *str = NULL;
  15140. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15141. XML_SCHEMAP_AG_PROPS_CORRECT,
  15142. NULL, WXS_BASIC_CAST type,
  15143. "There must not exist more than one attribute "
  15144. "declaration of type 'xs:ID' "
  15145. "(or derived from 'xs:ID'). The %s violates this "
  15146. "constraint",
  15147. xmlSchemaGetComponentDesignation(&str, use),
  15148. NULL);
  15149. FREE_AND_NULL(str);
  15150. if (xmlSchemaItemListRemove(uses, i) == -1)
  15151. goto exit_failure;
  15152. }
  15153. hasId = 1;
  15154. }
  15155. }
  15156. next_use: {}
  15157. }
  15158. }
  15159. return (0);
  15160. exit_failure:
  15161. return(-1);
  15162. }
  15163. static int
  15164. xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
  15165. xmlSchemaTypePtr typeB)
  15166. {
  15167. /*
  15168. * TODO: This should implement component-identity
  15169. * in the future.
  15170. */
  15171. if ((typeA == NULL) || (typeB == NULL))
  15172. return (0);
  15173. return (typeA == typeB);
  15174. }
  15175. /**
  15176. * xmlSchemaCheckCOSCTDerivedOK:
  15177. * @ctxt: the schema parser context
  15178. * @type: the to-be derived complex type definition
  15179. * @baseType: the base complex type definition
  15180. * @set: the given set
  15181. *
  15182. * Schema Component Constraint:
  15183. * Type Derivation OK (Complex) (cos-ct-derived-ok)
  15184. *
  15185. * STATUS: completed
  15186. *
  15187. * Returns 0 if the constraints are satisfied, or 1
  15188. * if not.
  15189. */
  15190. static int
  15191. xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  15192. xmlSchemaTypePtr type,
  15193. xmlSchemaTypePtr baseType,
  15194. int set)
  15195. {
  15196. int equal = xmlSchemaAreEqualTypes(type, baseType);
  15197. /* TODO: Error codes. */
  15198. /*
  15199. * SPEC "For a complex type definition (call it D, for derived)
  15200. * to be validly derived from a type definition (call this
  15201. * B, for base) given a subset of {extension, restriction}
  15202. * all of the following must be true:"
  15203. */
  15204. if (! equal) {
  15205. /*
  15206. * SPEC (1) "If B and D are not the same type definition, then the
  15207. * {derivation method} of D must not be in the subset."
  15208. */
  15209. if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
  15210. ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
  15211. return (1);
  15212. } else {
  15213. /*
  15214. * SPEC (2.1) "B and D must be the same type definition."
  15215. */
  15216. return (0);
  15217. }
  15218. /*
  15219. * SPEC (2.2) "B must be D's {base type definition}."
  15220. */
  15221. if (type->baseType == baseType)
  15222. return (0);
  15223. /*
  15224. * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
  15225. * definition`."
  15226. */
  15227. if (WXS_IS_ANYTYPE(type->baseType))
  15228. return (1);
  15229. if (WXS_IS_COMPLEX(type->baseType)) {
  15230. /*
  15231. * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
  15232. * must be validly derived from B given the subset as defined by this
  15233. * constraint."
  15234. */
  15235. return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
  15236. baseType, set));
  15237. } else {
  15238. /*
  15239. * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
  15240. * must be validly derived from B given the subset as defined in Type
  15241. * Derivation OK (Simple) ($3.14.6).
  15242. */
  15243. return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
  15244. baseType, set));
  15245. }
  15246. }
  15247. /**
  15248. * xmlSchemaCheckCOSDerivedOK:
  15249. * @type: the derived simple type definition
  15250. * @baseType: the base type definition
  15251. *
  15252. * Calls:
  15253. * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
  15254. *
  15255. * Checks whether @type can be validly derived from @baseType.
  15256. *
  15257. * Returns 0 on success, an positive error code otherwise.
  15258. */
  15259. static int
  15260. xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  15261. xmlSchemaTypePtr type,
  15262. xmlSchemaTypePtr baseType,
  15263. int set)
  15264. {
  15265. if (WXS_IS_SIMPLE(type))
  15266. return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
  15267. else
  15268. return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
  15269. }
  15270. /**
  15271. * xmlSchemaCheckCOSCTExtends:
  15272. * @ctxt: the schema parser context
  15273. * @type: the complex type definition
  15274. *
  15275. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15276. * Schema Component Constraint:
  15277. * Derivation Valid (Extension) (cos-ct-extends)
  15278. *
  15279. * STATUS:
  15280. * missing:
  15281. * (1.5)
  15282. * (1.4.3.2.2.2) "Particle Valid (Extension)"
  15283. *
  15284. * Returns 0 if the constraints are satisfied, a positive
  15285. * error code if not and -1 if an internal error occurred.
  15286. */
  15287. static int
  15288. xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
  15289. xmlSchemaTypePtr type)
  15290. {
  15291. xmlSchemaTypePtr base = type->baseType;
  15292. /*
  15293. * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
  15294. * temporarily only.
  15295. */
  15296. /*
  15297. * SPEC (1) "If the {base type definition} is a complex type definition,
  15298. * then all of the following must be true:"
  15299. */
  15300. if (WXS_IS_COMPLEX(base)) {
  15301. /*
  15302. * SPEC (1.1) "The {final} of the {base type definition} must not
  15303. * contain extension."
  15304. */
  15305. if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
  15306. xmlSchemaPCustomErr(ctxt,
  15307. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15308. WXS_BASIC_CAST type, NULL,
  15309. "The 'final' of the base type definition "
  15310. "contains 'extension'", NULL);
  15311. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15312. }
  15313. /*
  15314. * ATTENTION: The constrains (1.2) and (1.3) are not applied,
  15315. * since they are automatically satisfied through the
  15316. * inheriting mechanism.
  15317. * Note that even if redefining components, the inheriting mechanism
  15318. * is used.
  15319. */
  15320. #if 0
  15321. /*
  15322. * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
  15323. * uses}
  15324. * of the complex type definition itself, that is, for every attribute
  15325. * use in the {attribute uses} of the {base type definition}, there
  15326. * must be an attribute use in the {attribute uses} of the complex
  15327. * type definition itself whose {attribute declaration} has the same
  15328. * {name}, {target namespace} and {type definition} as its attribute
  15329. * declaration"
  15330. */
  15331. if (base->attrUses != NULL) {
  15332. int i, j, found;
  15333. xmlSchemaAttributeUsePtr use, buse;
  15334. for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
  15335. buse = (WXS_LIST_CAST base->attrUses)->items[i];
  15336. found = 0;
  15337. if (type->attrUses != NULL) {
  15338. use = (WXS_LIST_CAST type->attrUses)->items[j];
  15339. for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
  15340. {
  15341. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  15342. WXS_ATTRUSE_DECL_NAME(buse)) &&
  15343. (WXS_ATTRUSE_DECL_TNS(use) ==
  15344. WXS_ATTRUSE_DECL_TNS(buse)) &&
  15345. (WXS_ATTRUSE_TYPEDEF(use) ==
  15346. WXS_ATTRUSE_TYPEDEF(buse))
  15347. {
  15348. found = 1;
  15349. break;
  15350. }
  15351. }
  15352. }
  15353. if (! found) {
  15354. xmlChar *str = NULL;
  15355. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15356. XML_SCHEMAP_COS_CT_EXTENDS_1_2,
  15357. NULL, WXS_BASIC_CAST type,
  15358. /*
  15359. * TODO: The report does not indicate that also the
  15360. * type needs to be the same.
  15361. */
  15362. "This type is missing a matching correspondent "
  15363. "for its {base type}'s %s in its {attribute uses}",
  15364. xmlSchemaGetComponentDesignation(&str,
  15365. buse->children),
  15366. NULL);
  15367. FREE_AND_NULL(str)
  15368. }
  15369. }
  15370. }
  15371. /*
  15372. * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
  15373. * definition must also have one, and the base type definition's
  15374. * {attribute wildcard}'s {namespace constraint} must be a subset
  15375. * of the complex type definition's {attribute wildcard}'s {namespace
  15376. * constraint}, as defined by Wildcard Subset ($3.10.6)."
  15377. */
  15378. /*
  15379. * MAYBE TODO: Enable if ever needed. But this will be needed only
  15380. * if created the type via a schema construction API.
  15381. */
  15382. if (base->attributeWildcard != NULL) {
  15383. if (type->attributeWildcard == NULL) {
  15384. xmlChar *str = NULL;
  15385. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15386. XML_SCHEMAP_COS_CT_EXTENDS_1_3,
  15387. NULL, type,
  15388. "The base %s has an attribute wildcard, "
  15389. "but this type is missing an attribute wildcard",
  15390. xmlSchemaGetComponentDesignation(&str, base));
  15391. FREE_AND_NULL(str)
  15392. } else if (xmlSchemaCheckCOSNSSubset(
  15393. base->attributeWildcard, type->attributeWildcard))
  15394. {
  15395. xmlChar *str = NULL;
  15396. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15397. XML_SCHEMAP_COS_CT_EXTENDS_1_3,
  15398. NULL, type,
  15399. "The attribute wildcard is not a valid "
  15400. "superset of the one in the base %s",
  15401. xmlSchemaGetComponentDesignation(&str, base));
  15402. FREE_AND_NULL(str)
  15403. }
  15404. }
  15405. #endif
  15406. /*
  15407. * SPEC (1.4) "One of the following must be true:"
  15408. */
  15409. if ((type->contentTypeDef != NULL) &&
  15410. (type->contentTypeDef == base->contentTypeDef)) {
  15411. /*
  15412. * SPEC (1.4.1) "The {content type} of the {base type definition}
  15413. * and the {content type} of the complex type definition itself
  15414. * must be the same simple type definition"
  15415. * PASS
  15416. */
  15417. } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
  15418. (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
  15419. /*
  15420. * SPEC (1.4.2) "The {content type} of both the {base type
  15421. * definition} and the complex type definition itself must
  15422. * be empty."
  15423. * PASS
  15424. */
  15425. } else {
  15426. /*
  15427. * SPEC (1.4.3) "All of the following must be true:"
  15428. */
  15429. if (type->subtypes == NULL) {
  15430. /*
  15431. * SPEC 1.4.3.1 The {content type} of the complex type
  15432. * definition itself must specify a particle.
  15433. */
  15434. xmlSchemaPCustomErr(ctxt,
  15435. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15436. WXS_BASIC_CAST type, NULL,
  15437. "The content type must specify a particle", NULL);
  15438. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15439. }
  15440. /*
  15441. * SPEC (1.4.3.2) "One of the following must be true:"
  15442. */
  15443. if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15444. /*
  15445. * SPEC (1.4.3.2.1) "The {content type} of the {base type
  15446. * definition} must be empty.
  15447. * PASS
  15448. */
  15449. } else {
  15450. /*
  15451. * SPEC (1.4.3.2.2) "All of the following must be true:"
  15452. */
  15453. if ((type->contentType != base->contentType) ||
  15454. ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
  15455. (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
  15456. /*
  15457. * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
  15458. * or both must be element-only."
  15459. */
  15460. xmlSchemaPCustomErr(ctxt,
  15461. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15462. WXS_BASIC_CAST type, NULL,
  15463. "The content type of both, the type and its base "
  15464. "type, must either 'mixed' or 'element-only'", NULL);
  15465. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15466. }
  15467. /*
  15468. * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
  15469. * complex type definition must be a `valid extension`
  15470. * of the {base type definition}'s particle, as defined
  15471. * in Particle Valid (Extension) ($3.9.6)."
  15472. *
  15473. * NOTE that we won't check "Particle Valid (Extension)",
  15474. * since it is ensured by the derivation process in
  15475. * xmlSchemaTypeFixup(). We need to implement this when heading
  15476. * for a construction API
  15477. * TODO: !! This is needed to be checked if redefining a type !!
  15478. */
  15479. }
  15480. /*
  15481. * URGENT TODO (1.5)
  15482. */
  15483. }
  15484. } else {
  15485. /*
  15486. * SPEC (2) "If the {base type definition} is a simple type definition,
  15487. * then all of the following must be true:"
  15488. */
  15489. if (type->contentTypeDef != base) {
  15490. /*
  15491. * SPEC (2.1) "The {content type} must be the same simple type
  15492. * definition."
  15493. */
  15494. xmlSchemaPCustomErr(ctxt,
  15495. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15496. WXS_BASIC_CAST type, NULL,
  15497. "The content type must be the simple base type", NULL);
  15498. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15499. }
  15500. if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
  15501. /*
  15502. * SPEC (2.2) "The {final} of the {base type definition} must not
  15503. * contain extension"
  15504. * NOTE that this is the same as (1.1).
  15505. */
  15506. xmlSchemaPCustomErr(ctxt,
  15507. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15508. WXS_BASIC_CAST type, NULL,
  15509. "The 'final' of the base type definition "
  15510. "contains 'extension'", NULL);
  15511. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15512. }
  15513. }
  15514. return (0);
  15515. }
  15516. /**
  15517. * xmlSchemaCheckDerivationOKRestriction:
  15518. * @ctxt: the schema parser context
  15519. * @type: the complex type definition
  15520. *
  15521. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15522. * Schema Component Constraint:
  15523. * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
  15524. *
  15525. * STATUS:
  15526. * missing:
  15527. * (5.4.2) ???
  15528. *
  15529. * ATTENTION:
  15530. * In XML Schema 1.1 this will be:
  15531. * Validation Rule: Checking complex type subsumption
  15532. *
  15533. * Returns 0 if the constraints are satisfied, a positive
  15534. * error code if not and -1 if an internal error occurred.
  15535. */
  15536. static int
  15537. xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
  15538. xmlSchemaTypePtr type)
  15539. {
  15540. xmlSchemaTypePtr base;
  15541. /*
  15542. * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
  15543. * temporarily only.
  15544. */
  15545. base = type->baseType;
  15546. if (! WXS_IS_COMPLEX(base)) {
  15547. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15548. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15549. type->node, WXS_BASIC_CAST type,
  15550. "The base type must be a complex type", NULL, NULL);
  15551. return(ctxt->err);
  15552. }
  15553. if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
  15554. /*
  15555. * SPEC (1) "The {base type definition} must be a complex type
  15556. * definition whose {final} does not contain restriction."
  15557. */
  15558. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15559. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15560. type->node, WXS_BASIC_CAST type,
  15561. "The 'final' of the base type definition "
  15562. "contains 'restriction'", NULL, NULL);
  15563. return (ctxt->err);
  15564. }
  15565. /*
  15566. * SPEC (2), (3) and (4)
  15567. * Those are handled in a separate function, since the
  15568. * same constraints are needed for redefinition of
  15569. * attribute groups as well.
  15570. */
  15571. if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
  15572. XML_SCHEMA_ACTION_DERIVE,
  15573. WXS_BASIC_CAST type, WXS_BASIC_CAST base,
  15574. type->attrUses, base->attrUses,
  15575. type->attributeWildcard,
  15576. base->attributeWildcard) == -1)
  15577. {
  15578. return(-1);
  15579. }
  15580. /*
  15581. * SPEC (5) "One of the following must be true:"
  15582. */
  15583. if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
  15584. /*
  15585. * SPEC (5.1) "The {base type definition} must be the
  15586. * `ur-type definition`."
  15587. * PASS
  15588. */
  15589. } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15590. (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
  15591. /*
  15592. * SPEC (5.2.1) "The {content type} of the complex type definition
  15593. * must be a simple type definition"
  15594. *
  15595. * SPEC (5.2.2) "One of the following must be true:"
  15596. */
  15597. if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15598. (base->contentType == XML_SCHEMA_CONTENT_BASIC))
  15599. {
  15600. int err;
  15601. /*
  15602. * SPEC (5.2.2.1) "The {content type} of the {base type
  15603. * definition} must be a simple type definition from which
  15604. * the {content type} is validly derived given the empty
  15605. * set as defined in Type Derivation OK (Simple) ($3.14.6)."
  15606. *
  15607. * ATTENTION TODO: This seems not needed if the type implicitly
  15608. * derived from the base type.
  15609. *
  15610. */
  15611. err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
  15612. type->contentTypeDef, base->contentTypeDef, 0);
  15613. if (err != 0) {
  15614. xmlChar *strA = NULL, *strB = NULL;
  15615. if (err == -1)
  15616. return(-1);
  15617. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15618. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15619. NULL, WXS_BASIC_CAST type,
  15620. "The {content type} %s is not validly derived from the "
  15621. "base type's {content type} %s",
  15622. xmlSchemaGetComponentDesignation(&strA,
  15623. type->contentTypeDef),
  15624. xmlSchemaGetComponentDesignation(&strB,
  15625. base->contentTypeDef));
  15626. FREE_AND_NULL(strA);
  15627. FREE_AND_NULL(strB);
  15628. return(ctxt->err);
  15629. }
  15630. } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  15631. (xmlSchemaIsParticleEmptiable(
  15632. (xmlSchemaParticlePtr) base->subtypes))) {
  15633. /*
  15634. * SPEC (5.2.2.2) "The {base type definition} must be mixed
  15635. * and have a particle which is `emptiable` as defined in
  15636. * Particle Emptiable ($3.9.6)."
  15637. * PASS
  15638. */
  15639. } else {
  15640. xmlSchemaPCustomErr(ctxt,
  15641. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15642. WXS_BASIC_CAST type, NULL,
  15643. "The content type of the base type must be either "
  15644. "a simple type or 'mixed' and an emptiable particle", NULL);
  15645. return (ctxt->err);
  15646. }
  15647. } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15648. /*
  15649. * SPEC (5.3.1) "The {content type} of the complex type itself must
  15650. * be empty"
  15651. */
  15652. if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15653. /*
  15654. * SPEC (5.3.2.1) "The {content type} of the {base type
  15655. * definition} must also be empty."
  15656. * PASS
  15657. */
  15658. } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
  15659. (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
  15660. xmlSchemaIsParticleEmptiable(
  15661. (xmlSchemaParticlePtr) base->subtypes)) {
  15662. /*
  15663. * SPEC (5.3.2.2) "The {content type} of the {base type
  15664. * definition} must be elementOnly or mixed and have a particle
  15665. * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
  15666. * PASS
  15667. */
  15668. } else {
  15669. xmlSchemaPCustomErr(ctxt,
  15670. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15671. WXS_BASIC_CAST type, NULL,
  15672. "The content type of the base type must be either "
  15673. "empty or 'mixed' (or 'elements-only') and an emptiable "
  15674. "particle", NULL);
  15675. return (ctxt->err);
  15676. }
  15677. } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
  15678. WXS_HAS_MIXED_CONTENT(type)) {
  15679. /*
  15680. * SPEC (5.4.1.1) "The {content type} of the complex type definition
  15681. * itself must be element-only"
  15682. */
  15683. if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
  15684. /*
  15685. * SPEC (5.4.1.2) "The {content type} of the complex type
  15686. * definition itself and of the {base type definition} must be
  15687. * mixed"
  15688. */
  15689. xmlSchemaPCustomErr(ctxt,
  15690. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15691. WXS_BASIC_CAST type, NULL,
  15692. "If the content type is 'mixed', then the content type of the "
  15693. "base type must also be 'mixed'", NULL);
  15694. return (ctxt->err);
  15695. }
  15696. /*
  15697. * SPEC (5.4.2) "The particle of the complex type definition itself
  15698. * must be a `valid restriction` of the particle of the {content
  15699. * type} of the {base type definition} as defined in Particle Valid
  15700. * (Restriction) ($3.9.6).
  15701. *
  15702. * URGENT TODO: (5.4.2)
  15703. */
  15704. } else {
  15705. xmlSchemaPCustomErr(ctxt,
  15706. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15707. WXS_BASIC_CAST type, NULL,
  15708. "The type is not a valid restriction of its base type", NULL);
  15709. return (ctxt->err);
  15710. }
  15711. return (0);
  15712. }
  15713. /**
  15714. * xmlSchemaCheckCTComponent:
  15715. * @ctxt: the schema parser context
  15716. * @type: the complex type definition
  15717. *
  15718. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15719. *
  15720. * Returns 0 if the constraints are satisfied, a positive
  15721. * error code if not and -1 if an internal error occurred.
  15722. */
  15723. static int
  15724. xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
  15725. xmlSchemaTypePtr type)
  15726. {
  15727. int ret;
  15728. /*
  15729. * Complex Type Definition Properties Correct
  15730. */
  15731. ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
  15732. if (ret != 0)
  15733. return (ret);
  15734. if (WXS_IS_EXTENSION(type))
  15735. ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
  15736. else
  15737. ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
  15738. return (ret);
  15739. }
  15740. /**
  15741. * xmlSchemaCheckSRCCT:
  15742. * @ctxt: the schema parser context
  15743. * @type: the complex type definition
  15744. *
  15745. * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
  15746. * Schema Representation Constraint:
  15747. * Complex Type Definition Representation OK (src-ct)
  15748. *
  15749. * Returns 0 if the constraints are satisfied, a positive
  15750. * error code if not and -1 if an internal error occurred.
  15751. */
  15752. static int
  15753. xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
  15754. xmlSchemaTypePtr type)
  15755. {
  15756. xmlSchemaTypePtr base;
  15757. int ret = 0;
  15758. /*
  15759. * TODO: Adjust the error codes here, as I used
  15760. * XML_SCHEMAP_SRC_CT_1 only yet.
  15761. */
  15762. base = type->baseType;
  15763. if (! WXS_HAS_SIMPLE_CONTENT(type)) {
  15764. /*
  15765. * 1 If the <complexContent> alternative is chosen, the type definition
  15766. * `resolved` to by the `actual value` of the base [attribute]
  15767. * must be a complex type definition;
  15768. */
  15769. if (! WXS_IS_COMPLEX(base)) {
  15770. xmlChar *str = NULL;
  15771. xmlSchemaPCustomErr(ctxt,
  15772. XML_SCHEMAP_SRC_CT_1,
  15773. WXS_BASIC_CAST type, type->node,
  15774. "If using <complexContent>, the base type is expected to be "
  15775. "a complex type. The base type '%s' is a simple type",
  15776. xmlSchemaFormatQName(&str, base->targetNamespace,
  15777. base->name));
  15778. FREE_AND_NULL(str)
  15779. return (XML_SCHEMAP_SRC_CT_1);
  15780. }
  15781. } else {
  15782. /*
  15783. * SPEC
  15784. * 2 If the <simpleContent> alternative is chosen, all of the
  15785. * following must be true:
  15786. * 2.1 The type definition `resolved` to by the `actual value` of the
  15787. * base [attribute] must be one of the following:
  15788. */
  15789. if (WXS_IS_SIMPLE(base)) {
  15790. if (WXS_IS_EXTENSION(type) == 0) {
  15791. xmlChar *str = NULL;
  15792. /*
  15793. * 2.1.3 only if the <extension> alternative is also
  15794. * chosen, a simple type definition.
  15795. */
  15796. /* TODO: Change error code to ..._SRC_CT_2_1_3. */
  15797. xmlSchemaPCustomErr(ctxt,
  15798. XML_SCHEMAP_SRC_CT_1,
  15799. WXS_BASIC_CAST type, NULL,
  15800. "If using <simpleContent> and <restriction>, the base "
  15801. "type must be a complex type. The base type '%s' is "
  15802. "a simple type",
  15803. xmlSchemaFormatQName(&str, base->targetNamespace,
  15804. base->name));
  15805. FREE_AND_NULL(str)
  15806. return (XML_SCHEMAP_SRC_CT_1);
  15807. }
  15808. } else {
  15809. /* Base type is a complex type. */
  15810. if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15811. (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
  15812. /*
  15813. * 2.1.1 a complex type definition whose {content type} is a
  15814. * simple type definition;
  15815. * PASS
  15816. */
  15817. if (base->contentTypeDef == NULL) {
  15818. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
  15819. WXS_BASIC_CAST type, NULL,
  15820. "Internal error: xmlSchemaCheckSRCCT, "
  15821. "'%s', base type has no content type",
  15822. type->name);
  15823. return (-1);
  15824. }
  15825. } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  15826. (WXS_IS_RESTRICTION(type))) {
  15827. /*
  15828. * 2.1.2 only if the <restriction> alternative is also
  15829. * chosen, a complex type definition whose {content type}
  15830. * is mixed and a particle emptiable.
  15831. */
  15832. if (! xmlSchemaIsParticleEmptiable(
  15833. (xmlSchemaParticlePtr) base->subtypes)) {
  15834. ret = XML_SCHEMAP_SRC_CT_1;
  15835. } else
  15836. /*
  15837. * Attention: at this point the <simpleType> child is in
  15838. * ->contentTypeDef (put there during parsing).
  15839. */
  15840. if (type->contentTypeDef == NULL) {
  15841. xmlChar *str = NULL;
  15842. /*
  15843. * 2.2 If clause 2.1.2 above is satisfied, then there
  15844. * must be a <simpleType> among the [children] of
  15845. * <restriction>.
  15846. */
  15847. /* TODO: Change error code to ..._SRC_CT_2_2. */
  15848. xmlSchemaPCustomErr(ctxt,
  15849. XML_SCHEMAP_SRC_CT_1,
  15850. WXS_BASIC_CAST type, NULL,
  15851. "A <simpleType> is expected among the children "
  15852. "of <restriction>, if <simpleContent> is used and "
  15853. "the base type '%s' is a complex type",
  15854. xmlSchemaFormatQName(&str, base->targetNamespace,
  15855. base->name));
  15856. FREE_AND_NULL(str)
  15857. return (XML_SCHEMAP_SRC_CT_1);
  15858. }
  15859. } else {
  15860. ret = XML_SCHEMAP_SRC_CT_1;
  15861. }
  15862. }
  15863. if (ret > 0) {
  15864. xmlChar *str = NULL;
  15865. if (WXS_IS_RESTRICTION(type)) {
  15866. xmlSchemaPCustomErr(ctxt,
  15867. XML_SCHEMAP_SRC_CT_1,
  15868. WXS_BASIC_CAST type, NULL,
  15869. "If <simpleContent> and <restriction> is used, the "
  15870. "base type must be a simple type or a complex type with "
  15871. "mixed content and particle emptiable. The base type "
  15872. "'%s' is none of those",
  15873. xmlSchemaFormatQName(&str, base->targetNamespace,
  15874. base->name));
  15875. } else {
  15876. xmlSchemaPCustomErr(ctxt,
  15877. XML_SCHEMAP_SRC_CT_1,
  15878. WXS_BASIC_CAST type, NULL,
  15879. "If <simpleContent> and <extension> is used, the "
  15880. "base type must be a simple type. The base type '%s' "
  15881. "is a complex type",
  15882. xmlSchemaFormatQName(&str, base->targetNamespace,
  15883. base->name));
  15884. }
  15885. FREE_AND_NULL(str)
  15886. }
  15887. }
  15888. /*
  15889. * SPEC (3) "The corresponding complex type definition component must
  15890. * satisfy the conditions set out in Constraints on Complex Type
  15891. * Definition Schema Components ($3.4.6);"
  15892. * NOTE (3) will be done in xmlSchemaTypeFixup().
  15893. */
  15894. /*
  15895. * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
  15896. * above for {attribute wildcard} is satisfied, the intensional
  15897. * intersection must be expressible, as defined in Attribute Wildcard
  15898. * Intersection ($3.10.6).
  15899. * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
  15900. */
  15901. return (ret);
  15902. }
  15903. #ifdef ENABLE_PARTICLE_RESTRICTION
  15904. /**
  15905. * xmlSchemaCheckParticleRangeOK:
  15906. * @ctxt: the schema parser context
  15907. * @type: the complex type definition
  15908. *
  15909. * (3.9.6) Constraints on Particle Schema Components
  15910. * Schema Component Constraint:
  15911. * Occurrence Range OK (range-ok)
  15912. *
  15913. * STATUS: complete
  15914. *
  15915. * Returns 0 if the constraints are satisfied, a positive
  15916. * error code if not and -1 if an internal error occurred.
  15917. */
  15918. static int
  15919. xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
  15920. int bmin, int bmax)
  15921. {
  15922. if (rmin < bmin)
  15923. return (1);
  15924. if ((bmax != UNBOUNDED) &&
  15925. (rmax > bmax))
  15926. return (1);
  15927. return (0);
  15928. }
  15929. /**
  15930. * xmlSchemaCheckRCaseNameAndTypeOK:
  15931. * @ctxt: the schema parser context
  15932. * @r: the restricting element declaration particle
  15933. * @b: the base element declaration particle
  15934. *
  15935. * (3.9.6) Constraints on Particle Schema Components
  15936. * Schema Component Constraint:
  15937. * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
  15938. * (rcase-NameAndTypeOK)
  15939. *
  15940. * STATUS:
  15941. * MISSING (3.2.3)
  15942. * CLARIFY: (3.2.2)
  15943. *
  15944. * Returns 0 if the constraints are satisfied, a positive
  15945. * error code if not and -1 if an internal error occurred.
  15946. */
  15947. static int
  15948. xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
  15949. xmlSchemaParticlePtr r,
  15950. xmlSchemaParticlePtr b)
  15951. {
  15952. xmlSchemaElementPtr elemR, elemB;
  15953. /* TODO: Error codes (rcase-NameAndTypeOK). */
  15954. elemR = (xmlSchemaElementPtr) r->children;
  15955. elemB = (xmlSchemaElementPtr) b->children;
  15956. /*
  15957. * SPEC (1) "The declarations' {name}s and {target namespace}s are
  15958. * the same."
  15959. */
  15960. if ((elemR != elemB) &&
  15961. ((! xmlStrEqual(elemR->name, elemB->name)) ||
  15962. (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
  15963. return (1);
  15964. /*
  15965. * SPEC (2) "R's occurrence range is a valid restriction of B's
  15966. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  15967. */
  15968. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  15969. b->minOccurs, b->maxOccurs) != 0)
  15970. return (1);
  15971. /*
  15972. * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
  15973. * {scope} are global."
  15974. */
  15975. if (elemR == elemB)
  15976. return (0);
  15977. /*
  15978. * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
  15979. */
  15980. if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
  15981. (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
  15982. return (1);
  15983. /*
  15984. * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
  15985. * or is not fixed, or R's declaration's {value constraint} is fixed
  15986. * with the same value."
  15987. */
  15988. if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
  15989. ((elemR->value == NULL) ||
  15990. ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
  15991. /* TODO: Equality of the initial value or normalized or canonical? */
  15992. (! xmlStrEqual(elemR->value, elemB->value))))
  15993. return (1);
  15994. /*
  15995. * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
  15996. * definitions} is a subset of B's declaration's {identity-constraint
  15997. * definitions}, if any."
  15998. */
  15999. if (elemB->idcs != NULL) {
  16000. /* TODO */
  16001. }
  16002. /*
  16003. * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
  16004. * superset of B's declaration's {disallowed substitutions}."
  16005. */
  16006. if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
  16007. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
  16008. ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
  16009. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
  16010. ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
  16011. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
  16012. return (1);
  16013. /*
  16014. * SPEC (3.2.5) "R's {type definition} is validly derived given
  16015. * {extension, list, union} from B's {type definition}"
  16016. *
  16017. * BADSPEC TODO: What's the point of adding "list" and "union" to the
  16018. * set, if the corresponding constraints handle "restriction" and
  16019. * "extension" only?
  16020. *
  16021. */
  16022. {
  16023. int set = 0;
  16024. set |= SUBSET_EXTENSION;
  16025. set |= SUBSET_LIST;
  16026. set |= SUBSET_UNION;
  16027. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
  16028. elemB->subtypes, set) != 0)
  16029. return (1);
  16030. }
  16031. return (0);
  16032. }
  16033. /**
  16034. * xmlSchemaCheckRCaseNSCompat:
  16035. * @ctxt: the schema parser context
  16036. * @r: the restricting element declaration particle
  16037. * @b: the base wildcard particle
  16038. *
  16039. * (3.9.6) Constraints on Particle Schema Components
  16040. * Schema Component Constraint:
  16041. * Particle Derivation OK (Elt:Any -- NSCompat)
  16042. * (rcase-NSCompat)
  16043. *
  16044. * STATUS: complete
  16045. *
  16046. * Returns 0 if the constraints are satisfied, a positive
  16047. * error code if not and -1 if an internal error occurred.
  16048. */
  16049. static int
  16050. xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
  16051. xmlSchemaParticlePtr r,
  16052. xmlSchemaParticlePtr b)
  16053. {
  16054. /* TODO:Error codes (rcase-NSCompat). */
  16055. /*
  16056. * SPEC "For an element declaration particle to be a `valid restriction`
  16057. * of a wildcard particle all of the following must be true:"
  16058. *
  16059. * SPEC (1) "The element declaration's {target namespace} is `valid`
  16060. * with respect to the wildcard's {namespace constraint} as defined by
  16061. * Wildcard allows Namespace Name ($3.10.4)."
  16062. */
  16063. if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
  16064. ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
  16065. return (1);
  16066. /*
  16067. * SPEC (2) "R's occurrence range is a valid restriction of B's
  16068. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  16069. */
  16070. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  16071. b->minOccurs, b->maxOccurs) != 0)
  16072. return (1);
  16073. return (0);
  16074. }
  16075. /**
  16076. * xmlSchemaCheckRCaseRecurseAsIfGroup:
  16077. * @ctxt: the schema parser context
  16078. * @r: the restricting element declaration particle
  16079. * @b: the base model group particle
  16080. *
  16081. * (3.9.6) Constraints on Particle Schema Components
  16082. * Schema Component Constraint:
  16083. * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
  16084. * (rcase-RecurseAsIfGroup)
  16085. *
  16086. * STATUS: TODO
  16087. *
  16088. * Returns 0 if the constraints are satisfied, a positive
  16089. * error code if not and -1 if an internal error occurred.
  16090. */
  16091. static int
  16092. xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
  16093. xmlSchemaParticlePtr r,
  16094. xmlSchemaParticlePtr b)
  16095. {
  16096. /* TODO: Error codes (rcase-RecurseAsIfGroup). */
  16097. TODO
  16098. return (0);
  16099. }
  16100. /**
  16101. * xmlSchemaCheckRCaseNSSubset:
  16102. * @ctxt: the schema parser context
  16103. * @r: the restricting wildcard particle
  16104. * @b: the base wildcard particle
  16105. *
  16106. * (3.9.6) Constraints on Particle Schema Components
  16107. * Schema Component Constraint:
  16108. * Particle Derivation OK (Any:Any -- NSSubset)
  16109. * (rcase-NSSubset)
  16110. *
  16111. * STATUS: complete
  16112. *
  16113. * Returns 0 if the constraints are satisfied, a positive
  16114. * error code if not and -1 if an internal error occurred.
  16115. */
  16116. static int
  16117. xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
  16118. xmlSchemaParticlePtr r,
  16119. xmlSchemaParticlePtr b,
  16120. int isAnyTypeBase)
  16121. {
  16122. /* TODO: Error codes (rcase-NSSubset). */
  16123. /*
  16124. * SPEC (1) "R's occurrence range is a valid restriction of B's
  16125. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  16126. */
  16127. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  16128. b->minOccurs, b->maxOccurs))
  16129. return (1);
  16130. /*
  16131. * SPEC (2) "R's {namespace constraint} must be an intensional subset
  16132. * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
  16133. */
  16134. if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
  16135. (xmlSchemaWildcardPtr) b->children))
  16136. return (1);
  16137. /*
  16138. * SPEC (3) "Unless B is the content model wildcard of the `ur-type
  16139. * definition`, R's {process contents} must be identical to or stronger
  16140. * than B's {process contents}, where strict is stronger than lax is
  16141. * stronger than skip."
  16142. */
  16143. if (! isAnyTypeBase) {
  16144. if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
  16145. ((xmlSchemaWildcardPtr) b->children)->processContents)
  16146. return (1);
  16147. }
  16148. return (0);
  16149. }
  16150. /**
  16151. * xmlSchemaCheckCOSParticleRestrict:
  16152. * @ctxt: the schema parser context
  16153. * @type: the complex type definition
  16154. *
  16155. * (3.9.6) Constraints on Particle Schema Components
  16156. * Schema Component Constraint:
  16157. * Particle Valid (Restriction) (cos-particle-restrict)
  16158. *
  16159. * STATUS: TODO
  16160. *
  16161. * Returns 0 if the constraints are satisfied, a positive
  16162. * error code if not and -1 if an internal error occurred.
  16163. */
  16164. static int
  16165. xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
  16166. xmlSchemaParticlePtr r,
  16167. xmlSchemaParticlePtr b)
  16168. {
  16169. int ret = 0;
  16170. /*part = WXS_TYPE_PARTICLE(type);
  16171. basePart = WXS_TYPE_PARTICLE(base);
  16172. */
  16173. TODO
  16174. /*
  16175. * SPEC (1) "They are the same particle."
  16176. */
  16177. if (r == b)
  16178. return (0);
  16179. return (0);
  16180. }
  16181. #if 0
  16182. /**
  16183. * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
  16184. * @ctxt: the schema parser context
  16185. * @r: the model group particle
  16186. * @b: the base wildcard particle
  16187. *
  16188. * (3.9.6) Constraints on Particle Schema Components
  16189. * Schema Component Constraint:
  16190. * Particle Derivation OK (All/Choice/Sequence:Any --
  16191. * NSRecurseCheckCardinality)
  16192. * (rcase-NSRecurseCheckCardinality)
  16193. *
  16194. * STATUS: TODO: subst-groups
  16195. *
  16196. * Returns 0 if the constraints are satisfied, a positive
  16197. * error code if not and -1 if an internal error occurred.
  16198. */
  16199. static int
  16200. xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
  16201. xmlSchemaParticlePtr r,
  16202. xmlSchemaParticlePtr b)
  16203. {
  16204. xmlSchemaParticlePtr part;
  16205. /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
  16206. if ((r->children == NULL) || (r->children->children == NULL))
  16207. return (-1);
  16208. /*
  16209. * SPEC "For a group particle to be a `valid restriction` of a
  16210. * wildcard particle..."
  16211. *
  16212. * SPEC (1) "Every member of the {particles} of the group is a `valid
  16213. * restriction` of the wildcard as defined by
  16214. * Particle Valid (Restriction) ($3.9.6)."
  16215. */
  16216. part = (xmlSchemaParticlePtr) r->children->children;
  16217. do {
  16218. if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
  16219. return (1);
  16220. part = (xmlSchemaParticlePtr) part->next;
  16221. } while (part != NULL);
  16222. /*
  16223. * SPEC (2) "The effective total range of the group [...] is a
  16224. * valid restriction of B's occurrence range as defined by
  16225. * Occurrence Range OK ($3.9.6)."
  16226. */
  16227. if (xmlSchemaCheckParticleRangeOK(
  16228. xmlSchemaGetParticleTotalRangeMin(r),
  16229. xmlSchemaGetParticleTotalRangeMax(r),
  16230. b->minOccurs, b->maxOccurs) != 0)
  16231. return (1);
  16232. return (0);
  16233. }
  16234. #endif
  16235. /**
  16236. * xmlSchemaCheckRCaseRecurse:
  16237. * @ctxt: the schema parser context
  16238. * @r: the <all> or <sequence> model group particle
  16239. * @b: the base <all> or <sequence> model group particle
  16240. *
  16241. * (3.9.6) Constraints on Particle Schema Components
  16242. * Schema Component Constraint:
  16243. * Particle Derivation OK (All:All,Sequence:Sequence --
  16244. Recurse)
  16245. * (rcase-Recurse)
  16246. *
  16247. * STATUS: ?
  16248. * TODO: subst-groups
  16249. *
  16250. * Returns 0 if the constraints are satisfied, a positive
  16251. * error code if not and -1 if an internal error occurred.
  16252. */
  16253. static int
  16254. xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
  16255. xmlSchemaParticlePtr r,
  16256. xmlSchemaParticlePtr b)
  16257. {
  16258. /* xmlSchemaParticlePtr part; */
  16259. /* TODO: Error codes (rcase-Recurse). */
  16260. if ((r->children == NULL) || (b->children == NULL) ||
  16261. (r->children->type != b->children->type))
  16262. return (-1);
  16263. /*
  16264. * SPEC "For an all or sequence group particle to be a `valid
  16265. * restriction` of another group particle with the same {compositor}..."
  16266. *
  16267. * SPEC (1) "R's occurrence range is a valid restriction of B's
  16268. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  16269. */
  16270. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  16271. b->minOccurs, b->maxOccurs))
  16272. return (1);
  16273. return (0);
  16274. }
  16275. #endif
  16276. #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
  16277. xmlSchemaPCustomErrExt(pctxt, \
  16278. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16279. WXS_BASIC_CAST fac1, fac1->node, \
  16280. "It is an error for both '%s' and '%s' to be specified on the "\
  16281. "same type definition", \
  16282. BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
  16283. BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
  16284. #define FACET_RESTR_ERR(fac1, msg) \
  16285. xmlSchemaPCustomErr(pctxt, \
  16286. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16287. WXS_BASIC_CAST fac1, fac1->node, \
  16288. msg, NULL);
  16289. #define FACET_RESTR_FIXED_ERR(fac) \
  16290. xmlSchemaPCustomErr(pctxt, \
  16291. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16292. WXS_BASIC_CAST fac, fac->node, \
  16293. "The base type's facet is 'fixed', thus the value must not " \
  16294. "differ", NULL);
  16295. static void
  16296. xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
  16297. xmlSchemaFacetPtr facet1,
  16298. xmlSchemaFacetPtr facet2,
  16299. int lessGreater,
  16300. int orEqual,
  16301. int ofBase)
  16302. {
  16303. xmlChar *msg = NULL;
  16304. msg = xmlStrdup(BAD_CAST "'");
  16305. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
  16306. msg = xmlStrcat(msg, BAD_CAST "' has to be");
  16307. if (lessGreater == 0)
  16308. msg = xmlStrcat(msg, BAD_CAST " equal to");
  16309. if (lessGreater == 1)
  16310. msg = xmlStrcat(msg, BAD_CAST " greater than");
  16311. else
  16312. msg = xmlStrcat(msg, BAD_CAST " less than");
  16313. if (orEqual)
  16314. msg = xmlStrcat(msg, BAD_CAST " or equal to");
  16315. msg = xmlStrcat(msg, BAD_CAST " '");
  16316. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
  16317. if (ofBase)
  16318. msg = xmlStrcat(msg, BAD_CAST "' of the base type");
  16319. else
  16320. msg = xmlStrcat(msg, BAD_CAST "'");
  16321. xmlSchemaPCustomErr(pctxt,
  16322. XML_SCHEMAP_INVALID_FACET_VALUE,
  16323. WXS_BASIC_CAST facet1, NULL,
  16324. (const char *) msg, NULL);
  16325. if (msg != NULL)
  16326. xmlFree(msg);
  16327. }
  16328. /*
  16329. * xmlSchemaDeriveAndValidateFacets:
  16330. *
  16331. * Schema Component Constraint: Simple Type Restriction (Facets)
  16332. * (st-restrict-facets)
  16333. */
  16334. static int
  16335. xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
  16336. xmlSchemaTypePtr type)
  16337. {
  16338. xmlSchemaTypePtr base = type->baseType;
  16339. xmlSchemaFacetLinkPtr link, cur, last = NULL;
  16340. xmlSchemaFacetPtr facet, bfacet,
  16341. flength = NULL, ftotdig = NULL, ffracdig = NULL,
  16342. fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
  16343. fmininc = NULL, fmaxinc = NULL,
  16344. fminexc = NULL, fmaxexc = NULL,
  16345. bflength = NULL, bftotdig = NULL, bffracdig = NULL,
  16346. bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
  16347. bfmininc = NULL, bfmaxinc = NULL,
  16348. bfminexc = NULL, bfmaxexc = NULL;
  16349. int res; /* err = 0, fixedErr; */
  16350. /*
  16351. * SPEC st-restrict-facets 1:
  16352. * "The {variety} of R is the same as that of B."
  16353. */
  16354. /*
  16355. * SPEC st-restrict-facets 2:
  16356. * "If {variety} is atomic, the {primitive type definition}
  16357. * of R is the same as that of B."
  16358. *
  16359. * NOTE: we leave 1 & 2 out for now, since this will be
  16360. * satisfied by the derivation process.
  16361. * CONSTRUCTION TODO: Maybe needed if using a construction API.
  16362. */
  16363. /*
  16364. * SPEC st-restrict-facets 3:
  16365. * "The {facets} of R are the union of S and the {facets}
  16366. * of B, eliminating duplicates. To eliminate duplicates,
  16367. * when a facet of the same kind occurs in both S and the
  16368. * {facets} of B, the one in the {facets} of B is not
  16369. * included, with the exception of enumeration and pattern
  16370. * facets, for which multiple occurrences with distinct values
  16371. * are allowed."
  16372. */
  16373. if ((type->facetSet == NULL) && (base->facetSet == NULL))
  16374. return (0);
  16375. last = type->facetSet;
  16376. if (last != NULL)
  16377. while (last->next != NULL)
  16378. last = last->next;
  16379. for (cur = type->facetSet; cur != NULL; cur = cur->next) {
  16380. facet = cur->facet;
  16381. switch (facet->type) {
  16382. case XML_SCHEMA_FACET_LENGTH:
  16383. flength = facet; break;
  16384. case XML_SCHEMA_FACET_MINLENGTH:
  16385. fminlen = facet; break;
  16386. case XML_SCHEMA_FACET_MININCLUSIVE:
  16387. fmininc = facet; break;
  16388. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  16389. fminexc = facet; break;
  16390. case XML_SCHEMA_FACET_MAXLENGTH:
  16391. fmaxlen = facet; break;
  16392. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  16393. fmaxinc = facet; break;
  16394. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  16395. fmaxexc = facet; break;
  16396. case XML_SCHEMA_FACET_TOTALDIGITS:
  16397. ftotdig = facet; break;
  16398. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  16399. ffracdig = facet; break;
  16400. default:
  16401. break;
  16402. }
  16403. }
  16404. for (cur = base->facetSet; cur != NULL; cur = cur->next) {
  16405. facet = cur->facet;
  16406. switch (facet->type) {
  16407. case XML_SCHEMA_FACET_LENGTH:
  16408. bflength = facet; break;
  16409. case XML_SCHEMA_FACET_MINLENGTH:
  16410. bfminlen = facet; break;
  16411. case XML_SCHEMA_FACET_MININCLUSIVE:
  16412. bfmininc = facet; break;
  16413. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  16414. bfminexc = facet; break;
  16415. case XML_SCHEMA_FACET_MAXLENGTH:
  16416. bfmaxlen = facet; break;
  16417. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  16418. bfmaxinc = facet; break;
  16419. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  16420. bfmaxexc = facet; break;
  16421. case XML_SCHEMA_FACET_TOTALDIGITS:
  16422. bftotdig = facet; break;
  16423. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  16424. bffracdig = facet; break;
  16425. default:
  16426. break;
  16427. }
  16428. }
  16429. /*
  16430. * length and minLength or maxLength (2.2) + (3.2)
  16431. */
  16432. if (flength && (fminlen || fmaxlen)) {
  16433. FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
  16434. "either of 'minLength' or 'maxLength' to be specified on "
  16435. "the same type definition")
  16436. }
  16437. /*
  16438. * Mutual exclusions in the same derivation step.
  16439. */
  16440. if ((fmaxinc) && (fmaxexc)) {
  16441. /*
  16442. * SCC "maxInclusive and maxExclusive"
  16443. */
  16444. FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
  16445. }
  16446. if ((fmininc) && (fminexc)) {
  16447. /*
  16448. * SCC "minInclusive and minExclusive"
  16449. */
  16450. FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
  16451. }
  16452. if (flength && bflength) {
  16453. /*
  16454. * SCC "length valid restriction"
  16455. * The values have to be equal.
  16456. */
  16457. res = xmlSchemaCompareValues(flength->val, bflength->val);
  16458. if (res == -2)
  16459. goto internal_error;
  16460. if (res != 0)
  16461. xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
  16462. if ((res != 0) && (bflength->fixed)) {
  16463. FACET_RESTR_FIXED_ERR(flength)
  16464. }
  16465. }
  16466. if (fminlen && bfminlen) {
  16467. /*
  16468. * SCC "minLength valid restriction"
  16469. * minLength >= BASE minLength
  16470. */
  16471. res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
  16472. if (res == -2)
  16473. goto internal_error;
  16474. if (res == -1)
  16475. xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
  16476. if ((res != 0) && (bfminlen->fixed)) {
  16477. FACET_RESTR_FIXED_ERR(fminlen)
  16478. }
  16479. }
  16480. if (fmaxlen && bfmaxlen) {
  16481. /*
  16482. * SCC "maxLength valid restriction"
  16483. * maxLength <= BASE minLength
  16484. */
  16485. res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
  16486. if (res == -2)
  16487. goto internal_error;
  16488. if (res == 1)
  16489. xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
  16490. if ((res != 0) && (bfmaxlen->fixed)) {
  16491. FACET_RESTR_FIXED_ERR(fmaxlen)
  16492. }
  16493. }
  16494. /*
  16495. * SCC "length and minLength or maxLength"
  16496. */
  16497. if (! flength)
  16498. flength = bflength;
  16499. if (flength) {
  16500. if (! fminlen)
  16501. fminlen = bfminlen;
  16502. if (fminlen) {
  16503. /* (1.1) length >= minLength */
  16504. res = xmlSchemaCompareValues(flength->val, fminlen->val);
  16505. if (res == -2)
  16506. goto internal_error;
  16507. if (res == -1)
  16508. xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
  16509. }
  16510. if (! fmaxlen)
  16511. fmaxlen = bfmaxlen;
  16512. if (fmaxlen) {
  16513. /* (2.1) length <= maxLength */
  16514. res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
  16515. if (res == -2)
  16516. goto internal_error;
  16517. if (res == 1)
  16518. xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
  16519. }
  16520. }
  16521. if (fmaxinc) {
  16522. /*
  16523. * "maxInclusive"
  16524. */
  16525. if (fmininc) {
  16526. /* SCC "maxInclusive >= minInclusive" */
  16527. res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
  16528. if (res == -2)
  16529. goto internal_error;
  16530. if (res == -1) {
  16531. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
  16532. }
  16533. }
  16534. /*
  16535. * SCC "maxInclusive valid restriction"
  16536. */
  16537. if (bfmaxinc) {
  16538. /* maxInclusive <= BASE maxInclusive */
  16539. res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
  16540. if (res == -2)
  16541. goto internal_error;
  16542. if (res == 1)
  16543. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
  16544. if ((res != 0) && (bfmaxinc->fixed)) {
  16545. FACET_RESTR_FIXED_ERR(fmaxinc)
  16546. }
  16547. }
  16548. if (bfmaxexc) {
  16549. /* maxInclusive < BASE maxExclusive */
  16550. res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
  16551. if (res == -2)
  16552. goto internal_error;
  16553. if (res != -1) {
  16554. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
  16555. }
  16556. }
  16557. if (bfmininc) {
  16558. /* maxInclusive >= BASE minInclusive */
  16559. res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
  16560. if (res == -2)
  16561. goto internal_error;
  16562. if (res == -1) {
  16563. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
  16564. }
  16565. }
  16566. if (bfminexc) {
  16567. /* maxInclusive > BASE minExclusive */
  16568. res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
  16569. if (res == -2)
  16570. goto internal_error;
  16571. if (res != 1) {
  16572. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
  16573. }
  16574. }
  16575. }
  16576. if (fmaxexc) {
  16577. /*
  16578. * "maxExclusive >= minExclusive"
  16579. */
  16580. if (fminexc) {
  16581. res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
  16582. if (res == -2)
  16583. goto internal_error;
  16584. if (res == -1) {
  16585. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
  16586. }
  16587. }
  16588. /*
  16589. * "maxExclusive valid restriction"
  16590. */
  16591. if (bfmaxexc) {
  16592. /* maxExclusive <= BASE maxExclusive */
  16593. res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
  16594. if (res == -2)
  16595. goto internal_error;
  16596. if (res == 1) {
  16597. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
  16598. }
  16599. if ((res != 0) && (bfmaxexc->fixed)) {
  16600. FACET_RESTR_FIXED_ERR(fmaxexc)
  16601. }
  16602. }
  16603. if (bfmaxinc) {
  16604. /* maxExclusive <= BASE maxInclusive */
  16605. res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
  16606. if (res == -2)
  16607. goto internal_error;
  16608. if (res == 1) {
  16609. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
  16610. }
  16611. }
  16612. if (bfmininc) {
  16613. /* maxExclusive > BASE minInclusive */
  16614. res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
  16615. if (res == -2)
  16616. goto internal_error;
  16617. if (res != 1) {
  16618. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
  16619. }
  16620. }
  16621. if (bfminexc) {
  16622. /* maxExclusive > BASE minExclusive */
  16623. res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
  16624. if (res == -2)
  16625. goto internal_error;
  16626. if (res != 1) {
  16627. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
  16628. }
  16629. }
  16630. }
  16631. if (fminexc) {
  16632. /*
  16633. * "minExclusive < maxInclusive"
  16634. */
  16635. if (fmaxinc) {
  16636. res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
  16637. if (res == -2)
  16638. goto internal_error;
  16639. if (res != -1) {
  16640. xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
  16641. }
  16642. }
  16643. /*
  16644. * "minExclusive valid restriction"
  16645. */
  16646. if (bfminexc) {
  16647. /* minExclusive >= BASE minExclusive */
  16648. res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
  16649. if (res == -2)
  16650. goto internal_error;
  16651. if (res == -1) {
  16652. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
  16653. }
  16654. if ((res != 0) && (bfminexc->fixed)) {
  16655. FACET_RESTR_FIXED_ERR(fminexc)
  16656. }
  16657. }
  16658. if (bfmaxinc) {
  16659. /* minExclusive <= BASE maxInclusive */
  16660. res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
  16661. if (res == -2)
  16662. goto internal_error;
  16663. if (res == 1) {
  16664. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
  16665. }
  16666. }
  16667. if (bfmininc) {
  16668. /* minExclusive >= BASE minInclusive */
  16669. res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
  16670. if (res == -2)
  16671. goto internal_error;
  16672. if (res == -1) {
  16673. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
  16674. }
  16675. }
  16676. if (bfmaxexc) {
  16677. /* minExclusive < BASE maxExclusive */
  16678. res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
  16679. if (res == -2)
  16680. goto internal_error;
  16681. if (res != -1) {
  16682. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
  16683. }
  16684. }
  16685. }
  16686. if (fmininc) {
  16687. /*
  16688. * "minInclusive < maxExclusive"
  16689. */
  16690. if (fmaxexc) {
  16691. res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
  16692. if (res == -2)
  16693. goto internal_error;
  16694. if (res != -1) {
  16695. xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
  16696. }
  16697. }
  16698. /*
  16699. * "minExclusive valid restriction"
  16700. */
  16701. if (bfmininc) {
  16702. /* minInclusive >= BASE minInclusive */
  16703. res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
  16704. if (res == -2)
  16705. goto internal_error;
  16706. if (res == -1) {
  16707. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
  16708. }
  16709. if ((res != 0) && (bfmininc->fixed)) {
  16710. FACET_RESTR_FIXED_ERR(fmininc)
  16711. }
  16712. }
  16713. if (bfmaxinc) {
  16714. /* minInclusive <= BASE maxInclusive */
  16715. res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
  16716. if (res == -2)
  16717. goto internal_error;
  16718. if (res == 1) {
  16719. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
  16720. }
  16721. }
  16722. if (bfminexc) {
  16723. /* minInclusive > BASE minExclusive */
  16724. res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
  16725. if (res == -2)
  16726. goto internal_error;
  16727. if (res != 1)
  16728. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
  16729. }
  16730. if (bfmaxexc) {
  16731. /* minInclusive < BASE maxExclusive */
  16732. res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
  16733. if (res == -2)
  16734. goto internal_error;
  16735. if (res != -1)
  16736. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
  16737. }
  16738. }
  16739. if (ftotdig && bftotdig) {
  16740. /*
  16741. * SCC " totalDigits valid restriction"
  16742. * totalDigits <= BASE totalDigits
  16743. */
  16744. res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
  16745. if (res == -2)
  16746. goto internal_error;
  16747. if (res == 1)
  16748. xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
  16749. -1, 1, 1);
  16750. if ((res != 0) && (bftotdig->fixed)) {
  16751. FACET_RESTR_FIXED_ERR(ftotdig)
  16752. }
  16753. }
  16754. if (ffracdig && bffracdig) {
  16755. /*
  16756. * SCC "fractionDigits valid restriction"
  16757. * fractionDigits <= BASE fractionDigits
  16758. */
  16759. res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
  16760. if (res == -2)
  16761. goto internal_error;
  16762. if (res == 1)
  16763. xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
  16764. -1, 1, 1);
  16765. if ((res != 0) && (bffracdig->fixed)) {
  16766. FACET_RESTR_FIXED_ERR(ffracdig)
  16767. }
  16768. }
  16769. /*
  16770. * SCC "fractionDigits less than or equal to totalDigits"
  16771. */
  16772. if (! ftotdig)
  16773. ftotdig = bftotdig;
  16774. if (! ffracdig)
  16775. ffracdig = bffracdig;
  16776. if (ftotdig && ffracdig) {
  16777. res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
  16778. if (res == -2)
  16779. goto internal_error;
  16780. if (res == 1)
  16781. xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
  16782. -1, 1, 0);
  16783. }
  16784. /*
  16785. * *Enumerations* won' be added here, since only the first set
  16786. * of enumerations in the ancestor-or-self axis is used
  16787. * for validation, plus we need to use the base type of those
  16788. * enumerations for whitespace.
  16789. *
  16790. * *Patterns*: won't be add here, since they are ORed at
  16791. * type level and ANDed at ancestor level. This will
  16792. * happen during validation by walking the base axis
  16793. * of the type.
  16794. */
  16795. for (cur = base->facetSet; cur != NULL; cur = cur->next) {
  16796. bfacet = cur->facet;
  16797. /*
  16798. * Special handling of enumerations and patterns.
  16799. * TODO: hmm, they should not appear in the set, so remove this.
  16800. */
  16801. if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
  16802. (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
  16803. continue;
  16804. /*
  16805. * Search for a duplicate facet in the current type.
  16806. */
  16807. link = type->facetSet;
  16808. /* err = 0; */
  16809. /* fixedErr = 0; */
  16810. while (link != NULL) {
  16811. facet = link->facet;
  16812. if (facet->type == bfacet->type) {
  16813. switch (facet->type) {
  16814. case XML_SCHEMA_FACET_WHITESPACE:
  16815. /*
  16816. * The whitespace must be stronger.
  16817. */
  16818. if (facet->whitespace < bfacet->whitespace) {
  16819. FACET_RESTR_ERR(facet,
  16820. "The 'whitespace' value has to be equal to "
  16821. "or stronger than the 'whitespace' value of "
  16822. "the base type")
  16823. }
  16824. if ((bfacet->fixed) &&
  16825. (facet->whitespace != bfacet->whitespace)) {
  16826. FACET_RESTR_FIXED_ERR(facet)
  16827. }
  16828. break;
  16829. default:
  16830. break;
  16831. }
  16832. /* Duplicate found. */
  16833. break;
  16834. }
  16835. link = link->next;
  16836. }
  16837. /*
  16838. * If no duplicate was found: add the base types's facet
  16839. * to the set.
  16840. */
  16841. if (link == NULL) {
  16842. link = (xmlSchemaFacetLinkPtr)
  16843. xmlMalloc(sizeof(xmlSchemaFacetLink));
  16844. if (link == NULL) {
  16845. xmlSchemaPErrMemory(pctxt,
  16846. "deriving facets, creating a facet link", NULL);
  16847. return (-1);
  16848. }
  16849. link->facet = cur->facet;
  16850. link->next = NULL;
  16851. if (last == NULL)
  16852. type->facetSet = link;
  16853. else
  16854. last->next = link;
  16855. last = link;
  16856. }
  16857. }
  16858. return (0);
  16859. internal_error:
  16860. PERROR_INT("xmlSchemaDeriveAndValidateFacets",
  16861. "an error occurred");
  16862. return (-1);
  16863. }
  16864. static int
  16865. xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
  16866. xmlSchemaTypePtr type)
  16867. {
  16868. xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
  16869. /*
  16870. * The actual value is then formed by replacing any union type
  16871. * definition in the `explicit members` with the members of their
  16872. * {member type definitions}, in order.
  16873. *
  16874. * TODO: There's a bug entry at
  16875. * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
  16876. * which indicates that we'll keep the union types the future.
  16877. */
  16878. link = type->memberTypes;
  16879. while (link != NULL) {
  16880. if (WXS_IS_TYPE_NOT_FIXED(link->type))
  16881. xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
  16882. if (WXS_IS_UNION(link->type)) {
  16883. subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
  16884. if (subLink != NULL) {
  16885. link->type = subLink->type;
  16886. if (subLink->next != NULL) {
  16887. lastLink = link->next;
  16888. subLink = subLink->next;
  16889. prevLink = link;
  16890. while (subLink != NULL) {
  16891. newLink = (xmlSchemaTypeLinkPtr)
  16892. xmlMalloc(sizeof(xmlSchemaTypeLink));
  16893. if (newLink == NULL) {
  16894. xmlSchemaPErrMemory(pctxt, "allocating a type link",
  16895. NULL);
  16896. return (-1);
  16897. }
  16898. newLink->type = subLink->type;
  16899. prevLink->next = newLink;
  16900. prevLink = newLink;
  16901. newLink->next = lastLink;
  16902. subLink = subLink->next;
  16903. }
  16904. }
  16905. }
  16906. }
  16907. link = link->next;
  16908. }
  16909. return (0);
  16910. }
  16911. static void
  16912. xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
  16913. {
  16914. int has = 0, needVal = 0, normVal = 0;
  16915. has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
  16916. if (has) {
  16917. needVal = (type->baseType->flags &
  16918. XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
  16919. normVal = (type->baseType->flags &
  16920. XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
  16921. }
  16922. if (type->facets != NULL) {
  16923. xmlSchemaFacetPtr fac;
  16924. for (fac = type->facets; fac != NULL; fac = fac->next) {
  16925. switch (fac->type) {
  16926. case XML_SCHEMA_FACET_WHITESPACE:
  16927. break;
  16928. case XML_SCHEMA_FACET_PATTERN:
  16929. normVal = 1;
  16930. has = 1;
  16931. break;
  16932. case XML_SCHEMA_FACET_ENUMERATION:
  16933. needVal = 1;
  16934. normVal = 1;
  16935. has = 1;
  16936. break;
  16937. default:
  16938. has = 1;
  16939. break;
  16940. }
  16941. }
  16942. }
  16943. if (normVal)
  16944. type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
  16945. if (needVal)
  16946. type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
  16947. if (has)
  16948. type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
  16949. if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
  16950. xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
  16951. /*
  16952. * OPTIMIZE VAL TODO: Some facets need a computed value.
  16953. */
  16954. if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
  16955. (prim->builtInType != XML_SCHEMAS_STRING)) {
  16956. type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
  16957. }
  16958. }
  16959. }
  16960. static int
  16961. xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
  16962. {
  16963. /*
  16964. * Evaluate the whitespace-facet value.
  16965. */
  16966. if (WXS_IS_LIST(type)) {
  16967. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16968. return (0);
  16969. } else if (WXS_IS_UNION(type))
  16970. return (0);
  16971. if (type->facetSet != NULL) {
  16972. xmlSchemaFacetLinkPtr lin;
  16973. for (lin = type->facetSet; lin != NULL; lin = lin->next) {
  16974. if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
  16975. switch (lin->facet->whitespace) {
  16976. case XML_SCHEMAS_FACET_PRESERVE:
  16977. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
  16978. break;
  16979. case XML_SCHEMAS_FACET_REPLACE:
  16980. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
  16981. break;
  16982. case XML_SCHEMAS_FACET_COLLAPSE:
  16983. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16984. break;
  16985. default:
  16986. return (-1);
  16987. }
  16988. return (0);
  16989. }
  16990. }
  16991. }
  16992. /*
  16993. * For all `atomic` datatypes other than string (and types `derived`
  16994. * by `restriction` from it) the value of whiteSpace is fixed to
  16995. * collapse
  16996. */
  16997. {
  16998. xmlSchemaTypePtr anc;
  16999. for (anc = type->baseType; anc != NULL &&
  17000. anc->builtInType != XML_SCHEMAS_ANYTYPE;
  17001. anc = anc->baseType) {
  17002. if (anc->type == XML_SCHEMA_TYPE_BASIC) {
  17003. if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
  17004. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
  17005. } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
  17006. (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
  17007. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
  17008. } else
  17009. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  17010. break;
  17011. }
  17012. }
  17013. }
  17014. return (0);
  17015. }
  17016. static int
  17017. xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
  17018. xmlSchemaTypePtr type)
  17019. {
  17020. if (type->type != XML_SCHEMA_TYPE_SIMPLE)
  17021. return(0);
  17022. if (! WXS_IS_TYPE_NOT_FIXED_1(type))
  17023. return(0);
  17024. type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
  17025. if (WXS_IS_LIST(type)) {
  17026. /*
  17027. * Corresponds to <simpleType><list>...
  17028. */
  17029. if (type->subtypes == NULL) {
  17030. /*
  17031. * This one is really needed, so get out.
  17032. */
  17033. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  17034. "list type has no item-type assigned");
  17035. return(-1);
  17036. }
  17037. } else if (WXS_IS_UNION(type)) {
  17038. /*
  17039. * Corresponds to <simpleType><union>...
  17040. */
  17041. if (type->memberTypes == NULL) {
  17042. /*
  17043. * This one is really needed, so get out.
  17044. */
  17045. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  17046. "union type has no member-types assigned");
  17047. return(-1);
  17048. }
  17049. } else {
  17050. /*
  17051. * Corresponds to <simpleType><restriction>...
  17052. */
  17053. if (type->baseType == NULL) {
  17054. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  17055. "type has no base-type assigned");
  17056. return(-1);
  17057. }
  17058. if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
  17059. if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
  17060. return(-1);
  17061. /*
  17062. * Variety
  17063. * If the <restriction> alternative is chosen, then the
  17064. * {variety} of the {base type definition}.
  17065. */
  17066. if (WXS_IS_ATOMIC(type->baseType))
  17067. type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
  17068. else if (WXS_IS_LIST(type->baseType)) {
  17069. type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
  17070. /*
  17071. * Inherit the itemType.
  17072. */
  17073. type->subtypes = type->baseType->subtypes;
  17074. } else if (WXS_IS_UNION(type->baseType)) {
  17075. type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
  17076. /*
  17077. * NOTE that we won't assign the memberTypes of the base,
  17078. * since this will make trouble when freeing them; we will
  17079. * use a lookup function to access them instead.
  17080. */
  17081. }
  17082. }
  17083. return(0);
  17084. }
  17085. #ifdef DEBUG_TYPE
  17086. static void
  17087. xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
  17088. xmlSchemaTypePtr type)
  17089. {
  17090. if (type->node != NULL) {
  17091. xmlGenericError(xmlGenericErrorContext,
  17092. "Type of %s : %s:%d :", name,
  17093. type->node->doc->URL,
  17094. xmlGetLineNo(type->node));
  17095. } else {
  17096. xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
  17097. }
  17098. if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
  17099. switch (type->contentType) {
  17100. case XML_SCHEMA_CONTENT_SIMPLE:
  17101. xmlGenericError(xmlGenericErrorContext, "simple\n");
  17102. break;
  17103. case XML_SCHEMA_CONTENT_ELEMENTS:
  17104. xmlGenericError(xmlGenericErrorContext, "elements\n");
  17105. break;
  17106. case XML_SCHEMA_CONTENT_UNKNOWN:
  17107. xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
  17108. break;
  17109. case XML_SCHEMA_CONTENT_EMPTY:
  17110. xmlGenericError(xmlGenericErrorContext, "empty\n");
  17111. break;
  17112. case XML_SCHEMA_CONTENT_MIXED:
  17113. if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
  17114. type->subtypes))
  17115. xmlGenericError(xmlGenericErrorContext,
  17116. "mixed as emptiable particle\n");
  17117. else
  17118. xmlGenericError(xmlGenericErrorContext, "mixed\n");
  17119. break;
  17120. /* Removed, since not used. */
  17121. /*
  17122. case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
  17123. xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
  17124. break;
  17125. */
  17126. case XML_SCHEMA_CONTENT_BASIC:
  17127. xmlGenericError(xmlGenericErrorContext, "basic\n");
  17128. break;
  17129. default:
  17130. xmlGenericError(xmlGenericErrorContext,
  17131. "not registered !!!\n");
  17132. break;
  17133. }
  17134. }
  17135. }
  17136. #endif
  17137. /*
  17138. * 3.14.6 Constraints on Simple Type Definition Schema Components
  17139. */
  17140. static int
  17141. xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
  17142. xmlSchemaTypePtr type)
  17143. {
  17144. int res, olderrs = pctxt->nberrors;
  17145. if (type->type != XML_SCHEMA_TYPE_SIMPLE)
  17146. return(-1);
  17147. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17148. return(0);
  17149. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
  17150. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  17151. if (type->baseType == NULL) {
  17152. PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
  17153. "missing baseType");
  17154. goto exit_failure;
  17155. }
  17156. if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
  17157. xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
  17158. /*
  17159. * If a member type of a union is a union itself, we need to substitute
  17160. * that member type for its member types.
  17161. * NOTE that this might change in WXS 1.1; i.e. we will keep the union
  17162. * types in WXS 1.1.
  17163. */
  17164. if ((type->memberTypes != NULL) &&
  17165. (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
  17166. return(-1);
  17167. /*
  17168. * SPEC src-simple-type 1
  17169. * "The corresponding simple type definition, if any, must satisfy
  17170. * the conditions set out in Constraints on Simple Type Definition
  17171. * Schema Components ($3.14.6)."
  17172. */
  17173. /*
  17174. * Schema Component Constraint: Simple Type Definition Properties Correct
  17175. * (st-props-correct)
  17176. */
  17177. res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
  17178. HFAILURE HERROR
  17179. /*
  17180. * Schema Component Constraint: Derivation Valid (Restriction, Simple)
  17181. * (cos-st-restricts)
  17182. */
  17183. res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
  17184. HFAILURE HERROR
  17185. /*
  17186. * TODO: Removed the error report, since it got annoying to get an
  17187. * extra error report, if anything failed until now.
  17188. * Enable this if needed.
  17189. *
  17190. * xmlSchemaPErr(ctxt, type->node,
  17191. * XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  17192. * "Simple type '%s' does not satisfy the constraints "
  17193. * "on simple type definitions.\n",
  17194. * type->name, NULL);
  17195. */
  17196. /*
  17197. * Schema Component Constraint: Simple Type Restriction (Facets)
  17198. * (st-restrict-facets)
  17199. */
  17200. res = xmlSchemaCheckFacetValues(type, pctxt);
  17201. HFAILURE HERROR
  17202. if ((type->facetSet != NULL) ||
  17203. (type->baseType->facetSet != NULL)) {
  17204. res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
  17205. HFAILURE HERROR
  17206. }
  17207. /*
  17208. * Whitespace value.
  17209. */
  17210. res = xmlSchemaTypeFixupWhitespace(type);
  17211. HFAILURE HERROR
  17212. xmlSchemaTypeFixupOptimFacets(type);
  17213. exit_error:
  17214. #ifdef DEBUG_TYPE
  17215. xmlSchemaDebugFixedType(pctxt, type);
  17216. #endif
  17217. if (olderrs != pctxt->nberrors)
  17218. return(pctxt->err);
  17219. return(0);
  17220. exit_failure:
  17221. #ifdef DEBUG_TYPE
  17222. xmlSchemaDebugFixedType(pctxt, type);
  17223. #endif
  17224. return(-1);
  17225. }
  17226. static int
  17227. xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
  17228. xmlSchemaTypePtr type)
  17229. {
  17230. int res = 0, olderrs = pctxt->nberrors;
  17231. xmlSchemaTypePtr baseType = type->baseType;
  17232. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17233. return(0);
  17234. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
  17235. if (baseType == NULL) {
  17236. PERROR_INT("xmlSchemaFixupComplexType",
  17237. "missing baseType");
  17238. goto exit_failure;
  17239. }
  17240. /*
  17241. * Fixup the base type.
  17242. */
  17243. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  17244. xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
  17245. if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
  17246. /*
  17247. * Skip fixup if the base type is invalid.
  17248. * TODO: Generate a warning!
  17249. */
  17250. return(0);
  17251. }
  17252. /*
  17253. * This basically checks if the base type can be derived.
  17254. */
  17255. res = xmlSchemaCheckSRCCT(pctxt, type);
  17256. HFAILURE HERROR
  17257. /*
  17258. * Fixup the content type.
  17259. */
  17260. if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
  17261. /*
  17262. * Corresponds to <complexType><simpleContent>...
  17263. */
  17264. if ((WXS_IS_COMPLEX(baseType)) &&
  17265. (baseType->contentTypeDef != NULL) &&
  17266. (WXS_IS_RESTRICTION(type))) {
  17267. xmlSchemaTypePtr contentBase, content;
  17268. #ifdef ENABLE_NAMED_LOCALS
  17269. char buf[30];
  17270. const xmlChar *tmpname;
  17271. #endif
  17272. /*
  17273. * SPEC (1) If <restriction> + base type is <complexType>,
  17274. * "whose own {content type} is a simple type..."
  17275. */
  17276. if (type->contentTypeDef != NULL) {
  17277. /*
  17278. * SPEC (1.1) "the simple type definition corresponding to the
  17279. * <simpleType> among the [children] of <restriction> if there
  17280. * is one;"
  17281. * Note that this "<simpleType> among the [children]" was put
  17282. * into ->contentTypeDef during parsing.
  17283. */
  17284. contentBase = type->contentTypeDef;
  17285. type->contentTypeDef = NULL;
  17286. } else {
  17287. /*
  17288. * (1.2) "...otherwise (<restriction> has no <simpleType>
  17289. * among its [children]), the simple type definition which
  17290. * is the {content type} of the ... base type."
  17291. */
  17292. contentBase = baseType->contentTypeDef;
  17293. }
  17294. /*
  17295. * SPEC
  17296. * "... a simple type definition which restricts the simple
  17297. * type definition identified in clause 1.1 or clause 1.2
  17298. * with a set of facet components"
  17299. *
  17300. * Create the anonymous simple type, which will be the content
  17301. * type of the complex type.
  17302. */
  17303. #ifdef ENABLE_NAMED_LOCALS
  17304. snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
  17305. tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
  17306. content = xmlSchemaAddType(pctxt, pctxt->schema,
  17307. XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
  17308. type->node, 0);
  17309. #else
  17310. content = xmlSchemaAddType(pctxt, pctxt->schema,
  17311. XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
  17312. type->node, 0);
  17313. #endif
  17314. if (content == NULL)
  17315. goto exit_failure;
  17316. /*
  17317. * We will use the same node as for the <complexType>
  17318. * to have it somehow anchored in the schema doc.
  17319. */
  17320. content->type = XML_SCHEMA_TYPE_SIMPLE;
  17321. content->baseType = contentBase;
  17322. /*
  17323. * Move the facets, previously anchored on the
  17324. * complexType during parsing.
  17325. */
  17326. content->facets = type->facets;
  17327. type->facets = NULL;
  17328. content->facetSet = type->facetSet;
  17329. type->facetSet = NULL;
  17330. type->contentTypeDef = content;
  17331. if (WXS_IS_TYPE_NOT_FIXED(contentBase))
  17332. xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
  17333. /*
  17334. * Fixup the newly created type. We don't need to check
  17335. * for circularity here.
  17336. */
  17337. res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
  17338. HFAILURE HERROR
  17339. res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
  17340. HFAILURE HERROR
  17341. } else if ((WXS_IS_COMPLEX(baseType)) &&
  17342. (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  17343. (WXS_IS_RESTRICTION(type))) {
  17344. /*
  17345. * SPEC (2) If <restriction> + base is a mixed <complexType> with
  17346. * an emptiable particle, then a simple type definition which
  17347. * restricts the <restriction>'s <simpleType> child.
  17348. */
  17349. if ((type->contentTypeDef == NULL) ||
  17350. (type->contentTypeDef->baseType == NULL)) {
  17351. /*
  17352. * TODO: Check if this ever happens.
  17353. */
  17354. xmlSchemaPCustomErr(pctxt,
  17355. XML_SCHEMAP_INTERNAL,
  17356. WXS_BASIC_CAST type, NULL,
  17357. "Internal error: xmlSchemaTypeFixup, "
  17358. "complex type '%s': the <simpleContent><restriction> "
  17359. "is missing a <simpleType> child, but was not caught "
  17360. "by xmlSchemaCheckSRCCT()", type->name);
  17361. goto exit_failure;
  17362. }
  17363. } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
  17364. /*
  17365. * SPEC (3) If <extension> + base is <complexType> with
  17366. * <simpleType> content, "...then the {content type} of that
  17367. * complex type definition"
  17368. */
  17369. if (baseType->contentTypeDef == NULL) {
  17370. /*
  17371. * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
  17372. * should have caught this already.
  17373. */
  17374. xmlSchemaPCustomErr(pctxt,
  17375. XML_SCHEMAP_INTERNAL,
  17376. WXS_BASIC_CAST type, NULL,
  17377. "Internal error: xmlSchemaTypeFixup, "
  17378. "complex type '%s': the <extension>ed base type is "
  17379. "a complex type with no simple content type",
  17380. type->name);
  17381. goto exit_failure;
  17382. }
  17383. type->contentTypeDef = baseType->contentTypeDef;
  17384. } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
  17385. /*
  17386. * SPEC (4) <extension> + base is <simpleType>
  17387. * "... then that simple type definition"
  17388. */
  17389. type->contentTypeDef = baseType;
  17390. } else {
  17391. /*
  17392. * TODO: Check if this ever happens.
  17393. */
  17394. xmlSchemaPCustomErr(pctxt,
  17395. XML_SCHEMAP_INTERNAL,
  17396. WXS_BASIC_CAST type, NULL,
  17397. "Internal error: xmlSchemaTypeFixup, "
  17398. "complex type '%s' with <simpleContent>: unhandled "
  17399. "derivation case", type->name);
  17400. goto exit_failure;
  17401. }
  17402. } else {
  17403. int dummySequence = 0;
  17404. xmlSchemaParticlePtr particle =
  17405. (xmlSchemaParticlePtr) type->subtypes;
  17406. /*
  17407. * Corresponds to <complexType><complexContent>...
  17408. *
  17409. * NOTE that the effective mixed was already set during parsing of
  17410. * <complexType> and <complexContent>; its flag value is
  17411. * XML_SCHEMAS_TYPE_MIXED.
  17412. *
  17413. * Compute the "effective content":
  17414. * (2.1.1) + (2.1.2) + (2.1.3)
  17415. */
  17416. if ((particle == NULL) ||
  17417. ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
  17418. ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
  17419. (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
  17420. ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
  17421. (particle->minOccurs == 0))) &&
  17422. ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
  17423. if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
  17424. /*
  17425. * SPEC (2.1.4) "If the `effective mixed` is true, then
  17426. * a particle whose properties are as follows:..."
  17427. *
  17428. * Empty sequence model group with
  17429. * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
  17430. * NOTE that we sill assign it the <complexType> node to
  17431. * somehow anchor it in the doc.
  17432. */
  17433. if ((particle == NULL) ||
  17434. (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
  17435. /*
  17436. * Create the particle.
  17437. */
  17438. particle = xmlSchemaAddParticle(pctxt,
  17439. type->node, 1, 1);
  17440. if (particle == NULL)
  17441. goto exit_failure;
  17442. /*
  17443. * Create the model group.
  17444. */ /* URGENT TODO: avoid adding to pending items. */
  17445. particle->children = (xmlSchemaTreeItemPtr)
  17446. xmlSchemaAddModelGroup(pctxt, pctxt->schema,
  17447. XML_SCHEMA_TYPE_SEQUENCE, type->node);
  17448. if (particle->children == NULL)
  17449. goto exit_failure;
  17450. type->subtypes = (xmlSchemaTypePtr) particle;
  17451. }
  17452. dummySequence = 1;
  17453. type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
  17454. } else {
  17455. /*
  17456. * SPEC (2.1.5) "otherwise empty"
  17457. */
  17458. type->contentType = XML_SCHEMA_CONTENT_EMPTY;
  17459. }
  17460. } else {
  17461. /*
  17462. * SPEC (2.2) "otherwise the particle corresponding to the
  17463. * <all>, <choice>, <group> or <sequence> among the
  17464. * [children]."
  17465. */
  17466. type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
  17467. }
  17468. /*
  17469. * Compute the "content type".
  17470. */
  17471. if (WXS_IS_RESTRICTION(type)) {
  17472. /*
  17473. * SPEC (3.1) "If <restriction>..."
  17474. * (3.1.1) + (3.1.2) */
  17475. if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
  17476. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17477. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17478. }
  17479. } else {
  17480. /*
  17481. * SPEC (3.2) "If <extension>..."
  17482. */
  17483. if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  17484. /*
  17485. * SPEC (3.2.1)
  17486. * "If the `effective content` is empty, then the
  17487. * {content type} of the [...] base ..."
  17488. */
  17489. type->contentType = baseType->contentType;
  17490. type->subtypes = baseType->subtypes;
  17491. /*
  17492. * Fixes bug #347316:
  17493. * This is the case when the base type has a simple
  17494. * type definition as content.
  17495. */
  17496. type->contentTypeDef = baseType->contentTypeDef;
  17497. /*
  17498. * NOTE that the effective mixed is ignored here.
  17499. */
  17500. } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  17501. /*
  17502. * SPEC (3.2.2)
  17503. */
  17504. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17505. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17506. } else {
  17507. /*
  17508. * SPEC (3.2.3)
  17509. */
  17510. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17511. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17512. /*
  17513. * "A model group whose {compositor} is sequence and whose
  17514. * {particles} are..."
  17515. */
  17516. if ((WXS_TYPE_PARTICLE(type) != NULL) &&
  17517. (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
  17518. ((WXS_TYPE_PARTICLE_TERM(type))->type ==
  17519. XML_SCHEMA_TYPE_ALL))
  17520. {
  17521. /*
  17522. * SPEC cos-all-limited (1)
  17523. */
  17524. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17525. /* TODO: error code */
  17526. XML_SCHEMAP_COS_ALL_LIMITED,
  17527. WXS_ITEM_NODE(type), NULL,
  17528. "The type has an 'all' model group in its "
  17529. "{content type} and thus cannot be derived from "
  17530. "a non-empty type, since this would produce a "
  17531. "'sequence' model group containing the 'all' "
  17532. "model group; 'all' model groups are not "
  17533. "allowed to appear inside other model groups",
  17534. NULL, NULL);
  17535. } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
  17536. (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
  17537. ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
  17538. XML_SCHEMA_TYPE_ALL))
  17539. {
  17540. /*
  17541. * SPEC cos-all-limited (1)
  17542. */
  17543. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17544. /* TODO: error code */
  17545. XML_SCHEMAP_COS_ALL_LIMITED,
  17546. WXS_ITEM_NODE(type), NULL,
  17547. "A type cannot be derived by extension from a type "
  17548. "which has an 'all' model group in its "
  17549. "{content type}, since this would produce a "
  17550. "'sequence' model group containing the 'all' "
  17551. "model group; 'all' model groups are not "
  17552. "allowed to appear inside other model groups",
  17553. NULL, NULL);
  17554. } else if (! dummySequence) {
  17555. xmlSchemaTreeItemPtr effectiveContent =
  17556. (xmlSchemaTreeItemPtr) type->subtypes;
  17557. /*
  17558. * Create the particle.
  17559. */
  17560. particle = xmlSchemaAddParticle(pctxt,
  17561. type->node, 1, 1);
  17562. if (particle == NULL)
  17563. goto exit_failure;
  17564. /*
  17565. * Create the "sequence" model group.
  17566. */
  17567. particle->children = (xmlSchemaTreeItemPtr)
  17568. xmlSchemaAddModelGroup(pctxt, pctxt->schema,
  17569. XML_SCHEMA_TYPE_SEQUENCE, type->node);
  17570. if (particle->children == NULL)
  17571. goto exit_failure;
  17572. WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
  17573. /*
  17574. * SPEC "the particle of the {content type} of
  17575. * the ... base ..."
  17576. * Create a duplicate of the base type's particle
  17577. * and assign its "term" to it.
  17578. */
  17579. particle->children->children =
  17580. (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
  17581. type->node,
  17582. ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
  17583. ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
  17584. if (particle->children->children == NULL)
  17585. goto exit_failure;
  17586. particle = (xmlSchemaParticlePtr)
  17587. particle->children->children;
  17588. particle->children =
  17589. ((xmlSchemaParticlePtr) baseType->subtypes)->children;
  17590. /*
  17591. * SPEC "followed by the `effective content`."
  17592. */
  17593. particle->next = effectiveContent;
  17594. /*
  17595. * This all will result in:
  17596. * new-particle
  17597. * --> new-sequence(
  17598. * new-particle
  17599. * --> base-model,
  17600. * this-particle
  17601. * --> this-model
  17602. * )
  17603. */
  17604. } else {
  17605. /*
  17606. * This is the case when there is already an empty
  17607. * <sequence> with minOccurs==maxOccurs==1.
  17608. * Just add the base types's content type.
  17609. * NOTE that, although we miss to add an intermediate
  17610. * <sequence>, this should produce no difference to
  17611. * neither the regex compilation of the content model,
  17612. * nor to the complex type constraints.
  17613. */
  17614. particle->children->children =
  17615. (xmlSchemaTreeItemPtr) baseType->subtypes;
  17616. }
  17617. }
  17618. }
  17619. }
  17620. /*
  17621. * Now fixup attribute uses:
  17622. * - expand attr. group references
  17623. * - intersect attribute wildcards
  17624. * - inherit attribute uses of the base type
  17625. * - inherit or union attr. wildcards if extending
  17626. * - apply attr. use prohibitions if restricting
  17627. */
  17628. res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
  17629. HFAILURE HERROR
  17630. /*
  17631. * Apply the complex type component constraints; this will not
  17632. * check attributes, since this is done in
  17633. * xmlSchemaFixupTypeAttributeUses().
  17634. */
  17635. res = xmlSchemaCheckCTComponent(pctxt, type);
  17636. HFAILURE HERROR
  17637. #ifdef DEBUG_TYPE
  17638. xmlSchemaDebugFixedType(pctxt, type);
  17639. #endif
  17640. if (olderrs != pctxt->nberrors)
  17641. return(pctxt->err);
  17642. else
  17643. return(0);
  17644. exit_error:
  17645. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
  17646. #ifdef DEBUG_TYPE
  17647. xmlSchemaDebugFixedType(pctxt, type);
  17648. #endif
  17649. return(pctxt->err);
  17650. exit_failure:
  17651. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
  17652. #ifdef DEBUG_TYPE
  17653. xmlSchemaDebugFixedType(pctxt, type);
  17654. #endif
  17655. return(-1);
  17656. }
  17657. /**
  17658. * xmlSchemaTypeFixup:
  17659. * @typeDecl: the schema type definition
  17660. * @ctxt: the schema parser context
  17661. *
  17662. * Fixes the content model of the type.
  17663. * URGENT TODO: We need an int result!
  17664. */
  17665. static int
  17666. xmlSchemaTypeFixup(xmlSchemaTypePtr type,
  17667. xmlSchemaAbstractCtxtPtr actxt)
  17668. {
  17669. if (type == NULL)
  17670. return(0);
  17671. if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
  17672. AERROR_INT("xmlSchemaTypeFixup",
  17673. "this function needs a parser context");
  17674. return(-1);
  17675. }
  17676. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17677. return(0);
  17678. if (type->type == XML_SCHEMA_TYPE_COMPLEX)
  17679. return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
  17680. else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
  17681. return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
  17682. return(0);
  17683. }
  17684. /**
  17685. * xmlSchemaCheckFacet:
  17686. * @facet: the facet
  17687. * @typeDecl: the schema type definition
  17688. * @pctxt: the schema parser context or NULL
  17689. * @name: the optional name of the type
  17690. *
  17691. * Checks and computes the values of facets.
  17692. *
  17693. * Returns 0 if valid, a positive error code if not valid and
  17694. * -1 in case of an internal or API error.
  17695. */
  17696. int
  17697. xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
  17698. xmlSchemaTypePtr typeDecl,
  17699. xmlSchemaParserCtxtPtr pctxt,
  17700. const xmlChar * name ATTRIBUTE_UNUSED)
  17701. {
  17702. int ret = 0, ctxtGiven;
  17703. if ((facet == NULL) || (typeDecl == NULL))
  17704. return(-1);
  17705. /*
  17706. * TODO: will the parser context be given if used from
  17707. * the relaxNG module?
  17708. */
  17709. if (pctxt == NULL)
  17710. ctxtGiven = 0;
  17711. else
  17712. ctxtGiven = 1;
  17713. switch (facet->type) {
  17714. case XML_SCHEMA_FACET_MININCLUSIVE:
  17715. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  17716. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  17717. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  17718. case XML_SCHEMA_FACET_ENUMERATION: {
  17719. /*
  17720. * Okay we need to validate the value
  17721. * at that point.
  17722. */
  17723. xmlSchemaTypePtr base;
  17724. /* 4.3.5.5 Constraints on enumeration Schema Components
  17725. * Schema Component Constraint: enumeration valid restriction
  17726. * It is an `error` if any member of {value} is not in the
  17727. * `value space` of {base type definition}.
  17728. *
  17729. * minInclusive, maxInclusive, minExclusive, maxExclusive:
  17730. * The value `must` be in the
  17731. * `value space` of the `base type`.
  17732. */
  17733. /*
  17734. * This function is intended to deliver a compiled value
  17735. * on the facet. In this implementation of XML Schemata the
  17736. * type holding a facet, won't be a built-in type.
  17737. * Thus to ensure that other API
  17738. * calls (relaxng) do work, if the given type is a built-in
  17739. * type, we will assume that the given built-in type *is
  17740. * already* the base type.
  17741. */
  17742. if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
  17743. base = typeDecl->baseType;
  17744. if (base == NULL) {
  17745. PERROR_INT("xmlSchemaCheckFacet",
  17746. "a type user derived type has no base type");
  17747. return (-1);
  17748. }
  17749. } else
  17750. base = typeDecl;
  17751. if (! ctxtGiven) {
  17752. /*
  17753. * A context is needed if called from RelaxNG.
  17754. */
  17755. pctxt = xmlSchemaNewParserCtxt("*");
  17756. if (pctxt == NULL)
  17757. return (-1);
  17758. }
  17759. /*
  17760. * NOTE: This call does not check the content nodes,
  17761. * since they are not available:
  17762. * facet->node is just the node holding the facet
  17763. * definition, *not* the attribute holding the *value*
  17764. * of the facet.
  17765. */
  17766. ret = xmlSchemaVCheckCVCSimpleType(
  17767. ACTXT_CAST pctxt, facet->node, base,
  17768. facet->value, &(facet->val), 1, 1, 0);
  17769. if (ret != 0) {
  17770. if (ret < 0) {
  17771. /* No error message for RelaxNG. */
  17772. if (ctxtGiven) {
  17773. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17774. XML_SCHEMAP_INTERNAL, facet->node, NULL,
  17775. "Internal error: xmlSchemaCheckFacet, "
  17776. "failed to validate the value '%s' of the "
  17777. "facet '%s' against the base type",
  17778. facet->value, xmlSchemaFacetTypeToString(facet->type));
  17779. }
  17780. goto internal_error;
  17781. }
  17782. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17783. /* No error message for RelaxNG. */
  17784. if (ctxtGiven) {
  17785. xmlChar *str = NULL;
  17786. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17787. ret, facet->node, WXS_BASIC_CAST facet,
  17788. "The value '%s' of the facet does not validate "
  17789. "against the base type '%s'",
  17790. facet->value,
  17791. xmlSchemaFormatQName(&str,
  17792. base->targetNamespace, base->name));
  17793. FREE_AND_NULL(str);
  17794. }
  17795. goto exit;
  17796. } else if (facet->val == NULL) {
  17797. if (ctxtGiven) {
  17798. PERROR_INT("xmlSchemaCheckFacet",
  17799. "value was not computed");
  17800. }
  17801. TODO
  17802. }
  17803. break;
  17804. }
  17805. case XML_SCHEMA_FACET_PATTERN:
  17806. facet->regexp = xmlRegexpCompile(facet->value);
  17807. if (facet->regexp == NULL) {
  17808. ret = XML_SCHEMAP_REGEXP_INVALID;
  17809. /* No error message for RelaxNG. */
  17810. if (ctxtGiven) {
  17811. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17812. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17813. "The value '%s' of the facet 'pattern' is not a "
  17814. "valid regular expression",
  17815. facet->value, NULL);
  17816. }
  17817. }
  17818. break;
  17819. case XML_SCHEMA_FACET_TOTALDIGITS:
  17820. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  17821. case XML_SCHEMA_FACET_LENGTH:
  17822. case XML_SCHEMA_FACET_MAXLENGTH:
  17823. case XML_SCHEMA_FACET_MINLENGTH:
  17824. if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
  17825. ret = xmlSchemaValidatePredefinedType(
  17826. xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
  17827. facet->value, &(facet->val));
  17828. } else {
  17829. ret = xmlSchemaValidatePredefinedType(
  17830. xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
  17831. facet->value, &(facet->val));
  17832. }
  17833. if (ret != 0) {
  17834. if (ret < 0) {
  17835. /* No error message for RelaxNG. */
  17836. if (ctxtGiven) {
  17837. PERROR_INT("xmlSchemaCheckFacet",
  17838. "validating facet value");
  17839. }
  17840. goto internal_error;
  17841. }
  17842. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17843. /* No error message for RelaxNG. */
  17844. if (ctxtGiven) {
  17845. /* error code */
  17846. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  17847. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17848. "The value '%s' of the facet '%s' is not a valid '%s'",
  17849. facet->value,
  17850. xmlSchemaFacetTypeToString(facet->type),
  17851. (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
  17852. BAD_CAST "nonNegativeInteger" :
  17853. BAD_CAST "positiveInteger",
  17854. NULL);
  17855. }
  17856. }
  17857. break;
  17858. case XML_SCHEMA_FACET_WHITESPACE:{
  17859. if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
  17860. facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
  17861. } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
  17862. facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
  17863. } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
  17864. facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
  17865. } else {
  17866. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17867. /* No error message for RelaxNG. */
  17868. if (ctxtGiven) {
  17869. /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
  17870. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17871. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17872. "The value '%s' of the facet 'whitespace' is not "
  17873. "valid", facet->value, NULL);
  17874. }
  17875. }
  17876. }
  17877. default:
  17878. break;
  17879. }
  17880. exit:
  17881. if ((! ctxtGiven) && (pctxt != NULL))
  17882. xmlSchemaFreeParserCtxt(pctxt);
  17883. return (ret);
  17884. internal_error:
  17885. if ((! ctxtGiven) && (pctxt != NULL))
  17886. xmlSchemaFreeParserCtxt(pctxt);
  17887. return (-1);
  17888. }
  17889. /**
  17890. * xmlSchemaCheckFacetValues:
  17891. * @typeDecl: the schema type definition
  17892. * @ctxt: the schema parser context
  17893. *
  17894. * Checks the default values types, especially for facets
  17895. */
  17896. static int
  17897. xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
  17898. xmlSchemaParserCtxtPtr pctxt)
  17899. {
  17900. int res, olderrs = pctxt->nberrors;
  17901. const xmlChar *name = typeDecl->name;
  17902. /*
  17903. * NOTE: It is intended to use the facets list, instead
  17904. * of facetSet.
  17905. */
  17906. if (typeDecl->facets != NULL) {
  17907. xmlSchemaFacetPtr facet = typeDecl->facets;
  17908. /*
  17909. * Temporarily assign the "schema" to the validation context
  17910. * of the parser context. This is needed for NOTATION validation.
  17911. */
  17912. if (pctxt->vctxt == NULL) {
  17913. if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
  17914. return(-1);
  17915. }
  17916. pctxt->vctxt->schema = pctxt->schema;
  17917. while (facet != NULL) {
  17918. res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
  17919. HFAILURE
  17920. facet = facet->next;
  17921. }
  17922. pctxt->vctxt->schema = NULL;
  17923. }
  17924. if (olderrs != pctxt->nberrors)
  17925. return(pctxt->err);
  17926. return(0);
  17927. exit_failure:
  17928. return(-1);
  17929. }
  17930. /**
  17931. * xmlSchemaGetCircModelGrDefRef:
  17932. * @ctxtMGroup: the searched model group
  17933. * @selfMGroup: the second searched model group
  17934. * @particle: the first particle
  17935. *
  17936. * This one is intended to be used by
  17937. * xmlSchemaCheckGroupDefCircular only.
  17938. *
  17939. * Returns the particle with the circular model group definition reference,
  17940. * otherwise NULL.
  17941. */
  17942. static xmlSchemaTreeItemPtr
  17943. xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
  17944. xmlSchemaTreeItemPtr particle)
  17945. {
  17946. xmlSchemaTreeItemPtr circ = NULL;
  17947. xmlSchemaTreeItemPtr term;
  17948. xmlSchemaModelGroupDefPtr gdef;
  17949. for (; particle != NULL; particle = particle->next) {
  17950. term = particle->children;
  17951. if (term == NULL)
  17952. continue;
  17953. switch (term->type) {
  17954. case XML_SCHEMA_TYPE_GROUP:
  17955. gdef = (xmlSchemaModelGroupDefPtr) term;
  17956. if (gdef == groupDef)
  17957. return (particle);
  17958. /*
  17959. * Mark this model group definition to avoid infinite
  17960. * recursion on circular references not yet examined.
  17961. */
  17962. if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
  17963. continue;
  17964. if (gdef->children != NULL) {
  17965. gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
  17966. circ = xmlSchemaGetCircModelGrDefRef(groupDef,
  17967. gdef->children->children);
  17968. gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
  17969. if (circ != NULL)
  17970. return (circ);
  17971. }
  17972. break;
  17973. case XML_SCHEMA_TYPE_SEQUENCE:
  17974. case XML_SCHEMA_TYPE_CHOICE:
  17975. case XML_SCHEMA_TYPE_ALL:
  17976. circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
  17977. if (circ != NULL)
  17978. return (circ);
  17979. break;
  17980. default:
  17981. break;
  17982. }
  17983. }
  17984. return (NULL);
  17985. }
  17986. /**
  17987. * xmlSchemaCheckGroupDefCircular:
  17988. * @item: the model group definition
  17989. * @ctxt: the parser context
  17990. * @name: the name
  17991. *
  17992. * Checks for circular references to model group definitions.
  17993. */
  17994. static void
  17995. xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
  17996. xmlSchemaParserCtxtPtr ctxt)
  17997. {
  17998. /*
  17999. * Schema Component Constraint: Model Group Correct
  18000. * 2 Circular groups are disallowed. That is, within the {particles}
  18001. * of a group there must not be at any depth a particle whose {term}
  18002. * is the group itself.
  18003. */
  18004. if ((item == NULL) ||
  18005. (item->type != XML_SCHEMA_TYPE_GROUP) ||
  18006. (item->children == NULL))
  18007. return;
  18008. {
  18009. xmlSchemaTreeItemPtr circ;
  18010. circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
  18011. if (circ != NULL) {
  18012. xmlChar *str = NULL;
  18013. /*
  18014. * TODO: The error report is not adequate: this constraint
  18015. * is defined for model groups but not definitions, but since
  18016. * there cannot be any circular model groups without a model group
  18017. * definition (if not using a construction API), we check those
  18018. * definitions only.
  18019. */
  18020. xmlSchemaPCustomErr(ctxt,
  18021. XML_SCHEMAP_MG_PROPS_CORRECT_2,
  18022. NULL, WXS_ITEM_NODE(circ),
  18023. "Circular reference to the model group definition '%s' "
  18024. "defined", xmlSchemaFormatQName(&str,
  18025. item->targetNamespace, item->name));
  18026. FREE_AND_NULL(str)
  18027. /*
  18028. * NOTE: We will cut the reference to avoid further
  18029. * confusion of the processor. This is a fatal error.
  18030. */
  18031. circ->children = NULL;
  18032. }
  18033. }
  18034. }
  18035. /**
  18036. * xmlSchemaModelGroupToModelGroupDefFixup:
  18037. * @ctxt: the parser context
  18038. * @mg: the model group
  18039. *
  18040. * Assigns the model group of model group definitions to the "term"
  18041. * of the referencing particle.
  18042. * In xmlSchemaResolveModelGroupParticleReferences the model group
  18043. * definitions were assigned to the "term", since needed for the
  18044. * circularity check.
  18045. *
  18046. * Schema Component Constraint:
  18047. * All Group Limited (cos-all-limited) (1.2)
  18048. */
  18049. static void
  18050. xmlSchemaModelGroupToModelGroupDefFixup(
  18051. xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
  18052. xmlSchemaModelGroupPtr mg)
  18053. {
  18054. xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
  18055. while (particle != NULL) {
  18056. if ((WXS_PARTICLE_TERM(particle) == NULL) ||
  18057. ((WXS_PARTICLE_TERM(particle))->type !=
  18058. XML_SCHEMA_TYPE_GROUP))
  18059. {
  18060. particle = WXS_PTC_CAST particle->next;
  18061. continue;
  18062. }
  18063. if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
  18064. /*
  18065. * TODO: Remove the particle.
  18066. */
  18067. WXS_PARTICLE_TERM(particle) = NULL;
  18068. particle = WXS_PTC_CAST particle->next;
  18069. continue;
  18070. }
  18071. /*
  18072. * Assign the model group to the {term} of the particle.
  18073. */
  18074. WXS_PARTICLE_TERM(particle) =
  18075. WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
  18076. particle = WXS_PTC_CAST particle->next;
  18077. }
  18078. }
  18079. /**
  18080. * xmlSchemaCheckAttrGroupCircularRecur:
  18081. * @ctxtGr: the searched attribute group
  18082. * @attr: the current attribute list to be processed
  18083. *
  18084. * This one is intended to be used by
  18085. * xmlSchemaCheckAttrGroupCircular only.
  18086. *
  18087. * Returns the circular attribute group reference, otherwise NULL.
  18088. */
  18089. static xmlSchemaQNameRefPtr
  18090. xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
  18091. xmlSchemaItemListPtr list)
  18092. {
  18093. xmlSchemaAttributeGroupPtr gr;
  18094. xmlSchemaQNameRefPtr ref, circ;
  18095. int i;
  18096. /*
  18097. * We will search for an attribute group reference which
  18098. * references the context attribute group.
  18099. */
  18100. for (i = 0; i < list->nbItems; i++) {
  18101. ref = list->items[i];
  18102. if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
  18103. (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
  18104. (ref->item != NULL))
  18105. {
  18106. gr = WXS_ATTR_GROUP_CAST ref->item;
  18107. if (gr == ctxtGr)
  18108. return(ref);
  18109. if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
  18110. continue;
  18111. /*
  18112. * Mark as visited to avoid infinite recursion on
  18113. * circular references not yet examined.
  18114. */
  18115. if ((gr->attrUses) &&
  18116. (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
  18117. {
  18118. gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
  18119. circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
  18120. (xmlSchemaItemListPtr) gr->attrUses);
  18121. gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
  18122. if (circ != NULL)
  18123. return (circ);
  18124. }
  18125. }
  18126. }
  18127. return (NULL);
  18128. }
  18129. /**
  18130. * xmlSchemaCheckAttrGroupCircular:
  18131. * attrGr: the attribute group definition
  18132. * @ctxt: the parser context
  18133. * @name: the name
  18134. *
  18135. * Checks for circular references of attribute groups.
  18136. */
  18137. static int
  18138. xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
  18139. xmlSchemaParserCtxtPtr ctxt)
  18140. {
  18141. /*
  18142. * Schema Representation Constraint:
  18143. * Attribute Group Definition Representation OK
  18144. * 3 Circular group reference is disallowed outside <redefine>.
  18145. * That is, unless this element information item's parent is
  18146. * <redefine>, then among the [children], if any, there must
  18147. * not be an <attributeGroup> with ref [attribute] which resolves
  18148. * to the component corresponding to this <attributeGroup>. Indirect
  18149. * circularity is also ruled out. That is, when QName resolution
  18150. * (Schema Document) ($3.15.3) is applied to a `QName` arising from
  18151. * any <attributeGroup>s with a ref [attribute] among the [children],
  18152. * it must not be the case that a `QName` is encountered at any depth
  18153. * which resolves to the component corresponding to this <attributeGroup>.
  18154. */
  18155. if (attrGr->attrUses == NULL)
  18156. return(0);
  18157. else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
  18158. return(0);
  18159. else {
  18160. xmlSchemaQNameRefPtr circ;
  18161. circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
  18162. (xmlSchemaItemListPtr) attrGr->attrUses);
  18163. if (circ != NULL) {
  18164. xmlChar *str = NULL;
  18165. /*
  18166. * TODO: Report the referenced attr group as QName.
  18167. */
  18168. xmlSchemaPCustomErr(ctxt,
  18169. XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
  18170. NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
  18171. "Circular reference to the attribute group '%s' "
  18172. "defined", xmlSchemaGetComponentQName(&str, attrGr));
  18173. FREE_AND_NULL(str);
  18174. /*
  18175. * NOTE: We will cut the reference to avoid further
  18176. * confusion of the processor.
  18177. * BADSPEC TODO: The spec should define how to process in this case.
  18178. */
  18179. circ->item = NULL;
  18180. return(ctxt->err);
  18181. }
  18182. }
  18183. return(0);
  18184. }
  18185. static int
  18186. xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
  18187. xmlSchemaAttributeGroupPtr attrGr);
  18188. /**
  18189. * xmlSchemaExpandAttributeGroupRefs:
  18190. * @pctxt: the parser context
  18191. * @node: the node of the component holding the attribute uses
  18192. * @completeWild: the intersected wildcard to be returned
  18193. * @list: the attribute uses
  18194. *
  18195. * Substitutes contained attribute group references
  18196. * for their attribute uses. Wildcards are intersected.
  18197. * Attribute use prohibitions are removed from the list
  18198. * and returned via the @prohibs list.
  18199. * Pointlessness of attr. prohibs, if a matching attr. decl
  18200. * is existent a well, are checked.
  18201. */
  18202. static int
  18203. xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
  18204. xmlSchemaBasicItemPtr item,
  18205. xmlSchemaWildcardPtr *completeWild,
  18206. xmlSchemaItemListPtr list,
  18207. xmlSchemaItemListPtr prohibs)
  18208. {
  18209. xmlSchemaAttributeGroupPtr gr;
  18210. xmlSchemaAttributeUsePtr use;
  18211. xmlSchemaItemListPtr sublist;
  18212. int i, j;
  18213. int created = (*completeWild == NULL) ? 0 : 1;
  18214. if (prohibs)
  18215. prohibs->nbItems = 0;
  18216. for (i = 0; i < list->nbItems; i++) {
  18217. use = list->items[i];
  18218. if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
  18219. if (prohibs == NULL) {
  18220. PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
  18221. "unexpected attr prohibition found");
  18222. return(-1);
  18223. }
  18224. /*
  18225. * Remove from attribute uses.
  18226. */
  18227. if (xmlSchemaItemListRemove(list, i) == -1)
  18228. return(-1);
  18229. i--;
  18230. /*
  18231. * Note that duplicate prohibitions were already
  18232. * handled at parsing time.
  18233. */
  18234. /*
  18235. * Add to list of prohibitions.
  18236. */
  18237. xmlSchemaItemListAddSize(prohibs, 2, use);
  18238. continue;
  18239. }
  18240. if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
  18241. ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
  18242. {
  18243. if ((WXS_QNAME_CAST use)->item == NULL)
  18244. return(-1);
  18245. gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
  18246. /*
  18247. * Expand the referenced attr. group.
  18248. * TODO: remove this, this is done in a previous step, so
  18249. * already done here.
  18250. */
  18251. if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
  18252. if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
  18253. return(-1);
  18254. }
  18255. /*
  18256. * Build the 'complete' wildcard; i.e. intersect multiple
  18257. * wildcards.
  18258. */
  18259. if (gr->attributeWildcard != NULL) {
  18260. if (*completeWild == NULL) {
  18261. *completeWild = gr->attributeWildcard;
  18262. } else {
  18263. if (! created) {
  18264. xmlSchemaWildcardPtr tmpWild;
  18265. /*
  18266. * Copy the first encountered wildcard as context,
  18267. * except for the annotation.
  18268. *
  18269. * Although the complete wildcard might not correspond
  18270. * to any node in the schema, we will anchor it on
  18271. * the node of the owner component.
  18272. */
  18273. tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema,
  18274. XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
  18275. WXS_ITEM_NODE(item));
  18276. if (tmpWild == NULL)
  18277. return(-1);
  18278. if (xmlSchemaCloneWildcardNsConstraints(pctxt,
  18279. tmpWild, *completeWild) == -1)
  18280. return (-1);
  18281. tmpWild->processContents = (*completeWild)->processContents;
  18282. *completeWild = tmpWild;
  18283. created = 1;
  18284. }
  18285. if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
  18286. gr->attributeWildcard) == -1)
  18287. return(-1);
  18288. }
  18289. }
  18290. /*
  18291. * Just remove the reference if the referenced group does not
  18292. * contain any attribute uses.
  18293. */
  18294. sublist = ((xmlSchemaItemListPtr) gr->attrUses);
  18295. if ((sublist == NULL) || sublist->nbItems == 0) {
  18296. if (xmlSchemaItemListRemove(list, i) == -1)
  18297. return(-1);
  18298. i--;
  18299. continue;
  18300. }
  18301. /*
  18302. * Add the attribute uses.
  18303. */
  18304. list->items[i] = sublist->items[0];
  18305. if (sublist->nbItems != 1) {
  18306. for (j = 1; j < sublist->nbItems; j++) {
  18307. i++;
  18308. if (xmlSchemaItemListInsert(list,
  18309. sublist->items[j], i) == -1)
  18310. return(-1);
  18311. }
  18312. }
  18313. }
  18314. }
  18315. /*
  18316. * Handle pointless prohibitions of declared attributes.
  18317. */
  18318. if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
  18319. xmlSchemaAttributeUseProhibPtr prohib;
  18320. for (i = prohibs->nbItems -1; i >= 0; i--) {
  18321. prohib = prohibs->items[i];
  18322. for (j = 0; j < list->nbItems; j++) {
  18323. use = list->items[j];
  18324. if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
  18325. (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
  18326. {
  18327. xmlChar *str = NULL;
  18328. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  18329. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  18330. prohib->node, NULL,
  18331. "Skipping pointless attribute use prohibition "
  18332. "'%s', since a corresponding attribute use "
  18333. "exists already in the type definition",
  18334. xmlSchemaFormatQName(&str,
  18335. prohib->targetNamespace, prohib->name),
  18336. NULL, NULL);
  18337. FREE_AND_NULL(str);
  18338. /*
  18339. * Remove the prohibition.
  18340. */
  18341. if (xmlSchemaItemListRemove(prohibs, i) == -1)
  18342. return(-1);
  18343. break;
  18344. }
  18345. }
  18346. }
  18347. }
  18348. return(0);
  18349. }
  18350. /**
  18351. * xmlSchemaAttributeGroupExpandRefs:
  18352. * @pctxt: the parser context
  18353. * @attrGr: the attribute group definition
  18354. *
  18355. * Computation of:
  18356. * {attribute uses} property
  18357. * {attribute wildcard} property
  18358. *
  18359. * Substitutes contained attribute group references
  18360. * for their attribute uses. Wildcards are intersected.
  18361. */
  18362. static int
  18363. xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
  18364. xmlSchemaAttributeGroupPtr attrGr)
  18365. {
  18366. if ((attrGr->attrUses == NULL) ||
  18367. (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
  18368. return(0);
  18369. attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
  18370. if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
  18371. &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
  18372. return(-1);
  18373. return(0);
  18374. }
  18375. /**
  18376. * xmlSchemaAttributeGroupExpandRefs:
  18377. * @pctxt: the parser context
  18378. * @attrGr: the attribute group definition
  18379. *
  18380. * Substitutes contained attribute group references
  18381. * for their attribute uses. Wildcards are intersected.
  18382. *
  18383. * Schema Component Constraint:
  18384. * Attribute Group Definition Properties Correct (ag-props-correct)
  18385. */
  18386. static int
  18387. xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18388. xmlSchemaAttributeGroupPtr attrGr)
  18389. {
  18390. /*
  18391. * SPEC ag-props-correct
  18392. * (1) "The values of the properties of an attribute group definition
  18393. * must be as described in the property tableau in The Attribute
  18394. * Group Definition Schema Component ($3.6.1), modulo the impact of
  18395. * Missing Sub-components ($5.3);"
  18396. */
  18397. if ((attrGr->attrUses != NULL) &&
  18398. (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
  18399. {
  18400. xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
  18401. xmlSchemaAttributeUsePtr use, tmp;
  18402. int i, j, hasId = 0;
  18403. for (i = uses->nbItems -1; i >= 0; i--) {
  18404. use = uses->items[i];
  18405. /*
  18406. * SPEC ag-props-correct
  18407. * (2) "Two distinct members of the {attribute uses} must not have
  18408. * {attribute declaration}s both of whose {name}s match and whose
  18409. * {target namespace}s are identical."
  18410. */
  18411. if (i > 0) {
  18412. for (j = i -1; j >= 0; j--) {
  18413. tmp = uses->items[j];
  18414. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  18415. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  18416. (WXS_ATTRUSE_DECL_TNS(use) ==
  18417. WXS_ATTRUSE_DECL_TNS(tmp)))
  18418. {
  18419. xmlChar *str = NULL;
  18420. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18421. XML_SCHEMAP_AG_PROPS_CORRECT,
  18422. attrGr->node, WXS_BASIC_CAST attrGr,
  18423. "Duplicate %s",
  18424. xmlSchemaGetComponentDesignation(&str, use),
  18425. NULL);
  18426. FREE_AND_NULL(str);
  18427. /*
  18428. * Remove the duplicate.
  18429. */
  18430. if (xmlSchemaItemListRemove(uses, i) == -1)
  18431. return(-1);
  18432. goto next_use;
  18433. }
  18434. }
  18435. }
  18436. /*
  18437. * SPEC ag-props-correct
  18438. * (3) "Two distinct members of the {attribute uses} must not have
  18439. * {attribute declaration}s both of whose {type definition}s are or
  18440. * are derived from ID."
  18441. * TODO: Does 'derived' include member-types of unions?
  18442. */
  18443. if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
  18444. if (xmlSchemaIsDerivedFromBuiltInType(
  18445. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  18446. {
  18447. if (hasId) {
  18448. xmlChar *str = NULL;
  18449. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18450. XML_SCHEMAP_AG_PROPS_CORRECT,
  18451. attrGr->node, WXS_BASIC_CAST attrGr,
  18452. "There must not exist more than one attribute "
  18453. "declaration of type 'xs:ID' "
  18454. "(or derived from 'xs:ID'). The %s violates this "
  18455. "constraint",
  18456. xmlSchemaGetComponentDesignation(&str, use),
  18457. NULL);
  18458. FREE_AND_NULL(str);
  18459. if (xmlSchemaItemListRemove(uses, i) == -1)
  18460. return(-1);
  18461. }
  18462. hasId = 1;
  18463. }
  18464. }
  18465. next_use: {}
  18466. }
  18467. }
  18468. return(0);
  18469. }
  18470. /**
  18471. * xmlSchemaResolveAttrGroupReferences:
  18472. * @attrgrpDecl: the schema attribute definition
  18473. * @ctxt: the schema parser context
  18474. * @name: the attribute name
  18475. *
  18476. * Resolves references to attribute group definitions.
  18477. */
  18478. static int
  18479. xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
  18480. xmlSchemaParserCtxtPtr ctxt)
  18481. {
  18482. xmlSchemaAttributeGroupPtr group;
  18483. if (ref->item != NULL)
  18484. return(0);
  18485. group = xmlSchemaGetAttributeGroup(ctxt->schema,
  18486. ref->name,
  18487. ref->targetNamespace);
  18488. if (group == NULL) {
  18489. xmlSchemaPResCompAttrErr(ctxt,
  18490. XML_SCHEMAP_SRC_RESOLVE,
  18491. NULL, ref->node,
  18492. "ref", ref->name, ref->targetNamespace,
  18493. ref->itemType, NULL);
  18494. return(ctxt->err);
  18495. }
  18496. ref->item = WXS_BASIC_CAST group;
  18497. return(0);
  18498. }
  18499. /**
  18500. * xmlSchemaCheckAttrPropsCorrect:
  18501. * @item: an schema attribute declaration/use
  18502. * @ctxt: a schema parser context
  18503. * @name: the name of the attribute
  18504. *
  18505. *
  18506. * Schema Component Constraint:
  18507. * Attribute Declaration Properties Correct (a-props-correct)
  18508. *
  18509. * Validates the value constraints of an attribute declaration/use.
  18510. * NOTE that this needs the simple type definitions to be already
  18511. * built and checked.
  18512. */
  18513. static int
  18514. xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18515. xmlSchemaAttributePtr attr)
  18516. {
  18517. /*
  18518. * SPEC a-props-correct (1)
  18519. * "The values of the properties of an attribute declaration must
  18520. * be as described in the property tableau in The Attribute
  18521. * Declaration Schema Component ($3.2.1), modulo the impact of
  18522. * Missing Sub-components ($5.3)."
  18523. */
  18524. if (WXS_ATTR_TYPEDEF(attr) == NULL)
  18525. return(0);
  18526. if (attr->defValue != NULL) {
  18527. int ret;
  18528. /*
  18529. * SPEC a-props-correct (3)
  18530. * "If the {type definition} is or is derived from ID then there
  18531. * must not be a {value constraint}."
  18532. */
  18533. if (xmlSchemaIsDerivedFromBuiltInType(
  18534. WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
  18535. {
  18536. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18537. XML_SCHEMAP_A_PROPS_CORRECT_3,
  18538. NULL, WXS_BASIC_CAST attr,
  18539. "Value constraints are not allowed if the type definition "
  18540. "is or is derived from xs:ID",
  18541. NULL, NULL);
  18542. return(pctxt->err);
  18543. }
  18544. /*
  18545. * SPEC a-props-correct (2)
  18546. * "if there is a {value constraint}, the canonical lexical
  18547. * representation of its value must be `valid` with respect
  18548. * to the {type definition} as defined in String Valid ($3.14.4)."
  18549. * TODO: Don't care about the *canonical* stuff here, this requirement
  18550. * will be removed in WXS 1.1 anyway.
  18551. */
  18552. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
  18553. attr->node, WXS_ATTR_TYPEDEF(attr),
  18554. attr->defValue, &(attr->defVal),
  18555. 1, 1, 0);
  18556. if (ret != 0) {
  18557. if (ret < 0) {
  18558. PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
  18559. "calling xmlSchemaVCheckCVCSimpleType()");
  18560. return(-1);
  18561. }
  18562. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18563. XML_SCHEMAP_A_PROPS_CORRECT_2,
  18564. NULL, WXS_BASIC_CAST attr,
  18565. "The value of the value constraint is not valid",
  18566. NULL, NULL);
  18567. return(pctxt->err);
  18568. }
  18569. }
  18570. return(0);
  18571. }
  18572. static xmlSchemaElementPtr
  18573. xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
  18574. xmlSchemaElementPtr ancestor)
  18575. {
  18576. xmlSchemaElementPtr ret;
  18577. if (WXS_SUBST_HEAD(ancestor) == NULL)
  18578. return (NULL);
  18579. if (WXS_SUBST_HEAD(ancestor) == elemDecl)
  18580. return (ancestor);
  18581. if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
  18582. return (NULL);
  18583. WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
  18584. ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
  18585. WXS_SUBST_HEAD(ancestor));
  18586. WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
  18587. return (ret);
  18588. }
  18589. /**
  18590. * xmlSchemaCheckElemPropsCorrect:
  18591. * @ctxt: a schema parser context
  18592. * @decl: the element declaration
  18593. * @name: the name of the attribute
  18594. *
  18595. * Schema Component Constraint:
  18596. * Element Declaration Properties Correct (e-props-correct)
  18597. *
  18598. * STATUS:
  18599. * missing: (6)
  18600. */
  18601. static int
  18602. xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18603. xmlSchemaElementPtr elemDecl)
  18604. {
  18605. int ret = 0;
  18606. xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
  18607. /*
  18608. * SPEC (1) "The values of the properties of an element declaration
  18609. * must be as described in the property tableau in The Element
  18610. * Declaration Schema Component ($3.3.1), modulo the impact of Missing
  18611. * Sub-components ($5.3)."
  18612. */
  18613. if (WXS_SUBST_HEAD(elemDecl) != NULL) {
  18614. xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
  18615. xmlSchemaCheckElementDeclComponent(head, pctxt);
  18616. /*
  18617. * SPEC (3) "If there is a non-`absent` {substitution group
  18618. * affiliation}, then {scope} must be global."
  18619. */
  18620. if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
  18621. xmlSchemaPCustomErr(pctxt,
  18622. XML_SCHEMAP_E_PROPS_CORRECT_3,
  18623. WXS_BASIC_CAST elemDecl, NULL,
  18624. "Only global element declarations can have a "
  18625. "substitution group affiliation", NULL);
  18626. ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
  18627. }
  18628. /*
  18629. * TODO: SPEC (6) "Circular substitution groups are disallowed.
  18630. * That is, it must not be possible to return to an element declaration
  18631. * by repeatedly following the {substitution group affiliation}
  18632. * property."
  18633. */
  18634. if (head == elemDecl)
  18635. circ = head;
  18636. else if (WXS_SUBST_HEAD(head) != NULL)
  18637. circ = xmlSchemaCheckSubstGroupCircular(head, head);
  18638. else
  18639. circ = NULL;
  18640. if (circ != NULL) {
  18641. xmlChar *strA = NULL, *strB = NULL;
  18642. xmlSchemaPCustomErrExt(pctxt,
  18643. XML_SCHEMAP_E_PROPS_CORRECT_6,
  18644. WXS_BASIC_CAST circ, NULL,
  18645. "The element declaration '%s' defines a circular "
  18646. "substitution group to element declaration '%s'",
  18647. xmlSchemaGetComponentQName(&strA, circ),
  18648. xmlSchemaGetComponentQName(&strB, head),
  18649. NULL);
  18650. FREE_AND_NULL(strA)
  18651. FREE_AND_NULL(strB)
  18652. ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
  18653. }
  18654. /*
  18655. * SPEC (4) "If there is a {substitution group affiliation},
  18656. * the {type definition}
  18657. * of the element declaration must be validly derived from the {type
  18658. * definition} of the {substitution group affiliation}, given the value
  18659. * of the {substitution group exclusions} of the {substitution group
  18660. * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
  18661. * (if the {type definition} is complex) or as defined in
  18662. * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
  18663. * simple)."
  18664. *
  18665. * NOTE: {substitution group exclusions} means the values of the
  18666. * attribute "final".
  18667. */
  18668. if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
  18669. int set = 0;
  18670. if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
  18671. set |= SUBSET_EXTENSION;
  18672. if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
  18673. set |= SUBSET_RESTRICTION;
  18674. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
  18675. WXS_ELEM_TYPEDEF(head), set) != 0) {
  18676. xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
  18677. ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
  18678. xmlSchemaPCustomErrExt(pctxt,
  18679. XML_SCHEMAP_E_PROPS_CORRECT_4,
  18680. WXS_BASIC_CAST elemDecl, NULL,
  18681. "The type definition '%s' was "
  18682. "either rejected by the substitution group "
  18683. "affiliation '%s', or not validly derived from its type "
  18684. "definition '%s'",
  18685. xmlSchemaGetComponentQName(&strA, typeDef),
  18686. xmlSchemaGetComponentQName(&strB, head),
  18687. xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
  18688. FREE_AND_NULL(strA)
  18689. FREE_AND_NULL(strB)
  18690. FREE_AND_NULL(strC)
  18691. }
  18692. }
  18693. }
  18694. /*
  18695. * SPEC (5) "If the {type definition} or {type definition}'s
  18696. * {content type}
  18697. * is or is derived from ID then there must not be a {value constraint}.
  18698. * Note: The use of ID as a type definition for elements goes beyond
  18699. * XML 1.0, and should be avoided if backwards compatibility is desired"
  18700. */
  18701. if ((elemDecl->value != NULL) &&
  18702. ((WXS_IS_SIMPLE(typeDef) &&
  18703. xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
  18704. (WXS_IS_COMPLEX(typeDef) &&
  18705. WXS_HAS_SIMPLE_CONTENT(typeDef) &&
  18706. xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
  18707. XML_SCHEMAS_ID)))) {
  18708. ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
  18709. xmlSchemaPCustomErr(pctxt,
  18710. XML_SCHEMAP_E_PROPS_CORRECT_5,
  18711. WXS_BASIC_CAST elemDecl, NULL,
  18712. "The type definition (or type definition's content type) is or "
  18713. "is derived from ID; value constraints are not allowed in "
  18714. "conjunction with such a type definition", NULL);
  18715. } else if (elemDecl->value != NULL) {
  18716. int vcret;
  18717. xmlNodePtr node = NULL;
  18718. /*
  18719. * SPEC (2) "If there is a {value constraint}, the canonical lexical
  18720. * representation of its value must be `valid` with respect to the
  18721. * {type definition} as defined in Element Default Valid (Immediate)
  18722. * ($3.3.6)."
  18723. */
  18724. if (typeDef == NULL) {
  18725. xmlSchemaPErr(pctxt, elemDecl->node,
  18726. XML_SCHEMAP_INTERNAL,
  18727. "Internal error: xmlSchemaCheckElemPropsCorrect, "
  18728. "type is missing... skipping validation of "
  18729. "the value constraint", NULL, NULL);
  18730. return (-1);
  18731. }
  18732. if (elemDecl->node != NULL) {
  18733. if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
  18734. node = (xmlNodePtr) xmlHasProp(elemDecl->node,
  18735. BAD_CAST "fixed");
  18736. else
  18737. node = (xmlNodePtr) xmlHasProp(elemDecl->node,
  18738. BAD_CAST "default");
  18739. }
  18740. vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
  18741. typeDef, elemDecl->value, &(elemDecl->defVal));
  18742. if (vcret != 0) {
  18743. if (vcret < 0) {
  18744. PERROR_INT("xmlSchemaElemCheckValConstr",
  18745. "failed to validate the value constraint of an "
  18746. "element declaration");
  18747. return (-1);
  18748. }
  18749. return (vcret);
  18750. }
  18751. }
  18752. return (ret);
  18753. }
  18754. /**
  18755. * xmlSchemaCheckElemSubstGroup:
  18756. * @ctxt: a schema parser context
  18757. * @decl: the element declaration
  18758. * @name: the name of the attribute
  18759. *
  18760. * Schema Component Constraint:
  18761. * Substitution Group (cos-equiv-class)
  18762. *
  18763. * In Libxml2 the subst. groups will be precomputed, in terms of that
  18764. * a list will be built for each subst. group head, holding all direct
  18765. * referents to this head.
  18766. * NOTE that this function needs:
  18767. * 1. circular subst. groups to be checked beforehand
  18768. * 2. the declaration's type to be derived from the head's type
  18769. *
  18770. * STATUS:
  18771. *
  18772. */
  18773. static void
  18774. xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
  18775. xmlSchemaElementPtr elemDecl)
  18776. {
  18777. if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
  18778. /* SPEC (1) "Its {abstract} is false." */
  18779. (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
  18780. return;
  18781. {
  18782. xmlSchemaElementPtr head;
  18783. xmlSchemaTypePtr headType, type;
  18784. int set, methSet;
  18785. /*
  18786. * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
  18787. * {disallowed substitutions} as the blocking constraint, as defined in
  18788. * Substitution Group OK (Transitive) ($3.3.6)."
  18789. */
  18790. for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
  18791. head = WXS_SUBST_HEAD(head)) {
  18792. set = 0;
  18793. methSet = 0;
  18794. /*
  18795. * The blocking constraints.
  18796. */
  18797. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
  18798. continue;
  18799. headType = head->subtypes;
  18800. type = elemDecl->subtypes;
  18801. if (headType == type)
  18802. goto add_member;
  18803. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
  18804. set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18805. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
  18806. set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18807. /*
  18808. * SPEC: Substitution Group OK (Transitive) (2.3)
  18809. * "The set of all {derivation method}s involved in the
  18810. * derivation of D's {type definition} from C's {type definition}
  18811. * does not intersect with the union of the blocking constraint,
  18812. * C's {prohibited substitutions} (if C is complex, otherwise the
  18813. * empty set) and the {prohibited substitutions} (respectively the
  18814. * empty set) of any intermediate {type definition}s in the
  18815. * derivation of D's {type definition} from C's {type definition}."
  18816. */
  18817. /*
  18818. * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
  18819. * subst.head axis, the methSet does not need to be computed for
  18820. * the full depth over and over.
  18821. */
  18822. /*
  18823. * The set of all {derivation method}s involved in the derivation
  18824. */
  18825. while ((type != NULL) && (type != headType)) {
  18826. if ((WXS_IS_EXTENSION(type)) &&
  18827. ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18828. methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18829. if (WXS_IS_RESTRICTION(type) &&
  18830. ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18831. methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18832. type = type->baseType;
  18833. }
  18834. /*
  18835. * The {prohibited substitutions} of all intermediate types +
  18836. * the head's type.
  18837. */
  18838. type = elemDecl->subtypes->baseType;
  18839. while (type != NULL) {
  18840. if (WXS_IS_COMPLEX(type)) {
  18841. if ((type->flags &
  18842. XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
  18843. ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
  18844. set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18845. if ((type->flags &
  18846. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
  18847. ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18848. set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18849. } else
  18850. break;
  18851. if (type == headType)
  18852. break;
  18853. type = type->baseType;
  18854. }
  18855. if ((set != 0) &&
  18856. (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
  18857. (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
  18858. ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
  18859. (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
  18860. continue;
  18861. }
  18862. add_member:
  18863. xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
  18864. if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
  18865. head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
  18866. }
  18867. }
  18868. }
  18869. #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
  18870. /**
  18871. * xmlSchemaCheckElementDeclComponent
  18872. * @pctxt: the schema parser context
  18873. * @ctxtComponent: the context component (an element declaration)
  18874. * @ctxtParticle: the first particle of the context component
  18875. * @searchParticle: the element declaration particle to be analysed
  18876. *
  18877. * Schema Component Constraint: Element Declarations Consistent
  18878. */
  18879. static int
  18880. xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
  18881. xmlSchemaBasicItemPtr ctxtComponent,
  18882. xmlSchemaParticlePtr ctxtParticle,
  18883. xmlSchemaParticlePtr searchParticle,
  18884. xmlSchemaParticlePtr curParticle,
  18885. int search)
  18886. {
  18887. return(0);
  18888. int ret = 0;
  18889. xmlSchemaParticlePtr cur = curParticle;
  18890. if (curParticle == NULL) {
  18891. return(0);
  18892. }
  18893. if (WXS_PARTICLE_TERM(curParticle) == NULL) {
  18894. /*
  18895. * Just return in this case. A missing "term" of the particle
  18896. * might arise due to an invalid "term" component.
  18897. */
  18898. return(0);
  18899. }
  18900. while (cur != NULL) {
  18901. switch (WXS_PARTICLE_TERM(cur)->type) {
  18902. case XML_SCHEMA_TYPE_ANY:
  18903. break;
  18904. case XML_SCHEMA_TYPE_ELEMENT:
  18905. if (search == 0) {
  18906. ret = xmlSchemaCheckElementDeclConsistent(pctxt,
  18907. ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
  18908. if (ret != 0)
  18909. return(ret);
  18910. } else {
  18911. xmlSchemaElementPtr elem =
  18912. WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
  18913. /*
  18914. * SPEC Element Declarations Consistent:
  18915. * "If the {particles} contains, either directly,
  18916. * indirectly (that is, within the {particles} of a
  18917. * contained model group, recursively) or `implicitly`
  18918. * two or more element declaration particles with
  18919. * the same {name} and {target namespace}, then
  18920. * all their type definitions must be the same
  18921. * top-level definition [...]"
  18922. */
  18923. if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
  18924. WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
  18925. xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
  18926. WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
  18927. {
  18928. xmlChar *strA = NULL, *strB = NULL;
  18929. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18930. /* TODO: error code */
  18931. XML_SCHEMAP_COS_NONAMBIG,
  18932. WXS_ITEM_NODE(cur), NULL,
  18933. "In the content model of %s, there are multiple "
  18934. "element declarations for '%s' with different "
  18935. "type definitions",
  18936. xmlSchemaGetComponentDesignation(&strA,
  18937. ctxtComponent),
  18938. xmlSchemaFormatQName(&strB,
  18939. WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
  18940. WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
  18941. FREE_AND_NULL(strA);
  18942. FREE_AND_NULL(strB);
  18943. return(XML_SCHEMAP_COS_NONAMBIG);
  18944. }
  18945. }
  18946. break;
  18947. case XML_SCHEMA_TYPE_SEQUENCE: {
  18948. break;
  18949. }
  18950. case XML_SCHEMA_TYPE_CHOICE:{
  18951. /*
  18952. xmlSchemaTreeItemPtr sub;
  18953. sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
  18954. while (sub != NULL) {
  18955. ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
  18956. ctxtParticle, ctxtElem);
  18957. if (ret != 0)
  18958. return(ret);
  18959. sub = sub->next;
  18960. }
  18961. */
  18962. break;
  18963. }
  18964. case XML_SCHEMA_TYPE_ALL:
  18965. break;
  18966. case XML_SCHEMA_TYPE_GROUP:
  18967. break;
  18968. default:
  18969. xmlSchemaInternalErr2(ACTXT_CAST pctxt,
  18970. "xmlSchemaCheckElementDeclConsistent",
  18971. "found unexpected term of type '%s' in content model",
  18972. WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
  18973. return(-1);
  18974. }
  18975. cur = (xmlSchemaParticlePtr) cur->next;
  18976. }
  18977. exit:
  18978. return(ret);
  18979. }
  18980. #endif
  18981. /**
  18982. * xmlSchemaCheckElementDeclComponent
  18983. * @item: an schema element declaration/particle
  18984. * @ctxt: a schema parser context
  18985. * @name: the name of the attribute
  18986. *
  18987. * Validates the value constraints of an element declaration.
  18988. * Adds substitution group members.
  18989. */
  18990. static void
  18991. xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
  18992. xmlSchemaParserCtxtPtr ctxt)
  18993. {
  18994. if (elemDecl == NULL)
  18995. return;
  18996. if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
  18997. return;
  18998. elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
  18999. if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
  19000. /*
  19001. * Adds substitution group members.
  19002. */
  19003. xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
  19004. }
  19005. }
  19006. /**
  19007. * xmlSchemaResolveModelGroupParticleReferences:
  19008. * @particle: a particle component
  19009. * @ctxt: a parser context
  19010. *
  19011. * Resolves references of a model group's {particles} to
  19012. * model group definitions and to element declarations.
  19013. */
  19014. static void
  19015. xmlSchemaResolveModelGroupParticleReferences(
  19016. xmlSchemaParserCtxtPtr ctxt,
  19017. xmlSchemaModelGroupPtr mg)
  19018. {
  19019. xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
  19020. xmlSchemaQNameRefPtr ref;
  19021. xmlSchemaBasicItemPtr refItem;
  19022. /*
  19023. * URGENT TODO: Test this.
  19024. */
  19025. while (particle != NULL) {
  19026. if ((WXS_PARTICLE_TERM(particle) == NULL) ||
  19027. ((WXS_PARTICLE_TERM(particle))->type !=
  19028. XML_SCHEMA_EXTRA_QNAMEREF))
  19029. {
  19030. goto next_particle;
  19031. }
  19032. ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
  19033. /*
  19034. * Resolve the reference.
  19035. * NULL the {term} by default.
  19036. */
  19037. particle->children = NULL;
  19038. refItem = xmlSchemaGetNamedComponent(ctxt->schema,
  19039. ref->itemType, ref->name, ref->targetNamespace);
  19040. if (refItem == NULL) {
  19041. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  19042. NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
  19043. ref->targetNamespace, ref->itemType, NULL);
  19044. /* TODO: remove the particle. */
  19045. goto next_particle;
  19046. }
  19047. if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
  19048. if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
  19049. /* TODO: remove the particle. */
  19050. goto next_particle;
  19051. /*
  19052. * NOTE that we will assign the model group definition
  19053. * itself to the "term" of the particle. This will ease
  19054. * the check for circular model group definitions. After
  19055. * that the "term" will be assigned the model group of the
  19056. * model group definition.
  19057. */
  19058. if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
  19059. XML_SCHEMA_TYPE_ALL) {
  19060. /*
  19061. * SPEC cos-all-limited (1)
  19062. * SPEC cos-all-limited (1.2)
  19063. * "It appears only as the value of one or both of the
  19064. * following properties:"
  19065. * (1.1) "the {model group} property of a model group
  19066. * definition."
  19067. * (1.2) "the {term} property of a particle [... of] the "
  19068. * {content type} of a complex type definition."
  19069. */
  19070. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  19071. /* TODO: error code */
  19072. XML_SCHEMAP_COS_ALL_LIMITED,
  19073. WXS_ITEM_NODE(particle), NULL,
  19074. "A model group definition is referenced, but "
  19075. "it contains an 'all' model group, which "
  19076. "cannot be contained by model groups",
  19077. NULL, NULL);
  19078. /* TODO: remove the particle. */
  19079. goto next_particle;
  19080. }
  19081. particle->children = (xmlSchemaTreeItemPtr) refItem;
  19082. } else {
  19083. /*
  19084. * TODO: Are referenced element declarations the only
  19085. * other components we expect here?
  19086. */
  19087. particle->children = (xmlSchemaTreeItemPtr) refItem;
  19088. }
  19089. next_particle:
  19090. particle = WXS_PTC_CAST particle->next;
  19091. }
  19092. }
  19093. static int
  19094. xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
  19095. xmlSchemaValPtr y)
  19096. {
  19097. xmlSchemaTypePtr tx, ty, ptx, pty;
  19098. int ret;
  19099. while (x != NULL) {
  19100. /* Same types. */
  19101. tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
  19102. ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
  19103. ptx = xmlSchemaGetPrimitiveType(tx);
  19104. pty = xmlSchemaGetPrimitiveType(ty);
  19105. /*
  19106. * (1) if a datatype T' is `derived` by `restriction` from an
  19107. * atomic datatype T then the `value space` of T' is a subset of
  19108. * the `value space` of T. */
  19109. /*
  19110. * (2) if datatypes T' and T'' are `derived` by `restriction`
  19111. * from a common atomic ancestor T then the `value space`s of T'
  19112. * and T'' may overlap.
  19113. */
  19114. if (ptx != pty)
  19115. return(0);
  19116. /*
  19117. * We assume computed values to be normalized, so do a fast
  19118. * string comparison for string based types.
  19119. */
  19120. if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
  19121. WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
  19122. if (! xmlStrEqual(
  19123. xmlSchemaValueGetAsString(x),
  19124. xmlSchemaValueGetAsString(y)))
  19125. return (0);
  19126. } else {
  19127. ret = xmlSchemaCompareValuesWhtsp(
  19128. x, XML_SCHEMA_WHITESPACE_PRESERVE,
  19129. y, XML_SCHEMA_WHITESPACE_PRESERVE);
  19130. if (ret == -2)
  19131. return(-1);
  19132. if (ret != 0)
  19133. return(0);
  19134. }
  19135. /*
  19136. * Lists.
  19137. */
  19138. x = xmlSchemaValueGetNext(x);
  19139. if (x != NULL) {
  19140. y = xmlSchemaValueGetNext(y);
  19141. if (y == NULL)
  19142. return (0);
  19143. } else if (xmlSchemaValueGetNext(y) != NULL)
  19144. return (0);
  19145. else
  19146. return (1);
  19147. }
  19148. return (0);
  19149. }
  19150. /**
  19151. * xmlSchemaResolveAttrUseReferences:
  19152. * @item: an attribute use
  19153. * @ctxt: a parser context
  19154. *
  19155. * Resolves the referenced attribute declaration.
  19156. */
  19157. static int
  19158. xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
  19159. xmlSchemaParserCtxtPtr ctxt)
  19160. {
  19161. if ((ctxt == NULL) || (ause == NULL))
  19162. return(-1);
  19163. if ((ause->attrDecl == NULL) ||
  19164. (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
  19165. return(0);
  19166. {
  19167. xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
  19168. /*
  19169. * TODO: Evaluate, what errors could occur if the declaration is not
  19170. * found.
  19171. */
  19172. ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
  19173. ref->name, ref->targetNamespace);
  19174. if (ause->attrDecl == NULL) {
  19175. xmlSchemaPResCompAttrErr(ctxt,
  19176. XML_SCHEMAP_SRC_RESOLVE,
  19177. WXS_BASIC_CAST ause, ause->node,
  19178. "ref", ref->name, ref->targetNamespace,
  19179. XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
  19180. return(ctxt->err);;
  19181. }
  19182. }
  19183. return(0);
  19184. }
  19185. /**
  19186. * xmlSchemaCheckAttrUsePropsCorrect:
  19187. * @ctxt: a parser context
  19188. * @use: an attribute use
  19189. *
  19190. * Schema Component Constraint:
  19191. * Attribute Use Correct (au-props-correct)
  19192. *
  19193. */
  19194. static int
  19195. xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
  19196. xmlSchemaAttributeUsePtr use)
  19197. {
  19198. if ((ctxt == NULL) || (use == NULL))
  19199. return(-1);
  19200. if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
  19201. ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
  19202. return(0);
  19203. /*
  19204. * SPEC au-props-correct (1)
  19205. * "The values of the properties of an attribute use must be as
  19206. * described in the property tableau in The Attribute Use Schema
  19207. * Component ($3.5.1), modulo the impact of Missing
  19208. * Sub-components ($5.3)."
  19209. */
  19210. if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
  19211. ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
  19212. ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
  19213. {
  19214. xmlSchemaPCustomErr(ctxt,
  19215. XML_SCHEMAP_AU_PROPS_CORRECT_2,
  19216. WXS_BASIC_CAST use, NULL,
  19217. "The attribute declaration has a 'fixed' value constraint "
  19218. ", thus the attribute use must also have a 'fixed' value "
  19219. "constraint",
  19220. NULL);
  19221. return(ctxt->err);
  19222. }
  19223. /*
  19224. * Compute and check the value constraint's value.
  19225. */
  19226. if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
  19227. int ret;
  19228. /*
  19229. * TODO: The spec seems to be missing a check of the
  19230. * value constraint of the attribute use. We will do it here.
  19231. */
  19232. /*
  19233. * SPEC a-props-correct (3)
  19234. */
  19235. if (xmlSchemaIsDerivedFromBuiltInType(
  19236. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  19237. {
  19238. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  19239. XML_SCHEMAP_AU_PROPS_CORRECT,
  19240. NULL, WXS_BASIC_CAST use,
  19241. "Value constraints are not allowed if the type definition "
  19242. "is or is derived from xs:ID",
  19243. NULL, NULL);
  19244. return(ctxt->err);
  19245. }
  19246. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
  19247. use->node, WXS_ATTRUSE_TYPEDEF(use),
  19248. use->defValue, &(use->defVal),
  19249. 1, 1, 0);
  19250. if (ret != 0) {
  19251. if (ret < 0) {
  19252. PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
  19253. "calling xmlSchemaVCheckCVCSimpleType()");
  19254. return(-1);
  19255. }
  19256. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  19257. XML_SCHEMAP_AU_PROPS_CORRECT,
  19258. NULL, WXS_BASIC_CAST use,
  19259. "The value of the value constraint is not valid",
  19260. NULL, NULL);
  19261. return(ctxt->err);
  19262. }
  19263. }
  19264. /*
  19265. * SPEC au-props-correct (2)
  19266. * "If the {attribute declaration} has a fixed
  19267. * {value constraint}, then if the attribute use itself has a
  19268. * {value constraint}, it must also be fixed and its value must match
  19269. * that of the {attribute declaration}'s {value constraint}."
  19270. */
  19271. if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
  19272. (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
  19273. {
  19274. if (! xmlSchemaAreValuesEqual(use->defVal,
  19275. (WXS_ATTRUSE_DECL(use))->defVal))
  19276. {
  19277. xmlSchemaPCustomErr(ctxt,
  19278. XML_SCHEMAP_AU_PROPS_CORRECT_2,
  19279. WXS_BASIC_CAST use, NULL,
  19280. "The 'fixed' value constraint of the attribute use "
  19281. "must match the attribute declaration's value "
  19282. "constraint '%s'",
  19283. (WXS_ATTRUSE_DECL(use))->defValue);
  19284. }
  19285. return(ctxt->err);
  19286. }
  19287. return(0);
  19288. }
  19289. /**
  19290. * xmlSchemaResolveAttrTypeReferences:
  19291. * @item: an attribute declaration
  19292. * @ctxt: a parser context
  19293. *
  19294. * Resolves the referenced type definition component.
  19295. */
  19296. static int
  19297. xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
  19298. xmlSchemaParserCtxtPtr ctxt)
  19299. {
  19300. /*
  19301. * The simple type definition corresponding to the <simpleType> element
  19302. * information item in the [children], if present, otherwise the simple
  19303. * type definition `resolved` to by the `actual value` of the type
  19304. * [attribute], if present, otherwise the `simple ur-type definition`.
  19305. */
  19306. if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
  19307. return(0);
  19308. item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
  19309. if (item->subtypes != NULL)
  19310. return(0);
  19311. if (item->typeName != NULL) {
  19312. xmlSchemaTypePtr type;
  19313. type = xmlSchemaGetType(ctxt->schema, item->typeName,
  19314. item->typeNs);
  19315. if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
  19316. xmlSchemaPResCompAttrErr(ctxt,
  19317. XML_SCHEMAP_SRC_RESOLVE,
  19318. WXS_BASIC_CAST item, item->node,
  19319. "type", item->typeName, item->typeNs,
  19320. XML_SCHEMA_TYPE_SIMPLE, NULL);
  19321. return(ctxt->err);
  19322. } else
  19323. item->subtypes = type;
  19324. } else {
  19325. /*
  19326. * The type defaults to the xs:anySimpleType.
  19327. */
  19328. item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  19329. }
  19330. return(0);
  19331. }
  19332. /**
  19333. * xmlSchemaResolveIDCKeyReferences:
  19334. * @idc: the identity-constraint definition
  19335. * @ctxt: the schema parser context
  19336. * @name: the attribute name
  19337. *
  19338. * Resolve keyRef references to key/unique IDCs.
  19339. * Schema Component Constraint:
  19340. * Identity-constraint Definition Properties Correct (c-props-correct)
  19341. */
  19342. static int
  19343. xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
  19344. xmlSchemaParserCtxtPtr pctxt)
  19345. {
  19346. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
  19347. return(0);
  19348. if (idc->ref->name != NULL) {
  19349. idc->ref->item = (xmlSchemaBasicItemPtr)
  19350. xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
  19351. idc->ref->targetNamespace);
  19352. if (idc->ref->item == NULL) {
  19353. /*
  19354. * TODO: It is actually not an error to fail to resolve
  19355. * at this stage. BUT we need to be that strict!
  19356. */
  19357. xmlSchemaPResCompAttrErr(pctxt,
  19358. XML_SCHEMAP_SRC_RESOLVE,
  19359. WXS_BASIC_CAST idc, idc->node,
  19360. "refer", idc->ref->name,
  19361. idc->ref->targetNamespace,
  19362. XML_SCHEMA_TYPE_IDC_KEY, NULL);
  19363. return(pctxt->err);
  19364. } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  19365. /*
  19366. * SPEC c-props-correct (1)
  19367. */
  19368. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19369. XML_SCHEMAP_C_PROPS_CORRECT,
  19370. NULL, WXS_BASIC_CAST idc,
  19371. "The keyref references a keyref",
  19372. NULL, NULL);
  19373. idc->ref->item = NULL;
  19374. return(pctxt->err);
  19375. } else {
  19376. if (idc->nbFields !=
  19377. ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
  19378. xmlChar *str = NULL;
  19379. xmlSchemaIDCPtr refer;
  19380. refer = (xmlSchemaIDCPtr) idc->ref->item;
  19381. /*
  19382. * SPEC c-props-correct(2)
  19383. * "If the {identity-constraint category} is keyref,
  19384. * the cardinality of the {fields} must equal that of
  19385. * the {fields} of the {referenced key}.
  19386. */
  19387. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19388. XML_SCHEMAP_C_PROPS_CORRECT,
  19389. NULL, WXS_BASIC_CAST idc,
  19390. "The cardinality of the keyref differs from the "
  19391. "cardinality of the referenced key/unique '%s'",
  19392. xmlSchemaFormatQName(&str, refer->targetNamespace,
  19393. refer->name),
  19394. NULL);
  19395. FREE_AND_NULL(str)
  19396. return(pctxt->err);
  19397. }
  19398. }
  19399. }
  19400. return(0);
  19401. }
  19402. static int
  19403. xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
  19404. xmlSchemaParserCtxtPtr pctxt)
  19405. {
  19406. if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
  19407. prohib->targetNamespace) == NULL) {
  19408. xmlSchemaPResCompAttrErr(pctxt,
  19409. XML_SCHEMAP_SRC_RESOLVE,
  19410. NULL, prohib->node,
  19411. "ref", prohib->name, prohib->targetNamespace,
  19412. XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
  19413. return(XML_SCHEMAP_SRC_RESOLVE);
  19414. }
  19415. return(0);
  19416. }
  19417. #define WXS_REDEFINED_TYPE(c) \
  19418. (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
  19419. #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
  19420. (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
  19421. #define WXS_REDEFINED_ATTR_GROUP(c) \
  19422. (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
  19423. static int
  19424. xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
  19425. {
  19426. int err = 0;
  19427. xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
  19428. xmlSchemaBasicItemPtr prev, item;
  19429. int wasRedefined;
  19430. if (redef == NULL)
  19431. return(0);
  19432. do {
  19433. item = redef->item;
  19434. /*
  19435. * First try to locate the redefined component in the
  19436. * schema graph starting with the redefined schema.
  19437. * NOTE: According to this schema bug entry:
  19438. * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
  19439. * it's not clear if the referenced component needs to originate
  19440. * from the <redefine>d schema _document_ or the schema; the latter
  19441. * would include all imported and included sub-schemas of the
  19442. * <redefine>d schema. Currently the latter approach is used.
  19443. * SUPPLEMENT: It seems that the WG moves towards the latter
  19444. * approach, so we are doing it right.
  19445. *
  19446. */
  19447. prev = xmlSchemaFindRedefCompInGraph(
  19448. redef->targetBucket, item->type,
  19449. redef->refName, redef->refTargetNs);
  19450. if (prev == NULL) {
  19451. xmlChar *str = NULL;
  19452. xmlNodePtr node;
  19453. /*
  19454. * SPEC src-redefine:
  19455. * (6.2.1) "The `actual value` of its own name attribute plus
  19456. * target namespace must successfully `resolve` to a model
  19457. * group definition in I."
  19458. * (7.2.1) "The `actual value` of its own name attribute plus
  19459. * target namespace must successfully `resolve` to an attribute
  19460. * group definition in I."
  19461. *
  19462. * Note that, if we are redefining with the use of references
  19463. * to components, the spec assumes the src-resolve to be used;
  19464. * but this won't assure that we search only *inside* the
  19465. * redefined schema.
  19466. */
  19467. if (redef->reference)
  19468. node = WXS_ITEM_NODE(redef->reference);
  19469. else
  19470. node = WXS_ITEM_NODE(item);
  19471. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19472. /*
  19473. * TODO: error code.
  19474. * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
  19475. * reference kind.
  19476. */
  19477. XML_SCHEMAP_SRC_REDEFINE, node, NULL,
  19478. "The %s '%s' to be redefined could not be found in "
  19479. "the redefined schema",
  19480. WXS_ITEM_TYPE_NAME(item),
  19481. xmlSchemaFormatQName(&str, redef->refTargetNs,
  19482. redef->refName));
  19483. FREE_AND_NULL(str);
  19484. err = pctxt->err;
  19485. redef = redef->next;
  19486. continue;
  19487. }
  19488. /*
  19489. * TODO: Obtaining and setting the redefinition state is really
  19490. * clumsy.
  19491. */
  19492. wasRedefined = 0;
  19493. switch (item->type) {
  19494. case XML_SCHEMA_TYPE_COMPLEX:
  19495. case XML_SCHEMA_TYPE_SIMPLE:
  19496. if ((WXS_TYPE_CAST prev)->flags &
  19497. XML_SCHEMAS_TYPE_REDEFINED)
  19498. {
  19499. wasRedefined = 1;
  19500. break;
  19501. }
  19502. /* Mark it as redefined. */
  19503. (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
  19504. /*
  19505. * Assign the redefined type to the
  19506. * base type of the redefining type.
  19507. * TODO: How
  19508. */
  19509. ((xmlSchemaTypePtr) item)->baseType =
  19510. (xmlSchemaTypePtr) prev;
  19511. break;
  19512. case XML_SCHEMA_TYPE_GROUP:
  19513. if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
  19514. XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
  19515. {
  19516. wasRedefined = 1;
  19517. break;
  19518. }
  19519. /* Mark it as redefined. */
  19520. (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
  19521. XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
  19522. if (redef->reference != NULL) {
  19523. /*
  19524. * Overwrite the QName-reference with the
  19525. * referenced model group def.
  19526. */
  19527. (WXS_PTC_CAST redef->reference)->children =
  19528. WXS_TREE_CAST prev;
  19529. }
  19530. redef->target = prev;
  19531. break;
  19532. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19533. if ((WXS_ATTR_GROUP_CAST prev)->flags &
  19534. XML_SCHEMAS_ATTRGROUP_REDEFINED)
  19535. {
  19536. wasRedefined = 1;
  19537. break;
  19538. }
  19539. (WXS_ATTR_GROUP_CAST prev)->flags |=
  19540. XML_SCHEMAS_ATTRGROUP_REDEFINED;
  19541. if (redef->reference != NULL) {
  19542. /*
  19543. * Assign the redefined attribute group to the
  19544. * QName-reference component.
  19545. * This is the easy case, since we will just
  19546. * expand the redefined group.
  19547. */
  19548. (WXS_QNAME_CAST redef->reference)->item = prev;
  19549. redef->target = NULL;
  19550. } else {
  19551. /*
  19552. * This is the complicated case: we need
  19553. * to apply src-redefine (7.2.2) at a later
  19554. * stage, i.e. when attribute group references
  19555. * have been expanded and simple types have
  19556. * been fixed.
  19557. */
  19558. redef->target = prev;
  19559. }
  19560. break;
  19561. default:
  19562. PERROR_INT("xmlSchemaResolveRedefReferences",
  19563. "Unexpected redefined component type");
  19564. return(-1);
  19565. }
  19566. if (wasRedefined) {
  19567. xmlChar *str = NULL;
  19568. xmlNodePtr node;
  19569. if (redef->reference)
  19570. node = WXS_ITEM_NODE(redef->reference);
  19571. else
  19572. node = WXS_ITEM_NODE(redef->item);
  19573. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19574. /* TODO: error code. */
  19575. XML_SCHEMAP_SRC_REDEFINE,
  19576. node, NULL,
  19577. "The referenced %s was already redefined. Multiple "
  19578. "redefinition of the same component is not supported",
  19579. xmlSchemaGetComponentDesignation(&str, prev),
  19580. NULL);
  19581. FREE_AND_NULL(str)
  19582. err = pctxt->err;
  19583. redef = redef->next;
  19584. continue;
  19585. }
  19586. redef = redef->next;
  19587. } while (redef != NULL);
  19588. return(err);
  19589. }
  19590. static int
  19591. xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
  19592. {
  19593. int err = 0;
  19594. xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
  19595. xmlSchemaBasicItemPtr item;
  19596. if (redef == NULL)
  19597. return(0);
  19598. do {
  19599. if (redef->target == NULL) {
  19600. redef = redef->next;
  19601. continue;
  19602. }
  19603. item = redef->item;
  19604. switch (item->type) {
  19605. case XML_SCHEMA_TYPE_SIMPLE:
  19606. case XML_SCHEMA_TYPE_COMPLEX:
  19607. /*
  19608. * Since the spec wants the {name} of the redefined
  19609. * type to be 'absent', we'll NULL it.
  19610. */
  19611. (WXS_TYPE_CAST redef->target)->name = NULL;
  19612. /*
  19613. * TODO: Seems like there's nothing more to do. The normal
  19614. * inheritance mechanism is used. But not 100% sure.
  19615. */
  19616. break;
  19617. case XML_SCHEMA_TYPE_GROUP:
  19618. /*
  19619. * URGENT TODO:
  19620. * SPEC src-redefine:
  19621. * (6.2.2) "The {model group} of the model group definition
  19622. * which corresponds to it per XML Representation of Model
  19623. * Group Definition Schema Components ($3.7.2) must be a
  19624. * `valid restriction` of the {model group} of that model
  19625. * group definition in I, as defined in Particle Valid
  19626. * (Restriction) ($3.9.6)."
  19627. */
  19628. break;
  19629. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19630. /*
  19631. * SPEC src-redefine:
  19632. * (7.2.2) "The {attribute uses} and {attribute wildcard} of
  19633. * the attribute group definition which corresponds to it
  19634. * per XML Representation of Attribute Group Definition Schema
  19635. * Components ($3.6.2) must be `valid restrictions` of the
  19636. * {attribute uses} and {attribute wildcard} of that attribute
  19637. * group definition in I, as defined in clause 2, clause 3 and
  19638. * clause 4 of Derivation Valid (Restriction, Complex)
  19639. * ($3.4.6) (where references to the base type definition are
  19640. * understood as references to the attribute group definition
  19641. * in I)."
  19642. */
  19643. err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
  19644. XML_SCHEMA_ACTION_REDEFINE,
  19645. item, redef->target,
  19646. (WXS_ATTR_GROUP_CAST item)->attrUses,
  19647. (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
  19648. (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
  19649. (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
  19650. if (err == -1)
  19651. return(-1);
  19652. break;
  19653. default:
  19654. break;
  19655. }
  19656. redef = redef->next;
  19657. } while (redef != NULL);
  19658. return(0);
  19659. }
  19660. static int
  19661. xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
  19662. xmlSchemaBucketPtr bucket)
  19663. {
  19664. xmlSchemaBasicItemPtr item;
  19665. int err;
  19666. xmlHashTablePtr *table;
  19667. const xmlChar *name;
  19668. int i;
  19669. #define WXS_GET_GLOBAL_HASH(c, slot) { \
  19670. if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
  19671. table = &(WXS_IMPBUCKET((c))->schema->slot); \
  19672. else \
  19673. table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
  19674. /*
  19675. * Add global components to the schema's hash tables.
  19676. * This is the place where duplicate components will be
  19677. * detected.
  19678. * TODO: I think normally we should support imports of the
  19679. * same namespace from multiple locations. We don't do currently,
  19680. * but if we do then according to:
  19681. * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
  19682. * we would need, if imported directly, to import redefined
  19683. * components as well to be able to catch clashing components.
  19684. * (I hope I'll still know what this means after some months :-()
  19685. */
  19686. if (bucket == NULL)
  19687. return(-1);
  19688. if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
  19689. return(0);
  19690. bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
  19691. for (i = 0; i < bucket->globals->nbItems; i++) {
  19692. item = bucket->globals->items[i];
  19693. table = NULL;
  19694. switch (item->type) {
  19695. case XML_SCHEMA_TYPE_COMPLEX:
  19696. case XML_SCHEMA_TYPE_SIMPLE:
  19697. if (WXS_REDEFINED_TYPE(item))
  19698. continue;
  19699. name = (WXS_TYPE_CAST item)->name;
  19700. WXS_GET_GLOBAL_HASH(bucket, typeDecl)
  19701. break;
  19702. case XML_SCHEMA_TYPE_ELEMENT:
  19703. name = (WXS_ELEM_CAST item)->name;
  19704. WXS_GET_GLOBAL_HASH(bucket, elemDecl)
  19705. break;
  19706. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19707. name = (WXS_ATTR_CAST item)->name;
  19708. WXS_GET_GLOBAL_HASH(bucket, attrDecl)
  19709. break;
  19710. case XML_SCHEMA_TYPE_GROUP:
  19711. if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
  19712. continue;
  19713. name = (WXS_MODEL_GROUPDEF_CAST item)->name;
  19714. WXS_GET_GLOBAL_HASH(bucket, groupDecl)
  19715. break;
  19716. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19717. if (WXS_REDEFINED_ATTR_GROUP(item))
  19718. continue;
  19719. name = (WXS_ATTR_GROUP_CAST item)->name;
  19720. WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
  19721. break;
  19722. case XML_SCHEMA_TYPE_IDC_KEY:
  19723. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  19724. case XML_SCHEMA_TYPE_IDC_KEYREF:
  19725. name = (WXS_IDC_CAST item)->name;
  19726. WXS_GET_GLOBAL_HASH(bucket, idcDef)
  19727. break;
  19728. case XML_SCHEMA_TYPE_NOTATION:
  19729. name = ((xmlSchemaNotationPtr) item)->name;
  19730. WXS_GET_GLOBAL_HASH(bucket, notaDecl)
  19731. break;
  19732. default:
  19733. PERROR_INT("xmlSchemaAddComponents",
  19734. "Unexpected global component type");
  19735. continue;
  19736. }
  19737. if (*table == NULL) {
  19738. *table = xmlHashCreateDict(10, pctxt->dict);
  19739. if (*table == NULL) {
  19740. PERROR_INT("xmlSchemaAddComponents",
  19741. "failed to create a component hash table");
  19742. return(-1);
  19743. }
  19744. }
  19745. err = xmlHashAddEntry(*table, name, item);
  19746. if (err != 0) {
  19747. xmlChar *str = NULL;
  19748. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19749. XML_SCHEMAP_REDEFINED_TYPE,
  19750. WXS_ITEM_NODE(item),
  19751. WXS_BASIC_CAST item,
  19752. "A global %s '%s' does already exist",
  19753. WXS_ITEM_TYPE_NAME(item),
  19754. xmlSchemaGetComponentQName(&str, item));
  19755. FREE_AND_NULL(str);
  19756. }
  19757. }
  19758. /*
  19759. * Process imported/included schemas.
  19760. */
  19761. if (bucket->relations != NULL) {
  19762. xmlSchemaSchemaRelationPtr rel = bucket->relations;
  19763. do {
  19764. if ((rel->bucket != NULL) &&
  19765. ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
  19766. if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
  19767. return(-1);
  19768. }
  19769. rel = rel->next;
  19770. } while (rel != NULL);
  19771. }
  19772. return(0);
  19773. }
  19774. static int
  19775. xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
  19776. xmlSchemaBucketPtr rootBucket)
  19777. {
  19778. xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
  19779. xmlSchemaTreeItemPtr item, *items;
  19780. int nbItems, i, ret = 0;
  19781. xmlSchemaBucketPtr oldbucket = con->bucket;
  19782. xmlSchemaElementPtr elemDecl;
  19783. #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
  19784. if ((con->pending == NULL) ||
  19785. (con->pending->nbItems == 0))
  19786. return(0);
  19787. /*
  19788. * Since xmlSchemaFixupComplexType() will create new particles
  19789. * (local components), and those particle components need a bucket
  19790. * on the constructor, we'll assure here that the constructor has
  19791. * a bucket.
  19792. * TODO: Think about storing locals _only_ on the main bucket.
  19793. */
  19794. if (con->bucket == NULL)
  19795. con->bucket = rootBucket;
  19796. /* TODO:
  19797. * SPEC (src-redefine):
  19798. * (6.2) "If it has no such self-reference, then all of the
  19799. * following must be true:"
  19800. * (6.2.2) The {model group} of the model group definition which
  19801. * corresponds to it per XML Representation of Model Group
  19802. * Definition Schema Components ($3.7.2) must be a `valid
  19803. * restriction` of the {model group} of that model group definition
  19804. * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
  19805. */
  19806. xmlSchemaCheckSRCRedefineFirst(pctxt);
  19807. /*
  19808. * Add global components to the schemata's hash tables.
  19809. */
  19810. xmlSchemaAddComponents(pctxt, rootBucket);
  19811. pctxt->ctxtType = NULL;
  19812. items = (xmlSchemaTreeItemPtr *) con->pending->items;
  19813. nbItems = con->pending->nbItems;
  19814. /*
  19815. * Now that we have parsed *all* the schema document(s) and converted
  19816. * them to schema components, we can resolve references, apply component
  19817. * constraints, create the FSA from the content model, etc.
  19818. */
  19819. /*
  19820. * Resolve references of..
  19821. *
  19822. * 1. element declarations:
  19823. * - the type definition
  19824. * - the substitution group affiliation
  19825. * 2. simple/complex types:
  19826. * - the base type definition
  19827. * - the memberTypes of union types
  19828. * - the itemType of list types
  19829. * 3. attributes declarations and attribute uses:
  19830. * - the type definition
  19831. * - if an attribute use, then the attribute declaration
  19832. * 4. attribute group references:
  19833. * - the attribute group definition
  19834. * 5. particles:
  19835. * - the term of the particle (e.g. a model group)
  19836. * 6. IDC key-references:
  19837. * - the referenced IDC 'key' or 'unique' definition
  19838. * 7. Attribute prohibitions which had a "ref" attribute.
  19839. */
  19840. for (i = 0; i < nbItems; i++) {
  19841. item = items[i];
  19842. switch (item->type) {
  19843. case XML_SCHEMA_TYPE_ELEMENT:
  19844. xmlSchemaResolveElementReferences(
  19845. (xmlSchemaElementPtr) item, pctxt);
  19846. FIXHFAILURE;
  19847. break;
  19848. case XML_SCHEMA_TYPE_COMPLEX:
  19849. case XML_SCHEMA_TYPE_SIMPLE:
  19850. xmlSchemaResolveTypeReferences(
  19851. (xmlSchemaTypePtr) item, pctxt);
  19852. FIXHFAILURE;
  19853. break;
  19854. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19855. xmlSchemaResolveAttrTypeReferences(
  19856. (xmlSchemaAttributePtr) item, pctxt);
  19857. FIXHFAILURE;
  19858. break;
  19859. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  19860. xmlSchemaResolveAttrUseReferences(
  19861. (xmlSchemaAttributeUsePtr) item, pctxt);
  19862. FIXHFAILURE;
  19863. break;
  19864. case XML_SCHEMA_EXTRA_QNAMEREF:
  19865. if ((WXS_QNAME_CAST item)->itemType ==
  19866. XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
  19867. {
  19868. xmlSchemaResolveAttrGroupReferences(
  19869. WXS_QNAME_CAST item, pctxt);
  19870. }
  19871. FIXHFAILURE;
  19872. break;
  19873. case XML_SCHEMA_TYPE_SEQUENCE:
  19874. case XML_SCHEMA_TYPE_CHOICE:
  19875. case XML_SCHEMA_TYPE_ALL:
  19876. xmlSchemaResolveModelGroupParticleReferences(pctxt,
  19877. WXS_MODEL_GROUP_CAST item);
  19878. FIXHFAILURE;
  19879. break;
  19880. case XML_SCHEMA_TYPE_IDC_KEY:
  19881. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  19882. case XML_SCHEMA_TYPE_IDC_KEYREF:
  19883. xmlSchemaResolveIDCKeyReferences(
  19884. (xmlSchemaIDCPtr) item, pctxt);
  19885. FIXHFAILURE;
  19886. break;
  19887. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  19888. /*
  19889. * Handle attribute prohibition which had a
  19890. * "ref" attribute.
  19891. */
  19892. xmlSchemaResolveAttrUseProhibReferences(
  19893. WXS_ATTR_PROHIB_CAST item, pctxt);
  19894. FIXHFAILURE;
  19895. break;
  19896. default:
  19897. break;
  19898. }
  19899. }
  19900. if (pctxt->nberrors != 0)
  19901. goto exit_error;
  19902. /*
  19903. * Now that all references are resolved we
  19904. * can check for circularity of...
  19905. * 1. the base axis of type definitions
  19906. * 2. nested model group definitions
  19907. * 3. nested attribute group definitions
  19908. * TODO: check for circular substitution groups.
  19909. */
  19910. for (i = 0; i < nbItems; i++) {
  19911. item = items[i];
  19912. /*
  19913. * Let's better stop on the first error here.
  19914. */
  19915. switch (item->type) {
  19916. case XML_SCHEMA_TYPE_COMPLEX:
  19917. case XML_SCHEMA_TYPE_SIMPLE:
  19918. xmlSchemaCheckTypeDefCircular(
  19919. (xmlSchemaTypePtr) item, pctxt);
  19920. FIXHFAILURE;
  19921. if (pctxt->nberrors != 0)
  19922. goto exit_error;
  19923. break;
  19924. case XML_SCHEMA_TYPE_GROUP:
  19925. xmlSchemaCheckGroupDefCircular(
  19926. (xmlSchemaModelGroupDefPtr) item, pctxt);
  19927. FIXHFAILURE;
  19928. if (pctxt->nberrors != 0)
  19929. goto exit_error;
  19930. break;
  19931. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19932. xmlSchemaCheckAttrGroupCircular(
  19933. (xmlSchemaAttributeGroupPtr) item, pctxt);
  19934. FIXHFAILURE;
  19935. if (pctxt->nberrors != 0)
  19936. goto exit_error;
  19937. break;
  19938. default:
  19939. break;
  19940. }
  19941. }
  19942. if (pctxt->nberrors != 0)
  19943. goto exit_error;
  19944. /*
  19945. * Model group definition references:
  19946. * Such a reference is reflected by a particle at the component
  19947. * level. Until now the 'term' of such particles pointed
  19948. * to the model group definition; this was done, in order to
  19949. * ease circularity checks. Now we need to set the 'term' of
  19950. * such particles to the model group of the model group definition.
  19951. */
  19952. for (i = 0; i < nbItems; i++) {
  19953. item = items[i];
  19954. switch (item->type) {
  19955. case XML_SCHEMA_TYPE_SEQUENCE:
  19956. case XML_SCHEMA_TYPE_CHOICE:
  19957. xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
  19958. WXS_MODEL_GROUP_CAST item);
  19959. break;
  19960. default:
  19961. break;
  19962. }
  19963. }
  19964. if (pctxt->nberrors != 0)
  19965. goto exit_error;
  19966. /*
  19967. * Expand attribute group references of attribute group definitions.
  19968. */
  19969. for (i = 0; i < nbItems; i++) {
  19970. item = items[i];
  19971. switch (item->type) {
  19972. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19973. if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
  19974. WXS_ATTR_GROUP_HAS_REFS(item))
  19975. {
  19976. xmlSchemaAttributeGroupExpandRefs(pctxt,
  19977. WXS_ATTR_GROUP_CAST item);
  19978. FIXHFAILURE;
  19979. }
  19980. break;
  19981. default:
  19982. break;
  19983. }
  19984. }
  19985. if (pctxt->nberrors != 0)
  19986. goto exit_error;
  19987. /*
  19988. * First compute the variety of simple types. This is needed as
  19989. * a separate step, since otherwise we won't be able to detect
  19990. * circular union types in all cases.
  19991. */
  19992. for (i = 0; i < nbItems; i++) {
  19993. item = items[i];
  19994. switch (item->type) {
  19995. case XML_SCHEMA_TYPE_SIMPLE:
  19996. if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
  19997. xmlSchemaFixupSimpleTypeStageOne(pctxt,
  19998. (xmlSchemaTypePtr) item);
  19999. FIXHFAILURE;
  20000. }
  20001. break;
  20002. default:
  20003. break;
  20004. }
  20005. }
  20006. if (pctxt->nberrors != 0)
  20007. goto exit_error;
  20008. /*
  20009. * Detect circular union types. Note that this needs the variety to
  20010. * be already computed.
  20011. */
  20012. for (i = 0; i < nbItems; i++) {
  20013. item = items[i];
  20014. switch (item->type) {
  20015. case XML_SCHEMA_TYPE_SIMPLE:
  20016. if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
  20017. xmlSchemaCheckUnionTypeDefCircular(pctxt,
  20018. (xmlSchemaTypePtr) item);
  20019. FIXHFAILURE;
  20020. }
  20021. break;
  20022. default:
  20023. break;
  20024. }
  20025. }
  20026. if (pctxt->nberrors != 0)
  20027. goto exit_error;
  20028. /*
  20029. * Do the complete type fixup for simple types.
  20030. */
  20031. for (i = 0; i < nbItems; i++) {
  20032. item = items[i];
  20033. switch (item->type) {
  20034. case XML_SCHEMA_TYPE_SIMPLE:
  20035. if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
  20036. xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
  20037. FIXHFAILURE;
  20038. }
  20039. break;
  20040. default:
  20041. break;
  20042. }
  20043. }
  20044. if (pctxt->nberrors != 0)
  20045. goto exit_error;
  20046. /*
  20047. * At this point we need build and check all simple types.
  20048. */
  20049. /*
  20050. * Apply constraints for attribute declarations.
  20051. */
  20052. for (i = 0; i < nbItems; i++) {
  20053. item = items[i];
  20054. switch (item->type) {
  20055. case XML_SCHEMA_TYPE_ATTRIBUTE:
  20056. xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
  20057. FIXHFAILURE;
  20058. break;
  20059. default:
  20060. break;
  20061. }
  20062. }
  20063. if (pctxt->nberrors != 0)
  20064. goto exit_error;
  20065. /*
  20066. * Apply constraints for attribute uses.
  20067. */
  20068. for (i = 0; i < nbItems; i++) {
  20069. item = items[i];
  20070. switch (item->type) {
  20071. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  20072. if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
  20073. xmlSchemaCheckAttrUsePropsCorrect(pctxt,
  20074. WXS_ATTR_USE_CAST item);
  20075. FIXHFAILURE;
  20076. }
  20077. break;
  20078. default:
  20079. break;
  20080. }
  20081. }
  20082. if (pctxt->nberrors != 0)
  20083. goto exit_error;
  20084. /*
  20085. * Apply constraints for attribute group definitions.
  20086. */
  20087. for (i = 0; i < nbItems; i++) {
  20088. item = items[i];
  20089. switch (item->type) {
  20090. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  20091. if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
  20092. ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
  20093. {
  20094. xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
  20095. FIXHFAILURE;
  20096. }
  20097. break;
  20098. default:
  20099. break;
  20100. }
  20101. }
  20102. if (pctxt->nberrors != 0)
  20103. goto exit_error;
  20104. /*
  20105. * Apply constraints for redefinitions.
  20106. */
  20107. if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
  20108. xmlSchemaCheckSRCRedefineSecond(pctxt);
  20109. if (pctxt->nberrors != 0)
  20110. goto exit_error;
  20111. /*
  20112. * Complex types are built and checked.
  20113. */
  20114. for (i = 0; i < nbItems; i++) {
  20115. item = con->pending->items[i];
  20116. switch (item->type) {
  20117. case XML_SCHEMA_TYPE_COMPLEX:
  20118. if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
  20119. xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
  20120. FIXHFAILURE;
  20121. }
  20122. break;
  20123. default:
  20124. break;
  20125. }
  20126. }
  20127. if (pctxt->nberrors != 0)
  20128. goto exit_error;
  20129. /*
  20130. * The list could have changed, since xmlSchemaFixupComplexType()
  20131. * will create particles and model groups in some cases.
  20132. */
  20133. items = (xmlSchemaTreeItemPtr *) con->pending->items;
  20134. nbItems = con->pending->nbItems;
  20135. /*
  20136. * Apply some constraints for element declarations.
  20137. */
  20138. for (i = 0; i < nbItems; i++) {
  20139. item = items[i];
  20140. switch (item->type) {
  20141. case XML_SCHEMA_TYPE_ELEMENT:
  20142. elemDecl = (xmlSchemaElementPtr) item;
  20143. if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
  20144. {
  20145. xmlSchemaCheckElementDeclComponent(
  20146. (xmlSchemaElementPtr) elemDecl, pctxt);
  20147. FIXHFAILURE;
  20148. }
  20149. #ifdef WXS_ELEM_DECL_CONS_ENABLED
  20150. /*
  20151. * Schema Component Constraint: Element Declarations Consistent
  20152. * Apply this constraint to local types of element declarations.
  20153. */
  20154. if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
  20155. (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
  20156. (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
  20157. {
  20158. xmlSchemaCheckElementDeclConsistent(pctxt,
  20159. WXS_BASIC_CAST elemDecl,
  20160. WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
  20161. NULL, NULL, 0);
  20162. }
  20163. #endif
  20164. break;
  20165. default:
  20166. break;
  20167. }
  20168. }
  20169. if (pctxt->nberrors != 0)
  20170. goto exit_error;
  20171. /*
  20172. * Finally we can build the automaton from the content model of
  20173. * complex types.
  20174. */
  20175. for (i = 0; i < nbItems; i++) {
  20176. item = items[i];
  20177. switch (item->type) {
  20178. case XML_SCHEMA_TYPE_COMPLEX:
  20179. xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
  20180. /* FIXHFAILURE; */
  20181. break;
  20182. default:
  20183. break;
  20184. }
  20185. }
  20186. if (pctxt->nberrors != 0)
  20187. goto exit_error;
  20188. /*
  20189. * URGENT TODO: cos-element-consistent
  20190. */
  20191. goto exit;
  20192. exit_error:
  20193. ret = pctxt->err;
  20194. goto exit;
  20195. exit_failure:
  20196. ret = -1;
  20197. exit:
  20198. /*
  20199. * Reset the constructor. This is needed for XSI acquisition, since
  20200. * those items will be processed over and over again for every XSI
  20201. * if not cleared here.
  20202. */
  20203. con->bucket = oldbucket;
  20204. con->pending->nbItems = 0;
  20205. if (con->substGroups != NULL) {
  20206. xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
  20207. con->substGroups = NULL;
  20208. }
  20209. if (con->redefs != NULL) {
  20210. xmlSchemaRedefListFree(con->redefs);
  20211. con->redefs = NULL;
  20212. }
  20213. return(ret);
  20214. }
  20215. /**
  20216. * xmlSchemaParse:
  20217. * @ctxt: a schema validation context
  20218. *
  20219. * parse a schema definition resource and build an internal
  20220. * XML Schema structure which can be used to validate instances.
  20221. *
  20222. * Returns the internal XML Schema structure built from the resource or
  20223. * NULL in case of error
  20224. */
  20225. xmlSchemaPtr
  20226. xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
  20227. {
  20228. xmlSchemaPtr mainSchema = NULL;
  20229. xmlSchemaBucketPtr bucket = NULL;
  20230. int res;
  20231. /*
  20232. * This one is used if the schema to be parsed was specified via
  20233. * the API; i.e. not automatically by the validated instance document.
  20234. */
  20235. xmlSchemaInitTypes();
  20236. if (ctxt == NULL)
  20237. return (NULL);
  20238. /* TODO: Init the context. Is this all we need?*/
  20239. ctxt->nberrors = 0;
  20240. ctxt->err = 0;
  20241. ctxt->counter = 0;
  20242. /* Create the *main* schema. */
  20243. mainSchema = xmlSchemaNewSchema(ctxt);
  20244. if (mainSchema == NULL)
  20245. goto exit_failure;
  20246. /*
  20247. * Create the schema constructor.
  20248. */
  20249. if (ctxt->constructor == NULL) {
  20250. ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
  20251. if (ctxt->constructor == NULL)
  20252. return(NULL);
  20253. /* Take ownership of the constructor to be able to free it. */
  20254. ctxt->ownsConstructor = 1;
  20255. }
  20256. ctxt->constructor->mainSchema = mainSchema;
  20257. /*
  20258. * Locate and add the schema document.
  20259. */
  20260. res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
  20261. ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
  20262. NULL, NULL, &bucket);
  20263. if (res == -1)
  20264. goto exit_failure;
  20265. if (res != 0)
  20266. goto exit;
  20267. if (bucket == NULL) {
  20268. /* TODO: Error code, actually we failed to *locate* the schema. */
  20269. if (ctxt->URL)
  20270. xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
  20271. NULL, NULL,
  20272. "Failed to locate the main schema resource at '%s'",
  20273. ctxt->URL, NULL);
  20274. else
  20275. xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
  20276. NULL, NULL,
  20277. "Failed to locate the main schema resource",
  20278. NULL, NULL);
  20279. goto exit;
  20280. }
  20281. /* Then do the parsing for good. */
  20282. if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
  20283. goto exit_failure;
  20284. if (ctxt->nberrors != 0)
  20285. goto exit;
  20286. mainSchema->doc = bucket->doc;
  20287. mainSchema->preserve = ctxt->preserve;
  20288. ctxt->schema = mainSchema;
  20289. if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
  20290. goto exit_failure;
  20291. /*
  20292. * TODO: This is not nice, since we cannot distinguish from the
  20293. * result if there was an internal error or not.
  20294. */
  20295. exit:
  20296. if (ctxt->nberrors != 0) {
  20297. if (mainSchema) {
  20298. xmlSchemaFree(mainSchema);
  20299. mainSchema = NULL;
  20300. }
  20301. if (ctxt->constructor) {
  20302. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  20303. ctxt->constructor = NULL;
  20304. ctxt->ownsConstructor = 0;
  20305. }
  20306. }
  20307. ctxt->schema = NULL;
  20308. return(mainSchema);
  20309. exit_failure:
  20310. /*
  20311. * Quite verbose, but should catch internal errors, which were
  20312. * not communicated.
  20313. */
  20314. if (mainSchema) {
  20315. xmlSchemaFree(mainSchema);
  20316. mainSchema = NULL;
  20317. }
  20318. if (ctxt->constructor) {
  20319. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  20320. ctxt->constructor = NULL;
  20321. ctxt->ownsConstructor = 0;
  20322. }
  20323. PERROR_INT2("xmlSchemaParse",
  20324. "An internal error occurred");
  20325. ctxt->schema = NULL;
  20326. return(NULL);
  20327. }
  20328. /**
  20329. * xmlSchemaSetParserErrors:
  20330. * @ctxt: a schema validation context
  20331. * @err: the error callback
  20332. * @warn: the warning callback
  20333. * @ctx: contextual data for the callbacks
  20334. *
  20335. * Set the callback functions used to handle errors for a validation context
  20336. */
  20337. void
  20338. xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
  20339. xmlSchemaValidityErrorFunc err,
  20340. xmlSchemaValidityWarningFunc warn, void *ctx)
  20341. {
  20342. if (ctxt == NULL)
  20343. return;
  20344. ctxt->error = err;
  20345. ctxt->warning = warn;
  20346. ctxt->errCtxt = ctx;
  20347. if (ctxt->vctxt != NULL)
  20348. xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
  20349. }
  20350. /**
  20351. * xmlSchemaSetParserStructuredErrors:
  20352. * @ctxt: a schema parser context
  20353. * @serror: the structured error function
  20354. * @ctx: the functions context
  20355. *
  20356. * Set the structured error callback
  20357. */
  20358. void
  20359. xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
  20360. xmlStructuredErrorFunc serror,
  20361. void *ctx)
  20362. {
  20363. if (ctxt == NULL)
  20364. return;
  20365. ctxt->serror = serror;
  20366. ctxt->errCtxt = ctx;
  20367. if (ctxt->vctxt != NULL)
  20368. xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
  20369. }
  20370. /**
  20371. * xmlSchemaGetParserErrors:
  20372. * @ctxt: a XMl-Schema parser context
  20373. * @err: the error callback result
  20374. * @warn: the warning callback result
  20375. * @ctx: contextual data for the callbacks result
  20376. *
  20377. * Get the callback information used to handle errors for a parser context
  20378. *
  20379. * Returns -1 in case of failure, 0 otherwise
  20380. */
  20381. int
  20382. xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
  20383. xmlSchemaValidityErrorFunc * err,
  20384. xmlSchemaValidityWarningFunc * warn, void **ctx)
  20385. {
  20386. if (ctxt == NULL)
  20387. return(-1);
  20388. if (err != NULL)
  20389. *err = ctxt->error;
  20390. if (warn != NULL)
  20391. *warn = ctxt->warning;
  20392. if (ctx != NULL)
  20393. *ctx = ctxt->errCtxt;
  20394. return(0);
  20395. }
  20396. /**
  20397. * xmlSchemaFacetTypeToString:
  20398. * @type: the facet type
  20399. *
  20400. * Convert the xmlSchemaTypeType to a char string.
  20401. *
  20402. * Returns the char string representation of the facet type if the
  20403. * type is a facet and an "Internal Error" string otherwise.
  20404. */
  20405. static const xmlChar *
  20406. xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
  20407. {
  20408. switch (type) {
  20409. case XML_SCHEMA_FACET_PATTERN:
  20410. return (BAD_CAST "pattern");
  20411. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  20412. return (BAD_CAST "maxExclusive");
  20413. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  20414. return (BAD_CAST "maxInclusive");
  20415. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  20416. return (BAD_CAST "minExclusive");
  20417. case XML_SCHEMA_FACET_MININCLUSIVE:
  20418. return (BAD_CAST "minInclusive");
  20419. case XML_SCHEMA_FACET_WHITESPACE:
  20420. return (BAD_CAST "whiteSpace");
  20421. case XML_SCHEMA_FACET_ENUMERATION:
  20422. return (BAD_CAST "enumeration");
  20423. case XML_SCHEMA_FACET_LENGTH:
  20424. return (BAD_CAST "length");
  20425. case XML_SCHEMA_FACET_MAXLENGTH:
  20426. return (BAD_CAST "maxLength");
  20427. case XML_SCHEMA_FACET_MINLENGTH:
  20428. return (BAD_CAST "minLength");
  20429. case XML_SCHEMA_FACET_TOTALDIGITS:
  20430. return (BAD_CAST "totalDigits");
  20431. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  20432. return (BAD_CAST "fractionDigits");
  20433. default:
  20434. break;
  20435. }
  20436. return (BAD_CAST "Internal Error");
  20437. }
  20438. static xmlSchemaWhitespaceValueType
  20439. xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
  20440. {
  20441. /*
  20442. * The normalization type can be changed only for types which are derived
  20443. * from xsd:string.
  20444. */
  20445. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  20446. /*
  20447. * Note that we assume a whitespace of preserve for anySimpleType.
  20448. */
  20449. if ((type->builtInType == XML_SCHEMAS_STRING) ||
  20450. (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
  20451. return(XML_SCHEMA_WHITESPACE_PRESERVE);
  20452. else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
  20453. return(XML_SCHEMA_WHITESPACE_REPLACE);
  20454. else {
  20455. /*
  20456. * For all `atomic` datatypes other than string (and types `derived`
  20457. * by `restriction` from it) the value of whiteSpace is fixed to
  20458. * collapse
  20459. * Note that this includes built-in list datatypes.
  20460. */
  20461. return(XML_SCHEMA_WHITESPACE_COLLAPSE);
  20462. }
  20463. } else if (WXS_IS_LIST(type)) {
  20464. /*
  20465. * For list types the facet "whiteSpace" is fixed to "collapse".
  20466. */
  20467. return (XML_SCHEMA_WHITESPACE_COLLAPSE);
  20468. } else if (WXS_IS_UNION(type)) {
  20469. return (XML_SCHEMA_WHITESPACE_UNKNOWN);
  20470. } else if (WXS_IS_ATOMIC(type)) {
  20471. if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
  20472. return (XML_SCHEMA_WHITESPACE_PRESERVE);
  20473. else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
  20474. return (XML_SCHEMA_WHITESPACE_REPLACE);
  20475. else
  20476. return (XML_SCHEMA_WHITESPACE_COLLAPSE);
  20477. }
  20478. return (-1);
  20479. }
  20480. /************************************************************************
  20481. * *
  20482. * Simple type validation *
  20483. * *
  20484. ************************************************************************/
  20485. /************************************************************************
  20486. * *
  20487. * DOM Validation code *
  20488. * *
  20489. ************************************************************************/
  20490. /**
  20491. * xmlSchemaAssembleByLocation:
  20492. * @pctxt: a schema parser context
  20493. * @vctxt: a schema validation context
  20494. * @schema: the existing schema
  20495. * @node: the node that fired the assembling
  20496. * @nsName: the namespace name of the new schema
  20497. * @location: the location of the schema
  20498. *
  20499. * Expands an existing schema by an additional schema.
  20500. *
  20501. * Returns 0 if the new schema is correct, a positive error code
  20502. * number otherwise and -1 in case of an internal or API error.
  20503. */
  20504. static int
  20505. xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
  20506. xmlSchemaPtr schema,
  20507. xmlNodePtr node,
  20508. const xmlChar *nsName,
  20509. const xmlChar *location)
  20510. {
  20511. int ret = 0;
  20512. xmlSchemaParserCtxtPtr pctxt;
  20513. xmlSchemaBucketPtr bucket = NULL;
  20514. if ((vctxt == NULL) || (schema == NULL))
  20515. return (-1);
  20516. if (vctxt->pctxt == NULL) {
  20517. VERROR_INT("xmlSchemaAssembleByLocation",
  20518. "no parser context available");
  20519. return(-1);
  20520. }
  20521. pctxt = vctxt->pctxt;
  20522. if (pctxt->constructor == NULL) {
  20523. PERROR_INT("xmlSchemaAssembleByLocation",
  20524. "no constructor");
  20525. return(-1);
  20526. }
  20527. /*
  20528. * Acquire the schema document.
  20529. */
  20530. location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
  20531. location, node);
  20532. /*
  20533. * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
  20534. * the process will automatically change this to
  20535. * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
  20536. */
  20537. ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
  20538. location, NULL, NULL, 0, node, NULL, nsName,
  20539. &bucket);
  20540. if (ret != 0)
  20541. return(ret);
  20542. if (bucket == NULL) {
  20543. /*
  20544. * Generate a warning that the document could not be located.
  20545. */
  20546. xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
  20547. node, NULL,
  20548. "The document at location '%s' could not be acquired",
  20549. location, NULL, NULL);
  20550. return(ret);
  20551. }
  20552. /*
  20553. * The first located schema will be handled as if all other
  20554. * schemas imported by XSI were imported by this first schema.
  20555. */
  20556. if ((bucket != NULL) &&
  20557. (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
  20558. WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
  20559. /*
  20560. * TODO: Is this handled like an import? I.e. is it not an error
  20561. * if the schema cannot be located?
  20562. */
  20563. if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
  20564. return(0);
  20565. /*
  20566. * We will reuse the parser context for every schema imported
  20567. * directly via XSI. So reset the context.
  20568. */
  20569. pctxt->nberrors = 0;
  20570. pctxt->err = 0;
  20571. pctxt->doc = bucket->doc;
  20572. ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
  20573. if (ret == -1) {
  20574. pctxt->doc = NULL;
  20575. goto exit_failure;
  20576. }
  20577. /* Paranoid error channelling. */
  20578. if ((ret == 0) && (pctxt->nberrors != 0))
  20579. ret = pctxt->err;
  20580. if (pctxt->nberrors == 0) {
  20581. /*
  20582. * Only bother to fixup pending components, if there was
  20583. * no error yet.
  20584. * For every XSI acquired schema (and its sub-schemata) we will
  20585. * fixup the components.
  20586. */
  20587. xmlSchemaFixupComponents(pctxt, bucket);
  20588. ret = pctxt->err;
  20589. /*
  20590. * Not nice, but we need somehow to channel the schema parser
  20591. * error to the validation context.
  20592. */
  20593. if ((ret != 0) && (vctxt->err == 0))
  20594. vctxt->err = ret;
  20595. vctxt->nberrors += pctxt->nberrors;
  20596. } else {
  20597. /* Add to validation error sum. */
  20598. vctxt->nberrors += pctxt->nberrors;
  20599. }
  20600. pctxt->doc = NULL;
  20601. return(ret);
  20602. exit_failure:
  20603. pctxt->doc = NULL;
  20604. return (-1);
  20605. }
  20606. static xmlSchemaAttrInfoPtr
  20607. xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
  20608. int metaType)
  20609. {
  20610. if (vctxt->nbAttrInfos == 0)
  20611. return (NULL);
  20612. {
  20613. int i;
  20614. xmlSchemaAttrInfoPtr iattr;
  20615. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  20616. iattr = vctxt->attrInfos[i];
  20617. if (iattr->metaType == metaType)
  20618. return (iattr);
  20619. }
  20620. }
  20621. return (NULL);
  20622. }
  20623. /**
  20624. * xmlSchemaAssembleByXSI:
  20625. * @vctxt: a schema validation context
  20626. *
  20627. * Expands an existing schema by an additional schema using
  20628. * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
  20629. * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
  20630. * must be set to 1.
  20631. *
  20632. * Returns 0 if the new schema is correct, a positive error code
  20633. * number otherwise and -1 in case of an internal or API error.
  20634. */
  20635. static int
  20636. xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
  20637. {
  20638. const xmlChar *cur, *end;
  20639. const xmlChar *nsname = NULL, *location;
  20640. int count = 0;
  20641. int ret = 0;
  20642. xmlSchemaAttrInfoPtr iattr;
  20643. /*
  20644. * Parse the value; we will assume an even number of values
  20645. * to be given (this is how Xerces and XSV work).
  20646. *
  20647. * URGENT TODO: !! This needs to work for both
  20648. * @noNamespaceSchemaLocation AND @schemaLocation on the same
  20649. * element !!
  20650. */
  20651. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  20652. XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
  20653. if (iattr == NULL)
  20654. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  20655. XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
  20656. if (iattr == NULL)
  20657. return (0);
  20658. cur = iattr->value;
  20659. do {
  20660. /*
  20661. * TODO: Move the string parsing mechanism away from here.
  20662. */
  20663. if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
  20664. /*
  20665. * Get the namespace name.
  20666. */
  20667. while (IS_BLANK_CH(*cur))
  20668. cur++;
  20669. end = cur;
  20670. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  20671. end++;
  20672. if (end == cur)
  20673. break;
  20674. count++; /* TODO: Don't use the schema's dict. */
  20675. nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
  20676. cur = end;
  20677. }
  20678. /*
  20679. * Get the URI.
  20680. */
  20681. while (IS_BLANK_CH(*cur))
  20682. cur++;
  20683. end = cur;
  20684. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  20685. end++;
  20686. if (end == cur) {
  20687. if (iattr->metaType ==
  20688. XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
  20689. {
  20690. /*
  20691. * If using @schemaLocation then tuples are expected.
  20692. * I.e. the namespace name *and* the document's URI.
  20693. */
  20694. xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
  20695. iattr->node, NULL,
  20696. "The value must consist of tuples: the target namespace "
  20697. "name and the document's URI", NULL, NULL, NULL);
  20698. }
  20699. break;
  20700. }
  20701. count++; /* TODO: Don't use the schema's dict. */
  20702. location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
  20703. cur = end;
  20704. ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
  20705. iattr->node, nsname, location);
  20706. if (ret == -1) {
  20707. VERROR_INT("xmlSchemaAssembleByXSI",
  20708. "assembling schemata");
  20709. return (-1);
  20710. }
  20711. } while (*cur != 0);
  20712. return (ret);
  20713. }
  20714. static const xmlChar *
  20715. xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
  20716. const xmlChar *prefix)
  20717. {
  20718. if (vctxt->sax != NULL) {
  20719. int i, j;
  20720. xmlSchemaNodeInfoPtr inode;
  20721. for (i = vctxt->depth; i >= 0; i--) {
  20722. if (vctxt->elemInfos[i]->nbNsBindings != 0) {
  20723. inode = vctxt->elemInfos[i];
  20724. for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
  20725. if (((prefix == NULL) &&
  20726. (inode->nsBindings[j] == NULL)) ||
  20727. ((prefix != NULL) && xmlStrEqual(prefix,
  20728. inode->nsBindings[j]))) {
  20729. /*
  20730. * Note that the namespace bindings are already
  20731. * in a string dict.
  20732. */
  20733. return (inode->nsBindings[j+1]);
  20734. }
  20735. }
  20736. }
  20737. }
  20738. return (NULL);
  20739. #ifdef LIBXML_READER_ENABLED
  20740. } else if (vctxt->reader != NULL) {
  20741. xmlChar *nsName;
  20742. nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
  20743. if (nsName != NULL) {
  20744. const xmlChar *ret;
  20745. ret = xmlDictLookup(vctxt->dict, nsName, -1);
  20746. xmlFree(nsName);
  20747. return (ret);
  20748. } else
  20749. return (NULL);
  20750. #endif
  20751. } else {
  20752. xmlNsPtr ns;
  20753. if ((vctxt->inode->node == NULL) ||
  20754. (vctxt->inode->node->doc == NULL)) {
  20755. VERROR_INT("xmlSchemaLookupNamespace",
  20756. "no node or node's doc available");
  20757. return (NULL);
  20758. }
  20759. ns = xmlSearchNs(vctxt->inode->node->doc,
  20760. vctxt->inode->node, prefix);
  20761. if (ns != NULL)
  20762. return (ns->href);
  20763. return (NULL);
  20764. }
  20765. }
  20766. /*
  20767. * This one works on the schema of the validation context.
  20768. */
  20769. static int
  20770. xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
  20771. xmlSchemaPtr schema,
  20772. xmlNodePtr node,
  20773. const xmlChar *value,
  20774. xmlSchemaValPtr *val,
  20775. int valNeeded)
  20776. {
  20777. int ret;
  20778. if (vctxt && (vctxt->schema == NULL)) {
  20779. VERROR_INT("xmlSchemaValidateNotation",
  20780. "a schema is needed on the validation context");
  20781. return (-1);
  20782. }
  20783. ret = xmlValidateQName(value, 1);
  20784. if (ret != 0)
  20785. return (ret);
  20786. {
  20787. xmlChar *localName = NULL;
  20788. xmlChar *prefix = NULL;
  20789. localName = xmlSplitQName2(value, &prefix);
  20790. if (prefix != NULL) {
  20791. const xmlChar *nsName = NULL;
  20792. if (vctxt != NULL)
  20793. nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
  20794. else if (node != NULL) {
  20795. xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
  20796. if (ns != NULL)
  20797. nsName = ns->href;
  20798. } else {
  20799. xmlFree(prefix);
  20800. xmlFree(localName);
  20801. return (1);
  20802. }
  20803. if (nsName == NULL) {
  20804. xmlFree(prefix);
  20805. xmlFree(localName);
  20806. return (1);
  20807. }
  20808. if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
  20809. if ((valNeeded) && (val != NULL)) {
  20810. (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
  20811. xmlStrdup(nsName));
  20812. if (*val == NULL)
  20813. ret = -1;
  20814. }
  20815. } else
  20816. ret = 1;
  20817. xmlFree(prefix);
  20818. xmlFree(localName);
  20819. } else {
  20820. if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
  20821. if (valNeeded && (val != NULL)) {
  20822. (*val) = xmlSchemaNewNOTATIONValue(
  20823. BAD_CAST xmlStrdup(value), NULL);
  20824. if (*val == NULL)
  20825. ret = -1;
  20826. }
  20827. } else
  20828. return (1);
  20829. }
  20830. }
  20831. return (ret);
  20832. }
  20833. static int
  20834. xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
  20835. const xmlChar* lname,
  20836. const xmlChar* nsname)
  20837. {
  20838. int i;
  20839. lname = xmlDictLookup(vctxt->dict, lname, -1);
  20840. if (lname == NULL)
  20841. return(-1);
  20842. if (nsname != NULL) {
  20843. nsname = xmlDictLookup(vctxt->dict, nsname, -1);
  20844. if (nsname == NULL)
  20845. return(-1);
  20846. }
  20847. for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
  20848. if ((vctxt->nodeQNames->items [i] == lname) &&
  20849. (vctxt->nodeQNames->items[i +1] == nsname))
  20850. /* Already there */
  20851. return(i);
  20852. }
  20853. /* Add new entry. */
  20854. i = vctxt->nodeQNames->nbItems;
  20855. xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
  20856. xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
  20857. return(i);
  20858. }
  20859. /************************************************************************
  20860. * *
  20861. * Validation of identity-constraints (IDC) *
  20862. * *
  20863. ************************************************************************/
  20864. /**
  20865. * xmlSchemaAugmentIDC:
  20866. * @idcDef: the IDC definition
  20867. *
  20868. * Creates an augmented IDC definition item.
  20869. *
  20870. * Returns the item, or NULL on internal errors.
  20871. */
  20872. static void
  20873. xmlSchemaAugmentIDC(void *payload, void *data,
  20874. const xmlChar *name ATTRIBUTE_UNUSED)
  20875. {
  20876. xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
  20877. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
  20878. xmlSchemaIDCAugPtr aidc;
  20879. aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
  20880. if (aidc == NULL) {
  20881. xmlSchemaVErrMemory(vctxt,
  20882. "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
  20883. NULL);
  20884. return;
  20885. }
  20886. aidc->keyrefDepth = -1;
  20887. aidc->def = idcDef;
  20888. aidc->next = NULL;
  20889. if (vctxt->aidcs == NULL)
  20890. vctxt->aidcs = aidc;
  20891. else {
  20892. aidc->next = vctxt->aidcs;
  20893. vctxt->aidcs = aidc;
  20894. }
  20895. /*
  20896. * Save if we have keyrefs at all.
  20897. */
  20898. if ((vctxt->hasKeyrefs == 0) &&
  20899. (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
  20900. vctxt->hasKeyrefs = 1;
  20901. }
  20902. /**
  20903. * xmlSchemaAugmentImportedIDC:
  20904. * @imported: the imported schema
  20905. *
  20906. * Creates an augmented IDC definition for the imported schema.
  20907. */
  20908. static void
  20909. xmlSchemaAugmentImportedIDC(void *payload, void *data,
  20910. const xmlChar *name ATTRIBUTE_UNUSED) {
  20911. xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
  20912. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
  20913. if (imported->schema->idcDef != NULL) {
  20914. xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
  20915. }
  20916. }
  20917. /**
  20918. * xmlSchemaIDCNewBinding:
  20919. * @idcDef: the IDC definition of this binding
  20920. *
  20921. * Creates a new IDC binding.
  20922. *
  20923. * Returns the new IDC binding, NULL on internal errors.
  20924. */
  20925. static xmlSchemaPSVIIDCBindingPtr
  20926. xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
  20927. {
  20928. xmlSchemaPSVIIDCBindingPtr ret;
  20929. ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
  20930. sizeof(xmlSchemaPSVIIDCBinding));
  20931. if (ret == NULL) {
  20932. xmlSchemaVErrMemory(NULL,
  20933. "allocating a PSVI IDC binding item", NULL);
  20934. return (NULL);
  20935. }
  20936. memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
  20937. ret->definition = idcDef;
  20938. return (ret);
  20939. }
  20940. /**
  20941. * xmlSchemaIDCStoreNodeTableItem:
  20942. * @vctxt: the WXS validation context
  20943. * @item: the IDC node table item
  20944. *
  20945. * The validation context is used to store IDC node table items.
  20946. * They are stored to avoid copying them if IDC node-tables are merged
  20947. * with corresponding parent IDC node-tables (bubbling).
  20948. *
  20949. * Returns 0 if succeeded, -1 on internal errors.
  20950. */
  20951. static int
  20952. xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
  20953. xmlSchemaPSVIIDCNodePtr item)
  20954. {
  20955. /*
  20956. * Add to global list.
  20957. */
  20958. if (vctxt->idcNodes == NULL) {
  20959. vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
  20960. xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
  20961. if (vctxt->idcNodes == NULL) {
  20962. xmlSchemaVErrMemory(vctxt,
  20963. "allocating the IDC node table item list", NULL);
  20964. return (-1);
  20965. }
  20966. vctxt->sizeIdcNodes = 20;
  20967. } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
  20968. vctxt->sizeIdcNodes *= 2;
  20969. vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
  20970. xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
  20971. sizeof(xmlSchemaPSVIIDCNodePtr));
  20972. if (vctxt->idcNodes == NULL) {
  20973. xmlSchemaVErrMemory(vctxt,
  20974. "re-allocating the IDC node table item list", NULL);
  20975. return (-1);
  20976. }
  20977. }
  20978. vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
  20979. return (0);
  20980. }
  20981. /**
  20982. * xmlSchemaIDCStoreKey:
  20983. * @vctxt: the WXS validation context
  20984. * @item: the IDC key
  20985. *
  20986. * The validation context is used to store an IDC key.
  20987. *
  20988. * Returns 0 if succeeded, -1 on internal errors.
  20989. */
  20990. static int
  20991. xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
  20992. xmlSchemaPSVIIDCKeyPtr key)
  20993. {
  20994. /*
  20995. * Add to global list.
  20996. */
  20997. if (vctxt->idcKeys == NULL) {
  20998. vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
  20999. xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
  21000. if (vctxt->idcKeys == NULL) {
  21001. xmlSchemaVErrMemory(vctxt,
  21002. "allocating the IDC key storage list", NULL);
  21003. return (-1);
  21004. }
  21005. vctxt->sizeIdcKeys = 40;
  21006. } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
  21007. vctxt->sizeIdcKeys *= 2;
  21008. vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
  21009. xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
  21010. sizeof(xmlSchemaPSVIIDCKeyPtr));
  21011. if (vctxt->idcKeys == NULL) {
  21012. xmlSchemaVErrMemory(vctxt,
  21013. "re-allocating the IDC key storage list", NULL);
  21014. return (-1);
  21015. }
  21016. }
  21017. vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
  21018. return (0);
  21019. }
  21020. /**
  21021. * xmlSchemaIDCAppendNodeTableItem:
  21022. * @bind: the IDC binding
  21023. * @ntItem: the node-table item
  21024. *
  21025. * Appends the IDC node-table item to the binding.
  21026. *
  21027. * Returns 0 on success and -1 on internal errors.
  21028. */
  21029. static int
  21030. xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
  21031. xmlSchemaPSVIIDCNodePtr ntItem)
  21032. {
  21033. if (bind->nodeTable == NULL) {
  21034. bind->sizeNodes = 10;
  21035. bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  21036. xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
  21037. if (bind->nodeTable == NULL) {
  21038. xmlSchemaVErrMemory(NULL,
  21039. "allocating an array of IDC node-table items", NULL);
  21040. return(-1);
  21041. }
  21042. } else if (bind->sizeNodes <= bind->nbNodes) {
  21043. bind->sizeNodes *= 2;
  21044. bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  21045. xmlRealloc(bind->nodeTable, bind->sizeNodes *
  21046. sizeof(xmlSchemaPSVIIDCNodePtr));
  21047. if (bind->nodeTable == NULL) {
  21048. xmlSchemaVErrMemory(NULL,
  21049. "re-allocating an array of IDC node-table items", NULL);
  21050. return(-1);
  21051. }
  21052. }
  21053. bind->nodeTable[bind->nbNodes++] = ntItem;
  21054. return(0);
  21055. }
  21056. /**
  21057. * xmlSchemaIDCAcquireBinding:
  21058. * @vctxt: the WXS validation context
  21059. * @matcher: the IDC matcher
  21060. *
  21061. * Looks up an PSVI IDC binding, for the IDC definition and
  21062. * of the given matcher. If none found, a new one is created
  21063. * and added to the IDC table.
  21064. *
  21065. * Returns an IDC binding or NULL on internal errors.
  21066. */
  21067. static xmlSchemaPSVIIDCBindingPtr
  21068. xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
  21069. xmlSchemaIDCMatcherPtr matcher)
  21070. {
  21071. xmlSchemaNodeInfoPtr ielem;
  21072. ielem = vctxt->elemInfos[matcher->depth];
  21073. if (ielem->idcTable == NULL) {
  21074. ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
  21075. if (ielem->idcTable == NULL)
  21076. return (NULL);
  21077. return(ielem->idcTable);
  21078. } else {
  21079. xmlSchemaPSVIIDCBindingPtr bind = NULL;
  21080. bind = ielem->idcTable;
  21081. do {
  21082. if (bind->definition == matcher->aidc->def)
  21083. return(bind);
  21084. if (bind->next == NULL) {
  21085. bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
  21086. if (bind->next == NULL)
  21087. return (NULL);
  21088. return(bind->next);
  21089. }
  21090. bind = bind->next;
  21091. } while (bind != NULL);
  21092. }
  21093. return (NULL);
  21094. }
  21095. static xmlSchemaItemListPtr
  21096. xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
  21097. xmlSchemaIDCMatcherPtr matcher)
  21098. {
  21099. if (matcher->targets == NULL)
  21100. matcher->targets = xmlSchemaItemListCreate();
  21101. return(matcher->targets);
  21102. }
  21103. /**
  21104. * xmlSchemaIDCFreeKey:
  21105. * @key: the IDC key
  21106. *
  21107. * Frees an IDC key together with its compiled value.
  21108. */
  21109. static void
  21110. xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
  21111. {
  21112. if (key->val != NULL)
  21113. xmlSchemaFreeValue(key->val);
  21114. xmlFree(key);
  21115. }
  21116. /**
  21117. * xmlSchemaIDCFreeBinding:
  21118. *
  21119. * Frees an IDC binding. Note that the node table-items
  21120. * are not freed.
  21121. */
  21122. static void
  21123. xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
  21124. {
  21125. if (bind->nodeTable != NULL)
  21126. xmlFree(bind->nodeTable);
  21127. if (bind->dupls != NULL)
  21128. xmlSchemaItemListFree(bind->dupls);
  21129. xmlFree(bind);
  21130. }
  21131. /**
  21132. * xmlSchemaIDCFreeIDCTable:
  21133. * @bind: the first IDC binding in the list
  21134. *
  21135. * Frees an IDC table, i.e. all the IDC bindings in the list.
  21136. */
  21137. static void
  21138. xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
  21139. {
  21140. xmlSchemaPSVIIDCBindingPtr prev;
  21141. while (bind != NULL) {
  21142. prev = bind;
  21143. bind = bind->next;
  21144. xmlSchemaIDCFreeBinding(prev);
  21145. }
  21146. }
  21147. static void
  21148. xmlFreeIDCHashEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
  21149. {
  21150. xmlIDCHashEntryPtr e = payload, n;
  21151. while (e) {
  21152. n = e->next;
  21153. xmlFree(e);
  21154. e = n;
  21155. }
  21156. }
  21157. /**
  21158. * xmlSchemaIDCFreeMatcherList:
  21159. * @matcher: the first IDC matcher in the list
  21160. *
  21161. * Frees a list of IDC matchers.
  21162. */
  21163. static void
  21164. xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
  21165. {
  21166. xmlSchemaIDCMatcherPtr next;
  21167. while (matcher != NULL) {
  21168. next = matcher->next;
  21169. if (matcher->keySeqs != NULL) {
  21170. int i;
  21171. for (i = 0; i < matcher->sizeKeySeqs; i++)
  21172. if (matcher->keySeqs[i] != NULL)
  21173. xmlFree(matcher->keySeqs[i]);
  21174. xmlFree(matcher->keySeqs);
  21175. }
  21176. if (matcher->targets != NULL) {
  21177. if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21178. int i;
  21179. xmlSchemaPSVIIDCNodePtr idcNode;
  21180. /*
  21181. * Node-table items for keyrefs are not stored globally
  21182. * to the validation context, since they are not bubbled.
  21183. * We need to free them here.
  21184. */
  21185. for (i = 0; i < matcher->targets->nbItems; i++) {
  21186. idcNode =
  21187. (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
  21188. xmlFree(idcNode->keys);
  21189. xmlFree(idcNode);
  21190. }
  21191. }
  21192. xmlSchemaItemListFree(matcher->targets);
  21193. }
  21194. if (matcher->htab != NULL)
  21195. xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
  21196. xmlFree(matcher);
  21197. matcher = next;
  21198. }
  21199. }
  21200. /**
  21201. * xmlSchemaIDCReleaseMatcherList:
  21202. * @vctxt: the WXS validation context
  21203. * @matcher: the first IDC matcher in the list
  21204. *
  21205. * Caches a list of IDC matchers for reuse.
  21206. */
  21207. static void
  21208. xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
  21209. xmlSchemaIDCMatcherPtr matcher)
  21210. {
  21211. xmlSchemaIDCMatcherPtr next;
  21212. while (matcher != NULL) {
  21213. next = matcher->next;
  21214. if (matcher->keySeqs != NULL) {
  21215. int i;
  21216. /*
  21217. * Don't free the array, but only the content.
  21218. */
  21219. for (i = 0; i < matcher->sizeKeySeqs; i++)
  21220. if (matcher->keySeqs[i] != NULL) {
  21221. xmlFree(matcher->keySeqs[i]);
  21222. matcher->keySeqs[i] = NULL;
  21223. }
  21224. }
  21225. if (matcher->targets) {
  21226. if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21227. int i;
  21228. xmlSchemaPSVIIDCNodePtr idcNode;
  21229. /*
  21230. * Node-table items for keyrefs are not stored globally
  21231. * to the validation context, since they are not bubbled.
  21232. * We need to free them here.
  21233. */
  21234. for (i = 0; i < matcher->targets->nbItems; i++) {
  21235. idcNode =
  21236. (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
  21237. xmlFree(idcNode->keys);
  21238. xmlFree(idcNode);
  21239. }
  21240. }
  21241. xmlSchemaItemListFree(matcher->targets);
  21242. matcher->targets = NULL;
  21243. }
  21244. if (matcher->htab != NULL) {
  21245. xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
  21246. matcher->htab = NULL;
  21247. }
  21248. matcher->next = NULL;
  21249. /*
  21250. * Cache the matcher.
  21251. */
  21252. if (vctxt->idcMatcherCache != NULL)
  21253. matcher->nextCached = vctxt->idcMatcherCache;
  21254. vctxt->idcMatcherCache = matcher;
  21255. matcher = next;
  21256. }
  21257. }
  21258. /**
  21259. * xmlSchemaIDCAddStateObject:
  21260. * @vctxt: the WXS validation context
  21261. * @matcher: the IDC matcher
  21262. * @sel: the XPath information
  21263. * @parent: the parent "selector" state object if any
  21264. * @type: "selector" or "field"
  21265. *
  21266. * Creates/reuses and activates state objects for the given
  21267. * XPath information; if the XPath expression consists of unions,
  21268. * multiple state objects are created for every unioned expression.
  21269. *
  21270. * Returns 0 on success and -1 on internal errors.
  21271. */
  21272. static int
  21273. xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
  21274. xmlSchemaIDCMatcherPtr matcher,
  21275. xmlSchemaIDCSelectPtr sel,
  21276. int type)
  21277. {
  21278. xmlSchemaIDCStateObjPtr sto;
  21279. /*
  21280. * Reuse the state objects from the pool.
  21281. */
  21282. if (vctxt->xpathStatePool != NULL) {
  21283. sto = vctxt->xpathStatePool;
  21284. vctxt->xpathStatePool = sto->next;
  21285. sto->next = NULL;
  21286. } else {
  21287. /*
  21288. * Create a new state object.
  21289. */
  21290. sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
  21291. if (sto == NULL) {
  21292. xmlSchemaVErrMemory(NULL,
  21293. "allocating an IDC state object", NULL);
  21294. return (-1);
  21295. }
  21296. memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
  21297. }
  21298. /*
  21299. * Add to global list.
  21300. */
  21301. if (vctxt->xpathStates != NULL)
  21302. sto->next = vctxt->xpathStates;
  21303. vctxt->xpathStates = sto;
  21304. /*
  21305. * Free the old xpath validation context.
  21306. */
  21307. if (sto->xpathCtxt != NULL)
  21308. xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
  21309. /*
  21310. * Create a new XPath (pattern) validation context.
  21311. */
  21312. sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
  21313. (xmlPatternPtr) sel->xpathComp);
  21314. if (sto->xpathCtxt == NULL) {
  21315. VERROR_INT("xmlSchemaIDCAddStateObject",
  21316. "failed to create an XPath validation context");
  21317. return (-1);
  21318. }
  21319. sto->type = type;
  21320. sto->depth = vctxt->depth;
  21321. sto->matcher = matcher;
  21322. sto->sel = sel;
  21323. sto->nbHistory = 0;
  21324. #ifdef DEBUG_IDC
  21325. xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n",
  21326. sto->sel->xpath);
  21327. #endif
  21328. return (0);
  21329. }
  21330. /**
  21331. * xmlSchemaXPathEvaluate:
  21332. * @vctxt: the WXS validation context
  21333. * @nodeType: the nodeType of the current node
  21334. *
  21335. * Evaluates all active XPath state objects.
  21336. *
  21337. * Returns the number of IC "field" state objects which resolved to
  21338. * this node, 0 if none resolved and -1 on internal errors.
  21339. */
  21340. static int
  21341. xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
  21342. xmlElementType nodeType)
  21343. {
  21344. xmlSchemaIDCStateObjPtr sto, head = NULL, first;
  21345. int res, resolved = 0, depth = vctxt->depth;
  21346. if (vctxt->xpathStates == NULL)
  21347. return (0);
  21348. if (nodeType == XML_ATTRIBUTE_NODE)
  21349. depth++;
  21350. #ifdef DEBUG_IDC
  21351. {
  21352. xmlChar *str = NULL;
  21353. xmlGenericError(xmlGenericErrorContext,
  21354. "IDC: EVAL on %s, depth %d, type %d\n",
  21355. xmlSchemaFormatQName(&str, vctxt->inode->nsName,
  21356. vctxt->inode->localName), depth, nodeType);
  21357. FREE_AND_NULL(str)
  21358. }
  21359. #endif
  21360. /*
  21361. * Process all active XPath state objects.
  21362. */
  21363. first = vctxt->xpathStates;
  21364. sto = first;
  21365. while (sto != head) {
  21366. #ifdef DEBUG_IDC
  21367. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
  21368. xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n",
  21369. sto->matcher->aidc->def->name, sto->sel->xpath);
  21370. else
  21371. xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n",
  21372. sto->matcher->aidc->def->name, sto->sel->xpath);
  21373. #endif
  21374. if (nodeType == XML_ELEMENT_NODE)
  21375. res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
  21376. vctxt->inode->localName, vctxt->inode->nsName);
  21377. else
  21378. res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
  21379. vctxt->inode->localName, vctxt->inode->nsName);
  21380. if (res == -1) {
  21381. VERROR_INT("xmlSchemaXPathEvaluate",
  21382. "calling xmlStreamPush()");
  21383. return (-1);
  21384. }
  21385. if (res == 0)
  21386. goto next_sto;
  21387. /*
  21388. * Full match.
  21389. */
  21390. #ifdef DEBUG_IDC
  21391. xmlGenericError(xmlGenericErrorContext, "IDC: "
  21392. "MATCH\n");
  21393. #endif
  21394. /*
  21395. * Register a match in the state object history.
  21396. */
  21397. if (sto->history == NULL) {
  21398. sto->history = (int *) xmlMalloc(5 * sizeof(int));
  21399. if (sto->history == NULL) {
  21400. xmlSchemaVErrMemory(NULL,
  21401. "allocating the state object history", NULL);
  21402. return(-1);
  21403. }
  21404. sto->sizeHistory = 5;
  21405. } else if (sto->sizeHistory <= sto->nbHistory) {
  21406. sto->sizeHistory *= 2;
  21407. sto->history = (int *) xmlRealloc(sto->history,
  21408. sto->sizeHistory * sizeof(int));
  21409. if (sto->history == NULL) {
  21410. xmlSchemaVErrMemory(NULL,
  21411. "re-allocating the state object history", NULL);
  21412. return(-1);
  21413. }
  21414. }
  21415. sto->history[sto->nbHistory++] = depth;
  21416. #ifdef DEBUG_IDC
  21417. xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n",
  21418. vctxt->depth);
  21419. #endif
  21420. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
  21421. xmlSchemaIDCSelectPtr sel;
  21422. /*
  21423. * Activate state objects for the IDC fields of
  21424. * the IDC selector.
  21425. */
  21426. #ifdef DEBUG_IDC
  21427. xmlGenericError(xmlGenericErrorContext, "IDC: "
  21428. "activating field states\n");
  21429. #endif
  21430. sel = sto->matcher->aidc->def->fields;
  21431. while (sel != NULL) {
  21432. if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
  21433. sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
  21434. return (-1);
  21435. sel = sel->next;
  21436. }
  21437. } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
  21438. /*
  21439. * An IDC key node was found by the IDC field.
  21440. */
  21441. #ifdef DEBUG_IDC
  21442. xmlGenericError(xmlGenericErrorContext,
  21443. "IDC: key found\n");
  21444. #endif
  21445. /*
  21446. * Notify that the character value of this node is
  21447. * needed.
  21448. */
  21449. if (resolved == 0) {
  21450. if ((vctxt->inode->flags &
  21451. XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
  21452. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
  21453. }
  21454. resolved++;
  21455. }
  21456. next_sto:
  21457. if (sto->next == NULL) {
  21458. /*
  21459. * Evaluate field state objects created on this node as well.
  21460. */
  21461. head = first;
  21462. sto = vctxt->xpathStates;
  21463. } else
  21464. sto = sto->next;
  21465. }
  21466. return (resolved);
  21467. }
  21468. static const xmlChar *
  21469. xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt,
  21470. xmlChar **buf,
  21471. xmlSchemaPSVIIDCKeyPtr *seq,
  21472. int count, int for_hash)
  21473. {
  21474. int i, res;
  21475. xmlChar *value = NULL;
  21476. *buf = xmlStrdup(BAD_CAST "[");
  21477. for (i = 0; i < count; i++) {
  21478. *buf = xmlStrcat(*buf, BAD_CAST "'");
  21479. if (!for_hash)
  21480. res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
  21481. xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
  21482. &value);
  21483. else {
  21484. res = xmlSchemaGetCanonValueHash(seq[i]->val, &value);
  21485. }
  21486. if (res == 0)
  21487. *buf = xmlStrcat(*buf, BAD_CAST value);
  21488. else {
  21489. VERROR_INT("xmlSchemaFormatIDCKeySequence",
  21490. "failed to compute a canonical value");
  21491. *buf = xmlStrcat(*buf, BAD_CAST "???");
  21492. }
  21493. if (i < count -1)
  21494. *buf = xmlStrcat(*buf, BAD_CAST "', ");
  21495. else
  21496. *buf = xmlStrcat(*buf, BAD_CAST "'");
  21497. if (value != NULL) {
  21498. xmlFree(value);
  21499. value = NULL;
  21500. }
  21501. }
  21502. *buf = xmlStrcat(*buf, BAD_CAST "]");
  21503. return (BAD_CAST *buf);
  21504. }
  21505. static const xmlChar *
  21506. xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
  21507. xmlChar **buf,
  21508. xmlSchemaPSVIIDCKeyPtr *seq,
  21509. int count)
  21510. {
  21511. return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 0);
  21512. }
  21513. static const xmlChar *
  21514. xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt,
  21515. xmlChar **buf,
  21516. xmlSchemaPSVIIDCKeyPtr *seq,
  21517. int count)
  21518. {
  21519. return xmlSchemaFormatIDCKeySequence_1(vctxt, buf, seq, count, 1);
  21520. }
  21521. /**
  21522. * xmlSchemaXPathPop:
  21523. * @vctxt: the WXS validation context
  21524. *
  21525. * Pops all XPath states.
  21526. *
  21527. * Returns 0 on success and -1 on internal errors.
  21528. */
  21529. static int
  21530. xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
  21531. {
  21532. xmlSchemaIDCStateObjPtr sto;
  21533. int res;
  21534. if (vctxt->xpathStates == NULL)
  21535. return(0);
  21536. sto = vctxt->xpathStates;
  21537. do {
  21538. res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
  21539. if (res == -1)
  21540. return (-1);
  21541. sto = sto->next;
  21542. } while (sto != NULL);
  21543. return(0);
  21544. }
  21545. /**
  21546. * xmlSchemaXPathProcessHistory:
  21547. * @vctxt: the WXS validation context
  21548. * @type: the simple/complex type of the current node if any at all
  21549. * @val: the precompiled value
  21550. *
  21551. * Processes and pops the history items of the IDC state objects.
  21552. * IDC key-sequences are validated/created on IDC bindings.
  21553. *
  21554. * Returns 0 on success and -1 on internal errors.
  21555. */
  21556. static int
  21557. xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
  21558. int depth)
  21559. {
  21560. xmlSchemaIDCStateObjPtr sto, nextsto;
  21561. int res, matchDepth;
  21562. xmlSchemaPSVIIDCKeyPtr key = NULL;
  21563. xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
  21564. if (vctxt->xpathStates == NULL)
  21565. return (0);
  21566. sto = vctxt->xpathStates;
  21567. #ifdef DEBUG_IDC
  21568. {
  21569. xmlChar *str = NULL;
  21570. xmlGenericError(xmlGenericErrorContext,
  21571. "IDC: BACK on %s, depth %d\n",
  21572. xmlSchemaFormatQName(&str, vctxt->inode->nsName,
  21573. vctxt->inode->localName), vctxt->depth);
  21574. FREE_AND_NULL(str)
  21575. }
  21576. #endif
  21577. /*
  21578. * Evaluate the state objects.
  21579. */
  21580. while (sto != NULL) {
  21581. res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
  21582. if (res == -1) {
  21583. VERROR_INT("xmlSchemaXPathProcessHistory",
  21584. "calling xmlStreamPop()");
  21585. return (-1);
  21586. }
  21587. #ifdef DEBUG_IDC
  21588. xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n",
  21589. sto->sel->xpath);
  21590. #endif
  21591. if (sto->nbHistory == 0)
  21592. goto deregister_check;
  21593. matchDepth = sto->history[sto->nbHistory -1];
  21594. /*
  21595. * Only matches at the current depth are of interest.
  21596. */
  21597. if (matchDepth != depth) {
  21598. sto = sto->next;
  21599. continue;
  21600. }
  21601. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
  21602. /*
  21603. * NOTE: According to
  21604. * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
  21605. * ... the simple-content of complex types is also allowed.
  21606. */
  21607. if (WXS_IS_COMPLEX(type)) {
  21608. if (WXS_HAS_SIMPLE_CONTENT(type)) {
  21609. /*
  21610. * Sanity check for complex types with simple content.
  21611. */
  21612. simpleType = type->contentTypeDef;
  21613. if (simpleType == NULL) {
  21614. VERROR_INT("xmlSchemaXPathProcessHistory",
  21615. "field resolves to a CT with simple content "
  21616. "but the CT is missing the ST definition");
  21617. return (-1);
  21618. }
  21619. } else
  21620. simpleType = NULL;
  21621. } else
  21622. simpleType = type;
  21623. if (simpleType == NULL) {
  21624. xmlChar *str = NULL;
  21625. /*
  21626. * Not qualified if the field resolves to a node of non
  21627. * simple type.
  21628. */
  21629. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21630. XML_SCHEMAV_CVC_IDC, NULL,
  21631. WXS_BASIC_CAST sto->matcher->aidc->def,
  21632. "The XPath '%s' of a field of %s does evaluate to a node of "
  21633. "non-simple type",
  21634. sto->sel->xpath,
  21635. xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
  21636. FREE_AND_NULL(str);
  21637. sto->nbHistory--;
  21638. goto deregister_check;
  21639. }
  21640. if ((key == NULL) && (vctxt->inode->val == NULL)) {
  21641. /*
  21642. * Failed to provide the normalized value; maybe
  21643. * the value was invalid.
  21644. */
  21645. VERROR(XML_SCHEMAV_CVC_IDC,
  21646. WXS_BASIC_CAST sto->matcher->aidc->def,
  21647. "Warning: No precomputed value available, the value "
  21648. "was either invalid or something strange happened");
  21649. sto->nbHistory--;
  21650. goto deregister_check;
  21651. } else {
  21652. xmlSchemaIDCMatcherPtr matcher = sto->matcher;
  21653. xmlSchemaPSVIIDCKeyPtr *keySeq;
  21654. int pos, idx;
  21655. /*
  21656. * The key will be anchored on the matcher's list of
  21657. * key-sequences. The position in this list is determined
  21658. * by the target node's depth relative to the matcher's
  21659. * depth of creation (i.e. the depth of the scope element).
  21660. *
  21661. * Element Depth Pos List-entries
  21662. * <scope> 0 NULL
  21663. * <bar> 1 NULL
  21664. * <target/> 2 2 target
  21665. * <bar>
  21666. * </scope>
  21667. *
  21668. * The size of the list is only dependent on the depth of
  21669. * the tree.
  21670. * An entry will be NULLed in selector_leave, i.e. when
  21671. * we hit the target's
  21672. */
  21673. pos = sto->depth - matcher->depth;
  21674. idx = sto->sel->index;
  21675. /*
  21676. * Create/grow the array of key-sequences.
  21677. */
  21678. if (matcher->keySeqs == NULL) {
  21679. if (pos > 9)
  21680. matcher->sizeKeySeqs = pos * 2;
  21681. else
  21682. matcher->sizeKeySeqs = 10;
  21683. matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
  21684. xmlMalloc(matcher->sizeKeySeqs *
  21685. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21686. if (matcher->keySeqs == NULL) {
  21687. xmlSchemaVErrMemory(NULL,
  21688. "allocating an array of key-sequences",
  21689. NULL);
  21690. return(-1);
  21691. }
  21692. memset(matcher->keySeqs, 0,
  21693. matcher->sizeKeySeqs *
  21694. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21695. } else if (pos >= matcher->sizeKeySeqs) {
  21696. int i = matcher->sizeKeySeqs;
  21697. matcher->sizeKeySeqs *= 2;
  21698. matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
  21699. xmlRealloc(matcher->keySeqs,
  21700. matcher->sizeKeySeqs *
  21701. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21702. if (matcher->keySeqs == NULL) {
  21703. xmlSchemaVErrMemory(NULL,
  21704. "reallocating an array of key-sequences",
  21705. NULL);
  21706. return (-1);
  21707. }
  21708. /*
  21709. * The array needs to be NULLed.
  21710. * TODO: Use memset?
  21711. */
  21712. for (; i < matcher->sizeKeySeqs; i++)
  21713. matcher->keySeqs[i] = NULL;
  21714. }
  21715. /*
  21716. * Get/create the key-sequence.
  21717. */
  21718. keySeq = matcher->keySeqs[pos];
  21719. if (keySeq == NULL) {
  21720. goto create_sequence;
  21721. } else if (keySeq[idx] != NULL) {
  21722. xmlChar *str = NULL;
  21723. /*
  21724. * cvc-identity-constraint:
  21725. * 3 For each node in the `target node set` all
  21726. * of the {fields}, with that node as the context
  21727. * node, evaluate to either an empty node-set or
  21728. * a node-set with exactly one member, which must
  21729. * have a simple type.
  21730. *
  21731. * The key was already set; report an error.
  21732. */
  21733. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21734. XML_SCHEMAV_CVC_IDC, NULL,
  21735. WXS_BASIC_CAST matcher->aidc->def,
  21736. "The XPath '%s' of a field of %s evaluates to a "
  21737. "node-set with more than one member",
  21738. sto->sel->xpath,
  21739. xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
  21740. FREE_AND_NULL(str);
  21741. sto->nbHistory--;
  21742. goto deregister_check;
  21743. } else
  21744. goto create_key;
  21745. create_sequence:
  21746. /*
  21747. * Create a key-sequence.
  21748. */
  21749. keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
  21750. matcher->aidc->def->nbFields *
  21751. sizeof(xmlSchemaPSVIIDCKeyPtr));
  21752. if (keySeq == NULL) {
  21753. xmlSchemaVErrMemory(NULL,
  21754. "allocating an IDC key-sequence", NULL);
  21755. return(-1);
  21756. }
  21757. memset(keySeq, 0, matcher->aidc->def->nbFields *
  21758. sizeof(xmlSchemaPSVIIDCKeyPtr));
  21759. matcher->keySeqs[pos] = keySeq;
  21760. create_key:
  21761. /*
  21762. * Create a key once per node only.
  21763. */
  21764. if (key == NULL) {
  21765. key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
  21766. sizeof(xmlSchemaPSVIIDCKey));
  21767. if (key == NULL) {
  21768. xmlSchemaVErrMemory(NULL,
  21769. "allocating a IDC key", NULL);
  21770. xmlFree(keySeq);
  21771. matcher->keySeqs[pos] = NULL;
  21772. return(-1);
  21773. }
  21774. /*
  21775. * Consume the compiled value.
  21776. */
  21777. key->type = simpleType;
  21778. key->val = vctxt->inode->val;
  21779. vctxt->inode->val = NULL;
  21780. /*
  21781. * Store the key in a global list.
  21782. */
  21783. if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
  21784. xmlSchemaIDCFreeKey(key);
  21785. return (-1);
  21786. }
  21787. }
  21788. keySeq[idx] = key;
  21789. }
  21790. } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
  21791. xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
  21792. /* xmlSchemaPSVIIDCBindingPtr bind; */
  21793. xmlSchemaPSVIIDCNodePtr ntItem;
  21794. xmlSchemaIDCMatcherPtr matcher;
  21795. xmlSchemaIDCPtr idc;
  21796. xmlSchemaItemListPtr targets;
  21797. int pos, i, j, nbKeys;
  21798. /*
  21799. * Here we have the following scenario:
  21800. * An IDC 'selector' state object resolved to a target node,
  21801. * during the time this target node was in the
  21802. * ancestor-or-self axis, the 'field' state object(s) looked
  21803. * out for matching nodes to create a key-sequence for this
  21804. * target node. Now we are back to this target node and need
  21805. * to put the key-sequence, together with the target node
  21806. * itself, into the node-table of the corresponding IDC
  21807. * binding.
  21808. */
  21809. matcher = sto->matcher;
  21810. idc = matcher->aidc->def;
  21811. nbKeys = idc->nbFields;
  21812. pos = depth - matcher->depth;
  21813. /*
  21814. * Check if the matcher has any key-sequences at all, plus
  21815. * if it has a key-sequence for the current target node.
  21816. */
  21817. if ((matcher->keySeqs == NULL) ||
  21818. (matcher->sizeKeySeqs <= pos)) {
  21819. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
  21820. goto selector_key_error;
  21821. else
  21822. goto selector_leave;
  21823. }
  21824. keySeq = &(matcher->keySeqs[pos]);
  21825. if (*keySeq == NULL) {
  21826. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
  21827. goto selector_key_error;
  21828. else
  21829. goto selector_leave;
  21830. }
  21831. for (i = 0; i < nbKeys; i++) {
  21832. if ((*keySeq)[i] == NULL) {
  21833. /*
  21834. * Not qualified, if not all fields did resolve.
  21835. */
  21836. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
  21837. /*
  21838. * All fields of a "key" IDC must resolve.
  21839. */
  21840. goto selector_key_error;
  21841. }
  21842. goto selector_leave;
  21843. }
  21844. }
  21845. /*
  21846. * All fields did resolve.
  21847. */
  21848. /*
  21849. * 4.1 If the {identity-constraint category} is unique(/key),
  21850. * then no two members of the `qualified node set` have
  21851. * `key-sequences` whose members are pairwise equal, as
  21852. * defined by Equal in [XML Schemas: Datatypes].
  21853. *
  21854. * Get the IDC binding from the matcher and check for
  21855. * duplicate key-sequences.
  21856. */
  21857. #if 0
  21858. bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
  21859. #endif
  21860. targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
  21861. if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
  21862. (targets->nbItems != 0)) {
  21863. xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
  21864. xmlIDCHashEntryPtr e;
  21865. res = 0;
  21866. if (!matcher->htab)
  21867. e = NULL;
  21868. else {
  21869. xmlChar *value = NULL;
  21870. xmlSchemaHashKeySequence(vctxt, &value, *keySeq, nbKeys);
  21871. e = xmlHashLookup(matcher->htab, value);
  21872. FREE_AND_NULL(value);
  21873. }
  21874. /*
  21875. * Compare the key-sequences, key by key.
  21876. */
  21877. for (;e; e = e->next) {
  21878. bkeySeq =
  21879. ((xmlSchemaPSVIIDCNodePtr) targets->items[e->index])->keys;
  21880. for (j = 0; j < nbKeys; j++) {
  21881. ckey = (*keySeq)[j];
  21882. bkey = bkeySeq[j];
  21883. res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
  21884. if (res == -1) {
  21885. return (-1);
  21886. } else if (res == 0) {
  21887. /*
  21888. * One of the keys differs, so the key-sequence
  21889. * won't be equal; get out.
  21890. */
  21891. break;
  21892. }
  21893. }
  21894. if (res == 1) {
  21895. /*
  21896. * Duplicate key-sequence found.
  21897. */
  21898. break;
  21899. }
  21900. }
  21901. if (e) {
  21902. xmlChar *str = NULL, *strB = NULL;
  21903. /*
  21904. * TODO: Try to report the key-sequence.
  21905. */
  21906. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21907. XML_SCHEMAV_CVC_IDC, NULL,
  21908. WXS_BASIC_CAST idc,
  21909. "Duplicate key-sequence %s in %s",
  21910. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  21911. (*keySeq), nbKeys),
  21912. xmlSchemaGetIDCDesignation(&strB, idc));
  21913. FREE_AND_NULL(str);
  21914. FREE_AND_NULL(strB);
  21915. goto selector_leave;
  21916. }
  21917. }
  21918. /*
  21919. * Add a node-table item to the IDC binding.
  21920. */
  21921. ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
  21922. sizeof(xmlSchemaPSVIIDCNode));
  21923. if (ntItem == NULL) {
  21924. xmlSchemaVErrMemory(NULL,
  21925. "allocating an IDC node-table item", NULL);
  21926. xmlFree(*keySeq);
  21927. *keySeq = NULL;
  21928. return(-1);
  21929. }
  21930. memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
  21931. /*
  21932. * Store the node-table item in a global list.
  21933. */
  21934. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
  21935. if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
  21936. xmlFree(ntItem);
  21937. xmlFree(*keySeq);
  21938. *keySeq = NULL;
  21939. return (-1);
  21940. }
  21941. ntItem->nodeQNameID = -1;
  21942. } else {
  21943. /*
  21944. * Save a cached QName for this node on the IDC node, to be
  21945. * able to report it, even if the node is not saved.
  21946. */
  21947. ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
  21948. vctxt->inode->localName, vctxt->inode->nsName);
  21949. if (ntItem->nodeQNameID == -1) {
  21950. xmlFree(ntItem);
  21951. xmlFree(*keySeq);
  21952. *keySeq = NULL;
  21953. return (-1);
  21954. }
  21955. }
  21956. /*
  21957. * Init the node-table item: Save the node, position and
  21958. * consume the key-sequence.
  21959. */
  21960. ntItem->node = vctxt->node;
  21961. ntItem->nodeLine = vctxt->inode->nodeLine;
  21962. ntItem->keys = *keySeq;
  21963. *keySeq = NULL;
  21964. #if 0
  21965. if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
  21966. #endif
  21967. if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
  21968. if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21969. /*
  21970. * Free the item, since keyref items won't be
  21971. * put on a global list.
  21972. */
  21973. xmlFree(ntItem->keys);
  21974. xmlFree(ntItem);
  21975. }
  21976. return (-1);
  21977. }
  21978. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
  21979. xmlChar *value = NULL;
  21980. xmlIDCHashEntryPtr r, e;
  21981. if (!matcher->htab)
  21982. matcher->htab = xmlHashCreate(4);
  21983. xmlSchemaHashKeySequence(vctxt, &value, ntItem->keys, nbKeys);
  21984. e = xmlMalloc(sizeof *e);
  21985. e->index = targets->nbItems - 1;
  21986. r = xmlHashLookup(matcher->htab, value);
  21987. if (r) {
  21988. e->next = r->next;
  21989. r->next = e;
  21990. } else {
  21991. e->next = NULL;
  21992. xmlHashAddEntry(matcher->htab, value, e);
  21993. }
  21994. FREE_AND_NULL(value);
  21995. }
  21996. goto selector_leave;
  21997. selector_key_error:
  21998. {
  21999. xmlChar *str = NULL;
  22000. /*
  22001. * 4.2.1 (KEY) The `target node set` and the
  22002. * `qualified node set` are equal, that is, every
  22003. * member of the `target node set` is also a member
  22004. * of the `qualified node set` and vice versa.
  22005. */
  22006. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  22007. XML_SCHEMAV_CVC_IDC, NULL,
  22008. WXS_BASIC_CAST idc,
  22009. "Not all fields of %s evaluate to a node",
  22010. xmlSchemaGetIDCDesignation(&str, idc), NULL);
  22011. FREE_AND_NULL(str);
  22012. }
  22013. selector_leave:
  22014. /*
  22015. * Free the key-sequence if not added to the IDC table.
  22016. */
  22017. if ((keySeq != NULL) && (*keySeq != NULL)) {
  22018. xmlFree(*keySeq);
  22019. *keySeq = NULL;
  22020. }
  22021. } /* if selector */
  22022. sto->nbHistory--;
  22023. deregister_check:
  22024. /*
  22025. * Deregister state objects if they reach the depth of creation.
  22026. */
  22027. if ((sto->nbHistory == 0) && (sto->depth == depth)) {
  22028. #ifdef DEBUG_IDC
  22029. xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n",
  22030. sto->sel->xpath);
  22031. #endif
  22032. if (vctxt->xpathStates != sto) {
  22033. VERROR_INT("xmlSchemaXPathProcessHistory",
  22034. "The state object to be removed is not the first "
  22035. "in the list");
  22036. }
  22037. nextsto = sto->next;
  22038. /*
  22039. * Unlink from the list of active XPath state objects.
  22040. */
  22041. vctxt->xpathStates = sto->next;
  22042. sto->next = vctxt->xpathStatePool;
  22043. /*
  22044. * Link it to the pool of reusable state objects.
  22045. */
  22046. vctxt->xpathStatePool = sto;
  22047. sto = nextsto;
  22048. } else
  22049. sto = sto->next;
  22050. } /* while (sto != NULL) */
  22051. return (0);
  22052. }
  22053. /**
  22054. * xmlSchemaIDCRegisterMatchers:
  22055. * @vctxt: the WXS validation context
  22056. * @elemDecl: the element declaration
  22057. *
  22058. * Creates helper objects to evaluate IDC selectors/fields
  22059. * successively.
  22060. *
  22061. * Returns 0 if OK and -1 on internal errors.
  22062. */
  22063. static int
  22064. xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
  22065. xmlSchemaElementPtr elemDecl)
  22066. {
  22067. xmlSchemaIDCMatcherPtr matcher, last = NULL;
  22068. xmlSchemaIDCPtr idc, refIdc;
  22069. xmlSchemaIDCAugPtr aidc;
  22070. idc = (xmlSchemaIDCPtr) elemDecl->idcs;
  22071. if (idc == NULL)
  22072. return (0);
  22073. #ifdef DEBUG_IDC
  22074. {
  22075. xmlChar *str = NULL;
  22076. xmlGenericError(xmlGenericErrorContext,
  22077. "IDC: REGISTER on %s, depth %d\n",
  22078. (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
  22079. vctxt->inode->localName), vctxt->depth);
  22080. FREE_AND_NULL(str)
  22081. }
  22082. #endif
  22083. if (vctxt->inode->idcMatchers != NULL) {
  22084. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  22085. "The chain of IDC matchers is expected to be empty");
  22086. return (-1);
  22087. }
  22088. do {
  22089. if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  22090. /*
  22091. * Since IDCs bubbles are expensive we need to know the
  22092. * depth at which the bubbles should stop; this will be
  22093. * the depth of the top-most keyref IDC. If no keyref
  22094. * references a key/unique IDC, the keyrefDepth will
  22095. * be -1, indicating that no bubbles are needed.
  22096. */
  22097. refIdc = (xmlSchemaIDCPtr) idc->ref->item;
  22098. if (refIdc != NULL) {
  22099. /*
  22100. * Remember that we have keyrefs on this node.
  22101. */
  22102. vctxt->inode->hasKeyrefs = 1;
  22103. /*
  22104. * Lookup the referenced augmented IDC info.
  22105. */
  22106. aidc = vctxt->aidcs;
  22107. while (aidc != NULL) {
  22108. if (aidc->def == refIdc)
  22109. break;
  22110. aidc = aidc->next;
  22111. }
  22112. if (aidc == NULL) {
  22113. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  22114. "Could not find an augmented IDC item for an IDC "
  22115. "definition");
  22116. return (-1);
  22117. }
  22118. if ((aidc->keyrefDepth == -1) ||
  22119. (vctxt->depth < aidc->keyrefDepth))
  22120. aidc->keyrefDepth = vctxt->depth;
  22121. }
  22122. }
  22123. /*
  22124. * Lookup the augmented IDC item for the IDC definition.
  22125. */
  22126. aidc = vctxt->aidcs;
  22127. while (aidc != NULL) {
  22128. if (aidc->def == idc)
  22129. break;
  22130. aidc = aidc->next;
  22131. }
  22132. if (aidc == NULL) {
  22133. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  22134. "Could not find an augmented IDC item for an IDC definition");
  22135. return (-1);
  22136. }
  22137. /*
  22138. * Create an IDC matcher for every IDC definition.
  22139. */
  22140. if (vctxt->idcMatcherCache != NULL) {
  22141. /*
  22142. * Reuse a cached matcher.
  22143. */
  22144. matcher = vctxt->idcMatcherCache;
  22145. vctxt->idcMatcherCache = matcher->nextCached;
  22146. matcher->nextCached = NULL;
  22147. } else {
  22148. matcher = (xmlSchemaIDCMatcherPtr)
  22149. xmlMalloc(sizeof(xmlSchemaIDCMatcher));
  22150. if (matcher == NULL) {
  22151. xmlSchemaVErrMemory(vctxt,
  22152. "allocating an IDC matcher", NULL);
  22153. return (-1);
  22154. }
  22155. memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
  22156. }
  22157. if (last == NULL)
  22158. vctxt->inode->idcMatchers = matcher;
  22159. else
  22160. last->next = matcher;
  22161. last = matcher;
  22162. matcher->type = IDC_MATCHER;
  22163. matcher->depth = vctxt->depth;
  22164. matcher->aidc = aidc;
  22165. matcher->idcType = aidc->def->type;
  22166. #ifdef DEBUG_IDC
  22167. xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n");
  22168. #endif
  22169. /*
  22170. * Init the automaton state object.
  22171. */
  22172. if (xmlSchemaIDCAddStateObject(vctxt, matcher,
  22173. idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
  22174. return (-1);
  22175. idc = idc->next;
  22176. } while (idc != NULL);
  22177. return (0);
  22178. }
  22179. static int
  22180. xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
  22181. xmlSchemaNodeInfoPtr ielem)
  22182. {
  22183. xmlSchemaPSVIIDCBindingPtr bind;
  22184. int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
  22185. xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
  22186. xmlSchemaPSVIIDCNodePtr *targets, *dupls;
  22187. xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
  22188. /* vctxt->createIDCNodeTables */
  22189. while (matcher != NULL) {
  22190. /*
  22191. * Skip keyref IDCs and empty IDC target-lists.
  22192. */
  22193. if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
  22194. WXS_ILIST_IS_EMPTY(matcher->targets))
  22195. {
  22196. matcher = matcher->next;
  22197. continue;
  22198. }
  22199. /*
  22200. * If we _want_ the IDC node-table to be created in any case
  22201. * then do so. Otherwise create them only if keyrefs need them.
  22202. */
  22203. if ((! vctxt->createIDCNodeTables) &&
  22204. ((matcher->aidc->keyrefDepth == -1) ||
  22205. (matcher->aidc->keyrefDepth > vctxt->depth)))
  22206. {
  22207. matcher = matcher->next;
  22208. continue;
  22209. }
  22210. /*
  22211. * Get/create the IDC binding on this element for the IDC definition.
  22212. */
  22213. bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
  22214. if (bind == NULL)
  22215. goto internal_error;
  22216. if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
  22217. dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
  22218. nbDupls = bind->dupls->nbItems;
  22219. } else {
  22220. dupls = NULL;
  22221. nbDupls = 0;
  22222. }
  22223. if (bind->nodeTable != NULL) {
  22224. nbNodeTable = bind->nbNodes;
  22225. } else {
  22226. nbNodeTable = 0;
  22227. }
  22228. if ((nbNodeTable == 0) && (nbDupls == 0)) {
  22229. /*
  22230. * Transfer all IDC target-nodes to the IDC node-table.
  22231. */
  22232. bind->nodeTable =
  22233. (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
  22234. bind->sizeNodes = matcher->targets->sizeItems;
  22235. bind->nbNodes = matcher->targets->nbItems;
  22236. matcher->targets->items = NULL;
  22237. matcher->targets->sizeItems = 0;
  22238. matcher->targets->nbItems = 0;
  22239. if (matcher->htab) {
  22240. xmlHashFree(matcher->htab, xmlFreeIDCHashEntry);
  22241. matcher->htab = NULL;
  22242. }
  22243. } else {
  22244. /*
  22245. * Compare the key-sequences and add to the IDC node-table.
  22246. */
  22247. nbTargets = matcher->targets->nbItems;
  22248. targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
  22249. nbFields = matcher->aidc->def->nbFields;
  22250. i = 0;
  22251. do {
  22252. keys = targets[i]->keys;
  22253. if (nbDupls) {
  22254. /*
  22255. * Search in already found duplicates first.
  22256. */
  22257. j = 0;
  22258. do {
  22259. if (nbFields == 1) {
  22260. res = xmlSchemaAreValuesEqual(keys[0]->val,
  22261. dupls[j]->keys[0]->val);
  22262. if (res == -1)
  22263. goto internal_error;
  22264. if (res == 1) {
  22265. /*
  22266. * Equal key-sequence.
  22267. */
  22268. goto next_target;
  22269. }
  22270. } else {
  22271. res = 0;
  22272. ntkeys = dupls[j]->keys;
  22273. for (k = 0; k < nbFields; k++) {
  22274. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22275. ntkeys[k]->val);
  22276. if (res == -1)
  22277. goto internal_error;
  22278. if (res == 0) {
  22279. /*
  22280. * One of the keys differs.
  22281. */
  22282. break;
  22283. }
  22284. }
  22285. if (res == 1) {
  22286. /*
  22287. * Equal key-sequence found.
  22288. */
  22289. goto next_target;
  22290. }
  22291. }
  22292. j++;
  22293. } while (j < nbDupls);
  22294. }
  22295. if (nbNodeTable) {
  22296. j = 0;
  22297. do {
  22298. if (nbFields == 1) {
  22299. res = xmlSchemaAreValuesEqual(keys[0]->val,
  22300. bind->nodeTable[j]->keys[0]->val);
  22301. if (res == -1)
  22302. goto internal_error;
  22303. if (res == 0) {
  22304. /*
  22305. * The key-sequence differs.
  22306. */
  22307. goto next_node_table_entry;
  22308. }
  22309. } else {
  22310. res = 0;
  22311. ntkeys = bind->nodeTable[j]->keys;
  22312. for (k = 0; k < nbFields; k++) {
  22313. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22314. ntkeys[k]->val);
  22315. if (res == -1)
  22316. goto internal_error;
  22317. if (res == 0) {
  22318. /*
  22319. * One of the keys differs.
  22320. */
  22321. goto next_node_table_entry;
  22322. }
  22323. }
  22324. }
  22325. /*
  22326. * Add the duplicate to the list of duplicates.
  22327. */
  22328. if (bind->dupls == NULL) {
  22329. bind->dupls = xmlSchemaItemListCreate();
  22330. if (bind->dupls == NULL)
  22331. goto internal_error;
  22332. }
  22333. if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
  22334. goto internal_error;
  22335. /*
  22336. * Remove the duplicate entry from the IDC node-table.
  22337. */
  22338. bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
  22339. bind->nbNodes--;
  22340. goto next_target;
  22341. next_node_table_entry:
  22342. j++;
  22343. } while (j < nbNodeTable);
  22344. }
  22345. /*
  22346. * If everything is fine, then add the IDC target-node to
  22347. * the IDC node-table.
  22348. */
  22349. if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
  22350. goto internal_error;
  22351. next_target:
  22352. i++;
  22353. } while (i < nbTargets);
  22354. }
  22355. matcher = matcher->next;
  22356. }
  22357. return(0);
  22358. internal_error:
  22359. return(-1);
  22360. }
  22361. /**
  22362. * xmlSchemaBubbleIDCNodeTables:
  22363. * @depth: the current tree depth
  22364. *
  22365. * Merges IDC bindings of an element at @depth into the corresponding IDC
  22366. * bindings of its parent element. If a duplicate note-table entry is found,
  22367. * both, the parent node-table entry and child entry are discarded from the
  22368. * node-table of the parent.
  22369. *
  22370. * Returns 0 if OK and -1 on internal errors.
  22371. */
  22372. static int
  22373. xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
  22374. {
  22375. xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
  22376. xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
  22377. xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
  22378. xmlSchemaIDCAugPtr aidc;
  22379. int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
  22380. bind = vctxt->inode->idcTable;
  22381. if (bind == NULL) {
  22382. /* Fine, no table, no bubbles. */
  22383. return (0);
  22384. }
  22385. parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
  22386. /*
  22387. * Walk all bindings; create new or add to existing bindings.
  22388. * Remove duplicate key-sequences.
  22389. */
  22390. while (bind != NULL) {
  22391. if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
  22392. goto next_binding;
  22393. /*
  22394. * Check if the key/unique IDC table needs to be bubbled.
  22395. */
  22396. if (! vctxt->createIDCNodeTables) {
  22397. aidc = vctxt->aidcs;
  22398. do {
  22399. if (aidc->def == bind->definition) {
  22400. if ((aidc->keyrefDepth == -1) ||
  22401. (aidc->keyrefDepth >= vctxt->depth)) {
  22402. goto next_binding;
  22403. }
  22404. break;
  22405. }
  22406. aidc = aidc->next;
  22407. } while (aidc != NULL);
  22408. }
  22409. if (parTable != NULL)
  22410. parBind = *parTable;
  22411. /*
  22412. * Search a matching parent binding for the
  22413. * IDC definition.
  22414. */
  22415. while (parBind != NULL) {
  22416. if (parBind->definition == bind->definition)
  22417. break;
  22418. parBind = parBind->next;
  22419. }
  22420. if (parBind != NULL) {
  22421. /*
  22422. * Compare every node-table entry of the child node,
  22423. * i.e. the key-sequence within, ...
  22424. */
  22425. oldNum = parBind->nbNodes; /* Skip newly added items. */
  22426. if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
  22427. oldDupls = parBind->dupls->nbItems;
  22428. dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
  22429. } else {
  22430. dupls = NULL;
  22431. oldDupls = 0;
  22432. }
  22433. parNodes = parBind->nodeTable;
  22434. nbFields = bind->definition->nbFields;
  22435. for (i = 0; i < bind->nbNodes; i++) {
  22436. node = bind->nodeTable[i];
  22437. if (node == NULL)
  22438. continue;
  22439. /*
  22440. * ...with every key-sequence of the parent node, already
  22441. * evaluated to be a duplicate key-sequence.
  22442. */
  22443. if (oldDupls) {
  22444. j = 0;
  22445. while (j < oldDupls) {
  22446. if (nbFields == 1) {
  22447. ret = xmlSchemaAreValuesEqual(
  22448. node->keys[0]->val,
  22449. dupls[j]->keys[0]->val);
  22450. if (ret == -1)
  22451. goto internal_error;
  22452. if (ret == 0) {
  22453. j++;
  22454. continue;
  22455. }
  22456. } else {
  22457. parNode = dupls[j];
  22458. for (k = 0; k < nbFields; k++) {
  22459. ret = xmlSchemaAreValuesEqual(
  22460. node->keys[k]->val,
  22461. parNode->keys[k]->val);
  22462. if (ret == -1)
  22463. goto internal_error;
  22464. if (ret == 0)
  22465. break;
  22466. }
  22467. }
  22468. if (ret == 1)
  22469. /* Duplicate found. */
  22470. break;
  22471. j++;
  22472. }
  22473. if (j != oldDupls) {
  22474. /* Duplicate found. Skip this entry. */
  22475. continue;
  22476. }
  22477. }
  22478. /*
  22479. * ... and with every key-sequence of the parent node.
  22480. */
  22481. if (oldNum) {
  22482. j = 0;
  22483. while (j < oldNum) {
  22484. parNode = parNodes[j];
  22485. if (nbFields == 1) {
  22486. ret = xmlSchemaAreValuesEqual(
  22487. node->keys[0]->val,
  22488. parNode->keys[0]->val);
  22489. if (ret == -1)
  22490. goto internal_error;
  22491. if (ret == 0) {
  22492. j++;
  22493. continue;
  22494. }
  22495. } else {
  22496. for (k = 0; k < nbFields; k++) {
  22497. ret = xmlSchemaAreValuesEqual(
  22498. node->keys[k]->val,
  22499. parNode->keys[k]->val);
  22500. if (ret == -1)
  22501. goto internal_error;
  22502. if (ret == 0)
  22503. break;
  22504. }
  22505. }
  22506. if (ret == 1)
  22507. /* Duplicate found. */
  22508. break;
  22509. j++;
  22510. }
  22511. if (j != oldNum) {
  22512. /*
  22513. * Handle duplicates. Move the duplicate in
  22514. * the parent's node-table to the list of
  22515. * duplicates.
  22516. */
  22517. oldNum--;
  22518. parBind->nbNodes--;
  22519. /*
  22520. * Move last old item to pos of duplicate.
  22521. */
  22522. parNodes[j] = parNodes[oldNum];
  22523. if (parBind->nbNodes != oldNum) {
  22524. /*
  22525. * If new items exist, move last new item to
  22526. * last of old items.
  22527. */
  22528. parNodes[oldNum] =
  22529. parNodes[parBind->nbNodes];
  22530. }
  22531. if (parBind->dupls == NULL) {
  22532. parBind->dupls = xmlSchemaItemListCreate();
  22533. if (parBind->dupls == NULL)
  22534. goto internal_error;
  22535. }
  22536. xmlSchemaItemListAdd(parBind->dupls, parNode);
  22537. } else {
  22538. /*
  22539. * Add the node-table entry (node and key-sequence) of
  22540. * the child node to the node table of the parent node.
  22541. */
  22542. if (parBind->nodeTable == NULL) {
  22543. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22544. xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
  22545. if (parBind->nodeTable == NULL) {
  22546. xmlSchemaVErrMemory(NULL,
  22547. "allocating IDC list of node-table items", NULL);
  22548. goto internal_error;
  22549. }
  22550. parBind->sizeNodes = 1;
  22551. } else if (parBind->nbNodes >= parBind->sizeNodes) {
  22552. parBind->sizeNodes *= 2;
  22553. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22554. xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
  22555. sizeof(xmlSchemaPSVIIDCNodePtr));
  22556. if (parBind->nodeTable == NULL) {
  22557. xmlSchemaVErrMemory(NULL,
  22558. "re-allocating IDC list of node-table items", NULL);
  22559. goto internal_error;
  22560. }
  22561. }
  22562. parNodes = parBind->nodeTable;
  22563. /*
  22564. * Append the new node-table entry to the 'new node-table
  22565. * entries' section.
  22566. */
  22567. parNodes[parBind->nbNodes++] = node;
  22568. }
  22569. }
  22570. }
  22571. } else {
  22572. /*
  22573. * No binding for the IDC was found: create a new one and
  22574. * copy all node-tables.
  22575. */
  22576. parBind = xmlSchemaIDCNewBinding(bind->definition);
  22577. if (parBind == NULL)
  22578. goto internal_error;
  22579. /*
  22580. * TODO: Hmm, how to optimize the initial number of
  22581. * allocated entries?
  22582. */
  22583. if (bind->nbNodes != 0) {
  22584. /*
  22585. * Add all IDC node-table entries.
  22586. */
  22587. if (! vctxt->psviExposeIDCNodeTables) {
  22588. /*
  22589. * Just move the entries.
  22590. * NOTE: this is quite save here, since
  22591. * all the keyref lookups have already been
  22592. * performed.
  22593. */
  22594. parBind->nodeTable = bind->nodeTable;
  22595. bind->nodeTable = NULL;
  22596. parBind->sizeNodes = bind->sizeNodes;
  22597. bind->sizeNodes = 0;
  22598. parBind->nbNodes = bind->nbNodes;
  22599. bind->nbNodes = 0;
  22600. } else {
  22601. /*
  22602. * Copy the entries.
  22603. */
  22604. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22605. xmlMalloc(bind->nbNodes *
  22606. sizeof(xmlSchemaPSVIIDCNodePtr));
  22607. if (parBind->nodeTable == NULL) {
  22608. xmlSchemaVErrMemory(NULL,
  22609. "allocating an array of IDC node-table "
  22610. "items", NULL);
  22611. xmlSchemaIDCFreeBinding(parBind);
  22612. goto internal_error;
  22613. }
  22614. parBind->sizeNodes = bind->nbNodes;
  22615. parBind->nbNodes = bind->nbNodes;
  22616. memcpy(parBind->nodeTable, bind->nodeTable,
  22617. bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
  22618. }
  22619. }
  22620. if (bind->dupls) {
  22621. /*
  22622. * Move the duplicates.
  22623. */
  22624. if (parBind->dupls != NULL)
  22625. xmlSchemaItemListFree(parBind->dupls);
  22626. parBind->dupls = bind->dupls;
  22627. bind->dupls = NULL;
  22628. }
  22629. if (parTable != NULL) {
  22630. if (*parTable == NULL)
  22631. *parTable = parBind;
  22632. else {
  22633. parBind->next = *parTable;
  22634. *parTable = parBind;
  22635. }
  22636. }
  22637. }
  22638. next_binding:
  22639. bind = bind->next;
  22640. }
  22641. return (0);
  22642. internal_error:
  22643. return(-1);
  22644. }
  22645. /**
  22646. * xmlSchemaCheckCVCIDCKeyRef:
  22647. * @vctxt: the WXS validation context
  22648. * @elemDecl: the element declaration
  22649. *
  22650. * Check the cvc-idc-keyref constraints.
  22651. */
  22652. static int
  22653. xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
  22654. {
  22655. xmlSchemaIDCMatcherPtr matcher;
  22656. xmlSchemaPSVIIDCBindingPtr bind;
  22657. matcher = vctxt->inode->idcMatchers;
  22658. /*
  22659. * Find a keyref.
  22660. */
  22661. while (matcher != NULL) {
  22662. if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
  22663. matcher->targets &&
  22664. matcher->targets->nbItems)
  22665. {
  22666. int i, j, k, res, nbFields, hasDupls;
  22667. xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
  22668. xmlSchemaPSVIIDCNodePtr refNode = NULL;
  22669. xmlHashTablePtr table = NULL;
  22670. nbFields = matcher->aidc->def->nbFields;
  22671. /*
  22672. * Find the IDC node-table for the referenced IDC key/unique.
  22673. */
  22674. bind = vctxt->inode->idcTable;
  22675. while (bind != NULL) {
  22676. if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
  22677. bind->definition)
  22678. break;
  22679. bind = bind->next;
  22680. }
  22681. hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
  22682. /*
  22683. * Search for a matching key-sequences.
  22684. */
  22685. if (bind) {
  22686. table = xmlHashCreate(bind->nbNodes * 2);
  22687. for (j = 0; j < bind->nbNodes; j++) {
  22688. xmlChar *value;
  22689. xmlIDCHashEntryPtr r, e;
  22690. keys = bind->nodeTable[j]->keys;
  22691. xmlSchemaHashKeySequence(vctxt, &value, keys, nbFields);
  22692. e = xmlMalloc(sizeof *e);
  22693. e->index = j;
  22694. r = xmlHashLookup(table, value);
  22695. if (r) {
  22696. e->next = r->next;
  22697. r->next = e;
  22698. } else {
  22699. e->next = NULL;
  22700. xmlHashAddEntry(table, value, e);
  22701. }
  22702. FREE_AND_NULL(value);
  22703. }
  22704. }
  22705. for (i = 0; i < matcher->targets->nbItems; i++) {
  22706. res = 0;
  22707. refNode = matcher->targets->items[i];
  22708. if (bind != NULL) {
  22709. xmlChar *value;
  22710. xmlIDCHashEntryPtr e;
  22711. refKeys = refNode->keys;
  22712. xmlSchemaHashKeySequence(vctxt, &value, refKeys, nbFields);
  22713. e = xmlHashLookup(table, value);
  22714. FREE_AND_NULL(value);
  22715. res = 0;
  22716. for (;e; e = e->next) {
  22717. keys = bind->nodeTable[e->index]->keys;
  22718. for (k = 0; k < nbFields; k++) {
  22719. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22720. refKeys[k]->val);
  22721. if (res == 0)
  22722. break;
  22723. else if (res == -1) {
  22724. return (-1);
  22725. }
  22726. }
  22727. if (res == 1) {
  22728. /*
  22729. * Match found.
  22730. */
  22731. break;
  22732. }
  22733. }
  22734. if ((res == 0) && hasDupls) {
  22735. /*
  22736. * Search in duplicates
  22737. */
  22738. for (j = 0; j < bind->dupls->nbItems; j++) {
  22739. keys = ((xmlSchemaPSVIIDCNodePtr)
  22740. bind->dupls->items[j])->keys;
  22741. for (k = 0; k < nbFields; k++) {
  22742. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22743. refKeys[k]->val);
  22744. if (res == 0)
  22745. break;
  22746. else if (res == -1) {
  22747. return (-1);
  22748. }
  22749. }
  22750. if (res == 1) {
  22751. /*
  22752. * Match in duplicates found.
  22753. */
  22754. xmlChar *str = NULL, *strB = NULL;
  22755. xmlSchemaKeyrefErr(vctxt,
  22756. XML_SCHEMAV_CVC_IDC, refNode,
  22757. (xmlSchemaTypePtr) matcher->aidc->def,
  22758. "More than one match found for "
  22759. "key-sequence %s of keyref '%s'",
  22760. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  22761. refNode->keys, nbFields),
  22762. xmlSchemaGetComponentQName(&strB,
  22763. matcher->aidc->def));
  22764. FREE_AND_NULL(str);
  22765. FREE_AND_NULL(strB);
  22766. break;
  22767. }
  22768. }
  22769. }
  22770. }
  22771. if (res == 0) {
  22772. xmlChar *str = NULL, *strB = NULL;
  22773. xmlSchemaKeyrefErr(vctxt,
  22774. XML_SCHEMAV_CVC_IDC, refNode,
  22775. (xmlSchemaTypePtr) matcher->aidc->def,
  22776. "No match found for key-sequence %s of keyref '%s'",
  22777. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  22778. refNode->keys, nbFields),
  22779. xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
  22780. FREE_AND_NULL(str);
  22781. FREE_AND_NULL(strB);
  22782. }
  22783. }
  22784. if (table) {
  22785. xmlHashFree(table, xmlFreeIDCHashEntry);
  22786. }
  22787. }
  22788. matcher = matcher->next;
  22789. }
  22790. /* TODO: Return an error if any error encountered. */
  22791. return (0);
  22792. }
  22793. /************************************************************************
  22794. * *
  22795. * XML Reader validation code *
  22796. * *
  22797. ************************************************************************/
  22798. static xmlSchemaAttrInfoPtr
  22799. xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
  22800. {
  22801. xmlSchemaAttrInfoPtr iattr;
  22802. /*
  22803. * Grow/create list of attribute infos.
  22804. */
  22805. if (vctxt->attrInfos == NULL) {
  22806. vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
  22807. xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
  22808. vctxt->sizeAttrInfos = 1;
  22809. if (vctxt->attrInfos == NULL) {
  22810. xmlSchemaVErrMemory(vctxt,
  22811. "allocating attribute info list", NULL);
  22812. return (NULL);
  22813. }
  22814. } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
  22815. vctxt->sizeAttrInfos++;
  22816. vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
  22817. xmlRealloc(vctxt->attrInfos,
  22818. vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
  22819. if (vctxt->attrInfos == NULL) {
  22820. xmlSchemaVErrMemory(vctxt,
  22821. "re-allocating attribute info list", NULL);
  22822. return (NULL);
  22823. }
  22824. } else {
  22825. iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
  22826. if (iattr->localName != NULL) {
  22827. VERROR_INT("xmlSchemaGetFreshAttrInfo",
  22828. "attr info not cleared");
  22829. return (NULL);
  22830. }
  22831. iattr->nodeType = XML_ATTRIBUTE_NODE;
  22832. return (iattr);
  22833. }
  22834. /*
  22835. * Create an attribute info.
  22836. */
  22837. iattr = (xmlSchemaAttrInfoPtr)
  22838. xmlMalloc(sizeof(xmlSchemaAttrInfo));
  22839. if (iattr == NULL) {
  22840. xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
  22841. return (NULL);
  22842. }
  22843. memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
  22844. iattr->nodeType = XML_ATTRIBUTE_NODE;
  22845. vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
  22846. return (iattr);
  22847. }
  22848. static int
  22849. xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
  22850. xmlNodePtr attrNode,
  22851. int nodeLine,
  22852. const xmlChar *localName,
  22853. const xmlChar *nsName,
  22854. int ownedNames,
  22855. xmlChar *value,
  22856. int ownedValue)
  22857. {
  22858. xmlSchemaAttrInfoPtr attr;
  22859. attr = xmlSchemaGetFreshAttrInfo(vctxt);
  22860. if (attr == NULL) {
  22861. VERROR_INT("xmlSchemaPushAttribute",
  22862. "calling xmlSchemaGetFreshAttrInfo()");
  22863. return (-1);
  22864. }
  22865. attr->node = attrNode;
  22866. attr->nodeLine = nodeLine;
  22867. attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
  22868. attr->localName = localName;
  22869. attr->nsName = nsName;
  22870. if (ownedNames)
  22871. attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
  22872. /*
  22873. * Evaluate if it's an XSI attribute.
  22874. */
  22875. if (nsName != NULL) {
  22876. if (xmlStrEqual(localName, BAD_CAST "nil")) {
  22877. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22878. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
  22879. }
  22880. } else if (xmlStrEqual(localName, BAD_CAST "type")) {
  22881. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22882. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
  22883. }
  22884. } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
  22885. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22886. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
  22887. }
  22888. } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
  22889. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22890. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
  22891. }
  22892. } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
  22893. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
  22894. }
  22895. }
  22896. attr->value = value;
  22897. if (ownedValue)
  22898. attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  22899. if (attr->metaType != 0)
  22900. attr->state = XML_SCHEMAS_ATTR_META;
  22901. return (0);
  22902. }
  22903. /**
  22904. * xmlSchemaClearElemInfo:
  22905. * @vctxt: the WXS validation context
  22906. * @ielem: the element information item
  22907. */
  22908. static void
  22909. xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
  22910. xmlSchemaNodeInfoPtr ielem)
  22911. {
  22912. ielem->hasKeyrefs = 0;
  22913. ielem->appliedXPath = 0;
  22914. if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
  22915. FREE_AND_NULL(ielem->localName);
  22916. FREE_AND_NULL(ielem->nsName);
  22917. } else {
  22918. ielem->localName = NULL;
  22919. ielem->nsName = NULL;
  22920. }
  22921. if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  22922. FREE_AND_NULL(ielem->value);
  22923. } else {
  22924. ielem->value = NULL;
  22925. }
  22926. if (ielem->val != NULL) {
  22927. /*
  22928. * PSVI TODO: Be careful not to free it when the value is
  22929. * exposed via PSVI.
  22930. */
  22931. xmlSchemaFreeValue(ielem->val);
  22932. ielem->val = NULL;
  22933. }
  22934. if (ielem->idcMatchers != NULL) {
  22935. /*
  22936. * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
  22937. * Does it work?
  22938. */
  22939. xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
  22940. #if 0
  22941. xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
  22942. #endif
  22943. ielem->idcMatchers = NULL;
  22944. }
  22945. if (ielem->idcTable != NULL) {
  22946. /*
  22947. * OPTIMIZE TODO: Use a pool of IDC tables??.
  22948. */
  22949. xmlSchemaIDCFreeIDCTable(ielem->idcTable);
  22950. ielem->idcTable = NULL;
  22951. }
  22952. if (ielem->regexCtxt != NULL) {
  22953. xmlRegFreeExecCtxt(ielem->regexCtxt);
  22954. ielem->regexCtxt = NULL;
  22955. }
  22956. if (ielem->nsBindings != NULL) {
  22957. xmlFree((xmlChar **)ielem->nsBindings);
  22958. ielem->nsBindings = NULL;
  22959. ielem->nbNsBindings = 0;
  22960. ielem->sizeNsBindings = 0;
  22961. }
  22962. }
  22963. /**
  22964. * xmlSchemaGetFreshElemInfo:
  22965. * @vctxt: the schema validation context
  22966. *
  22967. * Creates/reuses and initializes the element info item for
  22968. * the current tree depth.
  22969. *
  22970. * Returns the element info item or NULL on API or internal errors.
  22971. */
  22972. static xmlSchemaNodeInfoPtr
  22973. xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
  22974. {
  22975. xmlSchemaNodeInfoPtr info = NULL;
  22976. if (vctxt->depth > vctxt->sizeElemInfos) {
  22977. VERROR_INT("xmlSchemaGetFreshElemInfo",
  22978. "inconsistent depth encountered");
  22979. return (NULL);
  22980. }
  22981. if (vctxt->elemInfos == NULL) {
  22982. vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
  22983. xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
  22984. if (vctxt->elemInfos == NULL) {
  22985. xmlSchemaVErrMemory(vctxt,
  22986. "allocating the element info array", NULL);
  22987. return (NULL);
  22988. }
  22989. memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
  22990. vctxt->sizeElemInfos = 10;
  22991. } else if (vctxt->sizeElemInfos <= vctxt->depth) {
  22992. int i = vctxt->sizeElemInfos;
  22993. vctxt->sizeElemInfos *= 2;
  22994. vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
  22995. xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
  22996. sizeof(xmlSchemaNodeInfoPtr));
  22997. if (vctxt->elemInfos == NULL) {
  22998. xmlSchemaVErrMemory(vctxt,
  22999. "re-allocating the element info array", NULL);
  23000. return (NULL);
  23001. }
  23002. /*
  23003. * We need the new memory to be NULLed.
  23004. * TODO: Use memset instead?
  23005. */
  23006. for (; i < vctxt->sizeElemInfos; i++)
  23007. vctxt->elemInfos[i] = NULL;
  23008. } else
  23009. info = vctxt->elemInfos[vctxt->depth];
  23010. if (info == NULL) {
  23011. info = (xmlSchemaNodeInfoPtr)
  23012. xmlMalloc(sizeof(xmlSchemaNodeInfo));
  23013. if (info == NULL) {
  23014. xmlSchemaVErrMemory(vctxt,
  23015. "allocating an element info", NULL);
  23016. return (NULL);
  23017. }
  23018. vctxt->elemInfos[vctxt->depth] = info;
  23019. } else {
  23020. if (info->localName != NULL) {
  23021. VERROR_INT("xmlSchemaGetFreshElemInfo",
  23022. "elem info has not been cleared");
  23023. return (NULL);
  23024. }
  23025. }
  23026. memset(info, 0, sizeof(xmlSchemaNodeInfo));
  23027. info->nodeType = XML_ELEMENT_NODE;
  23028. info->depth = vctxt->depth;
  23029. return (info);
  23030. }
  23031. #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
  23032. #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
  23033. #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
  23034. static int
  23035. xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
  23036. xmlNodePtr node,
  23037. xmlSchemaTypePtr type,
  23038. xmlSchemaValType valType,
  23039. const xmlChar * value,
  23040. xmlSchemaValPtr val,
  23041. unsigned long length,
  23042. int fireErrors)
  23043. {
  23044. int ret, error = 0, found;
  23045. xmlSchemaTypePtr tmpType;
  23046. xmlSchemaFacetLinkPtr facetLink;
  23047. xmlSchemaFacetPtr facet;
  23048. unsigned long len = 0;
  23049. xmlSchemaWhitespaceValueType ws;
  23050. /*
  23051. * In Libxml2, derived built-in types have currently no explicit facets.
  23052. */
  23053. if (type->type == XML_SCHEMA_TYPE_BASIC)
  23054. return (0);
  23055. /*
  23056. * NOTE: Do not jump away, if the facetSet of the given type is
  23057. * empty: until now, "pattern" and "enumeration" facets of the
  23058. * *base types* need to be checked as well.
  23059. */
  23060. if (type->facetSet == NULL)
  23061. goto pattern_and_enum;
  23062. if (! WXS_IS_ATOMIC(type)) {
  23063. if (WXS_IS_LIST(type))
  23064. goto WXS_IS_LIST;
  23065. else
  23066. goto pattern_and_enum;
  23067. }
  23068. /*
  23069. * Whitespace handling is only of importance for string-based
  23070. * types.
  23071. */
  23072. tmpType = xmlSchemaGetPrimitiveType(type);
  23073. if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
  23074. WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
  23075. ws = xmlSchemaGetWhiteSpaceFacetValue(type);
  23076. } else
  23077. ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
  23078. /*
  23079. * If the value was not computed (for string or
  23080. * anySimpleType based types), then use the provided
  23081. * type.
  23082. */
  23083. if (val != NULL)
  23084. valType = xmlSchemaGetValType(val);
  23085. ret = 0;
  23086. for (facetLink = type->facetSet; facetLink != NULL;
  23087. facetLink = facetLink->next) {
  23088. /*
  23089. * Skip the pattern "whiteSpace": it is used to
  23090. * format the character content beforehand.
  23091. */
  23092. switch (facetLink->facet->type) {
  23093. case XML_SCHEMA_FACET_WHITESPACE:
  23094. case XML_SCHEMA_FACET_PATTERN:
  23095. case XML_SCHEMA_FACET_ENUMERATION:
  23096. continue;
  23097. case XML_SCHEMA_FACET_LENGTH:
  23098. case XML_SCHEMA_FACET_MINLENGTH:
  23099. case XML_SCHEMA_FACET_MAXLENGTH:
  23100. ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
  23101. valType, value, val, &len, ws);
  23102. break;
  23103. default:
  23104. ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
  23105. valType, value, val, ws);
  23106. break;
  23107. }
  23108. if (ret < 0) {
  23109. AERROR_INT("xmlSchemaValidateFacets",
  23110. "validating against a atomic type facet");
  23111. return (-1);
  23112. } else if (ret > 0) {
  23113. if (fireErrors)
  23114. xmlSchemaFacetErr(actxt, ret, node,
  23115. value, len, type, facetLink->facet, NULL, NULL, NULL);
  23116. else
  23117. return (ret);
  23118. if (error == 0)
  23119. error = ret;
  23120. }
  23121. ret = 0;
  23122. }
  23123. WXS_IS_LIST:
  23124. if (! WXS_IS_LIST(type))
  23125. goto pattern_and_enum;
  23126. /*
  23127. * "length", "minLength" and "maxLength" of list types.
  23128. */
  23129. ret = 0;
  23130. for (facetLink = type->facetSet; facetLink != NULL;
  23131. facetLink = facetLink->next) {
  23132. switch (facetLink->facet->type) {
  23133. case XML_SCHEMA_FACET_LENGTH:
  23134. case XML_SCHEMA_FACET_MINLENGTH:
  23135. case XML_SCHEMA_FACET_MAXLENGTH:
  23136. ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
  23137. value, length, NULL);
  23138. break;
  23139. default:
  23140. continue;
  23141. }
  23142. if (ret < 0) {
  23143. AERROR_INT("xmlSchemaValidateFacets",
  23144. "validating against a list type facet");
  23145. return (-1);
  23146. } else if (ret > 0) {
  23147. if (fireErrors)
  23148. xmlSchemaFacetErr(actxt, ret, node,
  23149. value, length, type, facetLink->facet, NULL, NULL, NULL);
  23150. else
  23151. return (ret);
  23152. if (error == 0)
  23153. error = ret;
  23154. }
  23155. ret = 0;
  23156. }
  23157. pattern_and_enum:
  23158. found = 0;
  23159. /*
  23160. * Process enumerations. Facet values are in the value space
  23161. * of the defining type's base type. This seems to be a bug in the
  23162. * XML Schema 1.0 spec. Use the whitespace type of the base type.
  23163. * Only the first set of enumerations in the ancestor-or-self axis
  23164. * is used for validation.
  23165. */
  23166. ret = 0;
  23167. tmpType = type;
  23168. do {
  23169. for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
  23170. if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
  23171. continue;
  23172. found = 1;
  23173. ret = xmlSchemaAreValuesEqual(facet->val, val);
  23174. if (ret == 1)
  23175. break;
  23176. else if (ret < 0) {
  23177. AERROR_INT("xmlSchemaValidateFacets",
  23178. "validating against an enumeration facet");
  23179. return (-1);
  23180. }
  23181. }
  23182. if (ret != 0)
  23183. break;
  23184. /*
  23185. * Break on the first set of enumerations. Any additional
  23186. * enumerations which might be existent on the ancestors
  23187. * of the current type are restricted by this set; thus
  23188. * *must* *not* be taken into account.
  23189. */
  23190. if (found)
  23191. break;
  23192. tmpType = tmpType->baseType;
  23193. } while ((tmpType != NULL) &&
  23194. (tmpType->type != XML_SCHEMA_TYPE_BASIC));
  23195. if (found && (ret == 0)) {
  23196. ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
  23197. if (fireErrors) {
  23198. xmlSchemaFacetErr(actxt, ret, node,
  23199. value, 0, type, NULL, NULL, NULL, NULL);
  23200. } else
  23201. return (ret);
  23202. if (error == 0)
  23203. error = ret;
  23204. }
  23205. /*
  23206. * Process patters. Pattern facets are ORed at type level
  23207. * and ANDed if derived. Walk the base type axis.
  23208. */
  23209. tmpType = type;
  23210. facet = NULL;
  23211. do {
  23212. found = 0;
  23213. for (facetLink = tmpType->facetSet; facetLink != NULL;
  23214. facetLink = facetLink->next) {
  23215. if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
  23216. continue;
  23217. found = 1;
  23218. /*
  23219. * NOTE that for patterns, @value needs to be the
  23220. * normalized value.
  23221. */
  23222. ret = xmlRegexpExec(facetLink->facet->regexp, value);
  23223. if (ret == 1)
  23224. break;
  23225. else if (ret < 0) {
  23226. AERROR_INT("xmlSchemaValidateFacets",
  23227. "validating against a pattern facet");
  23228. return (-1);
  23229. } else {
  23230. /*
  23231. * Save the last non-validating facet.
  23232. */
  23233. facet = facetLink->facet;
  23234. }
  23235. }
  23236. if (found && (ret != 1)) {
  23237. ret = XML_SCHEMAV_CVC_PATTERN_VALID;
  23238. if (fireErrors) {
  23239. xmlSchemaFacetErr(actxt, ret, node,
  23240. value, 0, type, facet, NULL, NULL, NULL);
  23241. } else
  23242. return (ret);
  23243. if (error == 0)
  23244. error = ret;
  23245. break;
  23246. }
  23247. tmpType = tmpType->baseType;
  23248. } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
  23249. return (error);
  23250. }
  23251. static xmlChar *
  23252. xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
  23253. const xmlChar *value)
  23254. {
  23255. switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
  23256. case XML_SCHEMA_WHITESPACE_COLLAPSE:
  23257. return (xmlSchemaCollapseString(value));
  23258. case XML_SCHEMA_WHITESPACE_REPLACE:
  23259. return (xmlSchemaWhiteSpaceReplace(value));
  23260. default:
  23261. return (NULL);
  23262. }
  23263. }
  23264. static int
  23265. xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
  23266. const xmlChar *value,
  23267. xmlSchemaValPtr *val,
  23268. int valNeeded)
  23269. {
  23270. int ret;
  23271. const xmlChar *nsName;
  23272. xmlChar *local, *prefix = NULL;
  23273. ret = xmlValidateQName(value, 1);
  23274. if (ret != 0) {
  23275. if (ret == -1) {
  23276. VERROR_INT("xmlSchemaValidateQName",
  23277. "calling xmlValidateQName()");
  23278. return (-1);
  23279. }
  23280. return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
  23281. }
  23282. /*
  23283. * NOTE: xmlSplitQName2 will always return a duplicated
  23284. * strings.
  23285. */
  23286. local = xmlSplitQName2(value, &prefix);
  23287. if (local == NULL)
  23288. local = xmlStrdup(value);
  23289. /*
  23290. * OPTIMIZE TODO: Use flags for:
  23291. * - is there any namespace binding?
  23292. * - is there a default namespace?
  23293. */
  23294. nsName = xmlSchemaLookupNamespace(vctxt, prefix);
  23295. if (prefix != NULL) {
  23296. xmlFree(prefix);
  23297. /*
  23298. * A namespace must be found if the prefix is
  23299. * NOT NULL.
  23300. */
  23301. if (nsName == NULL) {
  23302. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23303. xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
  23304. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23305. "The QName value '%s' has no "
  23306. "corresponding namespace declaration in "
  23307. "scope", value, NULL);
  23308. if (local != NULL)
  23309. xmlFree(local);
  23310. return (ret);
  23311. }
  23312. }
  23313. if (valNeeded && val) {
  23314. if (nsName != NULL)
  23315. *val = xmlSchemaNewQNameValue(
  23316. BAD_CAST xmlStrdup(nsName), BAD_CAST local);
  23317. else
  23318. *val = xmlSchemaNewQNameValue(NULL,
  23319. BAD_CAST local);
  23320. } else
  23321. xmlFree(local);
  23322. return (0);
  23323. }
  23324. /*
  23325. * cvc-simple-type
  23326. */
  23327. static int
  23328. xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
  23329. xmlNodePtr node,
  23330. xmlSchemaTypePtr type,
  23331. const xmlChar *value,
  23332. xmlSchemaValPtr *retVal,
  23333. int fireErrors,
  23334. int normalize,
  23335. int isNormalized)
  23336. {
  23337. int ret = 0, valNeeded = (retVal) ? 1 : 0;
  23338. xmlSchemaValPtr val = NULL;
  23339. /* xmlSchemaWhitespaceValueType ws; */
  23340. xmlChar *normValue = NULL;
  23341. #define NORMALIZE(atype) \
  23342. if ((! isNormalized) && \
  23343. (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
  23344. normValue = xmlSchemaNormalizeValue(atype, value); \
  23345. if (normValue != NULL) \
  23346. value = normValue; \
  23347. isNormalized = 1; \
  23348. }
  23349. if ((retVal != NULL) && (*retVal != NULL)) {
  23350. xmlSchemaFreeValue(*retVal);
  23351. *retVal = NULL;
  23352. }
  23353. /*
  23354. * 3.14.4 Simple Type Definition Validation Rules
  23355. * Validation Rule: String Valid
  23356. */
  23357. /*
  23358. * 1 It is schema-valid with respect to that definition as defined
  23359. * by Datatype Valid in [XML Schemas: Datatypes].
  23360. */
  23361. /*
  23362. * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
  23363. * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
  23364. * the string must be a `declared entity name`.
  23365. */
  23366. /*
  23367. * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
  23368. * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
  23369. * then every whitespace-delimited substring of the string must be a `declared
  23370. * entity name`.
  23371. */
  23372. /*
  23373. * 2.3 otherwise no further condition applies.
  23374. */
  23375. if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
  23376. valNeeded = 1;
  23377. if (value == NULL)
  23378. value = BAD_CAST "";
  23379. if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
  23380. xmlSchemaTypePtr biType; /* The built-in type. */
  23381. /*
  23382. * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
  23383. * a literal in the `lexical space` of {base type definition}"
  23384. */
  23385. /*
  23386. * Whitespace-normalize.
  23387. */
  23388. NORMALIZE(type);
  23389. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  23390. /*
  23391. * Get the built-in type.
  23392. */
  23393. biType = type->baseType;
  23394. while ((biType != NULL) &&
  23395. (biType->type != XML_SCHEMA_TYPE_BASIC))
  23396. biType = biType->baseType;
  23397. if (biType == NULL) {
  23398. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23399. "could not get the built-in type");
  23400. goto internal_error;
  23401. }
  23402. } else
  23403. biType = type;
  23404. /*
  23405. * NOTATIONs need to be processed here, since they need
  23406. * to lookup in the hashtable of NOTATION declarations of the schema.
  23407. */
  23408. if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  23409. switch (biType->builtInType) {
  23410. case XML_SCHEMAS_NOTATION:
  23411. ret = xmlSchemaValidateNotation(
  23412. (xmlSchemaValidCtxtPtr) actxt,
  23413. ((xmlSchemaValidCtxtPtr) actxt)->schema,
  23414. NULL, value, &val, valNeeded);
  23415. break;
  23416. case XML_SCHEMAS_QNAME:
  23417. ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
  23418. value, &val, valNeeded);
  23419. break;
  23420. default:
  23421. /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
  23422. if (valNeeded)
  23423. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23424. value, &val, node);
  23425. else
  23426. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23427. value, NULL, node);
  23428. break;
  23429. }
  23430. } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
  23431. switch (biType->builtInType) {
  23432. case XML_SCHEMAS_NOTATION:
  23433. ret = xmlSchemaValidateNotation(NULL,
  23434. ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
  23435. value, &val, valNeeded);
  23436. break;
  23437. default:
  23438. /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
  23439. if (valNeeded)
  23440. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23441. value, &val, node);
  23442. else
  23443. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23444. value, NULL, node);
  23445. break;
  23446. }
  23447. } else {
  23448. /*
  23449. * Validation via a public API is not implemented yet.
  23450. */
  23451. TODO
  23452. goto internal_error;
  23453. }
  23454. if (ret != 0) {
  23455. if (ret < 0) {
  23456. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23457. "validating against a built-in type");
  23458. goto internal_error;
  23459. }
  23460. if (WXS_IS_LIST(type))
  23461. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23462. else
  23463. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23464. }
  23465. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23466. /*
  23467. * Check facets.
  23468. */
  23469. ret = xmlSchemaValidateFacets(actxt, node, type,
  23470. (xmlSchemaValType) biType->builtInType, value, val,
  23471. 0, fireErrors);
  23472. if (ret != 0) {
  23473. if (ret < 0) {
  23474. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23475. "validating facets of atomic simple type");
  23476. goto internal_error;
  23477. }
  23478. if (WXS_IS_LIST(type))
  23479. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23480. else
  23481. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23482. }
  23483. }
  23484. else if (fireErrors && (ret > 0))
  23485. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23486. } else if (WXS_IS_LIST(type)) {
  23487. xmlSchemaTypePtr itemType;
  23488. const xmlChar *cur, *end;
  23489. xmlChar *tmpValue = NULL;
  23490. unsigned long len = 0;
  23491. xmlSchemaValPtr prevVal = NULL, curVal = NULL;
  23492. /* 1.2.2 if {variety} is `list` then the string must be a sequence
  23493. * of white space separated tokens, each of which `match`es a literal
  23494. * in the `lexical space` of {item type definition}
  23495. */
  23496. /*
  23497. * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
  23498. * the list type has an enum or pattern facet.
  23499. */
  23500. NORMALIZE(type);
  23501. /*
  23502. * VAL TODO: Optimize validation of empty values.
  23503. * VAL TODO: We do not have computed values for lists.
  23504. */
  23505. itemType = WXS_LIST_ITEMTYPE(type);
  23506. cur = value;
  23507. do {
  23508. while (IS_BLANK_CH(*cur))
  23509. cur++;
  23510. end = cur;
  23511. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  23512. end++;
  23513. if (end == cur)
  23514. break;
  23515. tmpValue = xmlStrndup(cur, end - cur);
  23516. len++;
  23517. if (valNeeded)
  23518. ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
  23519. tmpValue, &curVal, fireErrors, 0, 1);
  23520. else
  23521. ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
  23522. tmpValue, NULL, fireErrors, 0, 1);
  23523. FREE_AND_NULL(tmpValue);
  23524. if (curVal != NULL) {
  23525. /*
  23526. * Add to list of computed values.
  23527. */
  23528. if (val == NULL)
  23529. val = curVal;
  23530. else
  23531. xmlSchemaValueAppend(prevVal, curVal);
  23532. prevVal = curVal;
  23533. curVal = NULL;
  23534. }
  23535. if (ret != 0) {
  23536. if (ret < 0) {
  23537. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23538. "validating an item of list simple type");
  23539. goto internal_error;
  23540. }
  23541. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23542. break;
  23543. }
  23544. cur = end;
  23545. } while (*cur != 0);
  23546. FREE_AND_NULL(tmpValue);
  23547. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23548. /*
  23549. * Apply facets (pattern, enumeration).
  23550. */
  23551. ret = xmlSchemaValidateFacets(actxt, node, type,
  23552. XML_SCHEMAS_UNKNOWN, value, val,
  23553. len, fireErrors);
  23554. if (ret != 0) {
  23555. if (ret < 0) {
  23556. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23557. "validating facets of list simple type");
  23558. goto internal_error;
  23559. }
  23560. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23561. }
  23562. }
  23563. if (fireErrors && (ret > 0)) {
  23564. /*
  23565. * Report the normalized value.
  23566. */
  23567. normalize = 1;
  23568. NORMALIZE(type);
  23569. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23570. }
  23571. } else if (WXS_IS_UNION(type)) {
  23572. xmlSchemaTypeLinkPtr memberLink;
  23573. /*
  23574. * TODO: For all datatypes `derived` by `union` whiteSpace does
  23575. * not apply directly; however, the normalization behavior of `union`
  23576. * types is controlled by the value of whiteSpace on that one of the
  23577. * `memberTypes` against which the `union` is successfully validated.
  23578. *
  23579. * This means that the value is normalized by the first validating
  23580. * member type, then the facets of the union type are applied. This
  23581. * needs changing of the value!
  23582. */
  23583. /*
  23584. * 1.2.3 if {variety} is `union` then the string must `match` a
  23585. * literal in the `lexical space` of at least one member of
  23586. * {member type definitions}
  23587. */
  23588. memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
  23589. if (memberLink == NULL) {
  23590. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23591. "union simple type has no member types");
  23592. goto internal_error;
  23593. }
  23594. /*
  23595. * Always normalize union type values, since we currently
  23596. * cannot store the whitespace information with the value
  23597. * itself; otherwise a later value-comparison would be
  23598. * not possible.
  23599. */
  23600. while (memberLink != NULL) {
  23601. if (valNeeded)
  23602. ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
  23603. memberLink->type, value, &val, 0, 1, 0);
  23604. else
  23605. ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
  23606. memberLink->type, value, NULL, 0, 1, 0);
  23607. if (ret <= 0)
  23608. break;
  23609. memberLink = memberLink->next;
  23610. }
  23611. if (ret != 0) {
  23612. if (ret < 0) {
  23613. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23614. "validating members of union simple type");
  23615. goto internal_error;
  23616. }
  23617. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
  23618. }
  23619. /*
  23620. * Apply facets (pattern, enumeration).
  23621. */
  23622. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23623. /*
  23624. * The normalization behavior of `union` types is controlled by
  23625. * the value of whiteSpace on that one of the `memberTypes`
  23626. * against which the `union` is successfully validated.
  23627. */
  23628. NORMALIZE(memberLink->type);
  23629. ret = xmlSchemaValidateFacets(actxt, node, type,
  23630. XML_SCHEMAS_UNKNOWN, value, val,
  23631. 0, fireErrors);
  23632. if (ret != 0) {
  23633. if (ret < 0) {
  23634. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23635. "validating facets of union simple type");
  23636. goto internal_error;
  23637. }
  23638. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
  23639. }
  23640. }
  23641. if (fireErrors && (ret > 0))
  23642. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23643. }
  23644. if (normValue != NULL)
  23645. xmlFree(normValue);
  23646. if (ret == 0) {
  23647. if (retVal != NULL)
  23648. *retVal = val;
  23649. else if (val != NULL)
  23650. xmlSchemaFreeValue(val);
  23651. } else if (val != NULL)
  23652. xmlSchemaFreeValue(val);
  23653. return (ret);
  23654. internal_error:
  23655. if (normValue != NULL)
  23656. xmlFree(normValue);
  23657. if (val != NULL)
  23658. xmlSchemaFreeValue(val);
  23659. return (-1);
  23660. }
  23661. static int
  23662. xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
  23663. const xmlChar *value,
  23664. const xmlChar **nsName,
  23665. const xmlChar **localName)
  23666. {
  23667. int ret = 0;
  23668. if ((nsName == NULL) || (localName == NULL))
  23669. return (-1);
  23670. *nsName = NULL;
  23671. *localName = NULL;
  23672. ret = xmlValidateQName(value, 1);
  23673. if (ret == -1)
  23674. return (-1);
  23675. if (ret > 0) {
  23676. xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
  23677. XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
  23678. value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
  23679. return (1);
  23680. }
  23681. {
  23682. xmlChar *local = NULL;
  23683. xmlChar *prefix;
  23684. /*
  23685. * NOTE: xmlSplitQName2 will return a duplicated
  23686. * string.
  23687. */
  23688. local = xmlSplitQName2(value, &prefix);
  23689. if (local == NULL)
  23690. *localName = xmlDictLookup(vctxt->dict, value, -1);
  23691. else {
  23692. *localName = xmlDictLookup(vctxt->dict, local, -1);
  23693. xmlFree(local);
  23694. }
  23695. *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
  23696. if (prefix != NULL) {
  23697. xmlFree(prefix);
  23698. /*
  23699. * A namespace must be found if the prefix is NOT NULL.
  23700. */
  23701. if (*nsName == NULL) {
  23702. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23703. XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
  23704. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23705. "The QName value '%s' has no "
  23706. "corresponding namespace declaration in scope",
  23707. value, NULL);
  23708. return (2);
  23709. }
  23710. }
  23711. }
  23712. return (0);
  23713. }
  23714. static int
  23715. xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
  23716. xmlSchemaAttrInfoPtr iattr,
  23717. xmlSchemaTypePtr *localType,
  23718. xmlSchemaElementPtr elemDecl)
  23719. {
  23720. int ret = 0;
  23721. /*
  23722. * cvc-elt (3.3.4) : (4)
  23723. * AND
  23724. * Schema-Validity Assessment (Element) (cvc-assess-elt)
  23725. * (1.2.1.2.1) - (1.2.1.2.4)
  23726. * Handle 'xsi:type'.
  23727. */
  23728. if (localType == NULL)
  23729. return (-1);
  23730. *localType = NULL;
  23731. if (iattr == NULL)
  23732. return (0);
  23733. else {
  23734. const xmlChar *nsName = NULL, *local = NULL;
  23735. /*
  23736. * TODO: We should report a *warning* that the type was overridden
  23737. * by the instance.
  23738. */
  23739. ACTIVATE_ATTRIBUTE(iattr);
  23740. /*
  23741. * (cvc-elt) (3.3.4) : (4.1)
  23742. * (cvc-assess-elt) (1.2.1.2.2)
  23743. */
  23744. ret = xmlSchemaVExpandQName(vctxt, iattr->value,
  23745. &nsName, &local);
  23746. if (ret != 0) {
  23747. if (ret < 0) {
  23748. VERROR_INT("xmlSchemaValidateElementByDeclaration",
  23749. "calling xmlSchemaQNameExpand() to validate the "
  23750. "attribute 'xsi:type'");
  23751. goto internal_error;
  23752. }
  23753. goto exit;
  23754. }
  23755. /*
  23756. * (cvc-elt) (3.3.4) : (4.2)
  23757. * (cvc-assess-elt) (1.2.1.2.3)
  23758. */
  23759. *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
  23760. if (*localType == NULL) {
  23761. xmlChar *str = NULL;
  23762. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23763. XML_SCHEMAV_CVC_ELT_4_2, NULL,
  23764. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23765. "The QName value '%s' of the xsi:type attribute does not "
  23766. "resolve to a type definition",
  23767. xmlSchemaFormatQName(&str, nsName, local), NULL);
  23768. FREE_AND_NULL(str);
  23769. ret = vctxt->err;
  23770. goto exit;
  23771. }
  23772. if (elemDecl != NULL) {
  23773. int set = 0;
  23774. /*
  23775. * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
  23776. * "The `local type definition` must be validly
  23777. * derived from the {type definition} given the union of
  23778. * the {disallowed substitutions} and the {type definition}'s
  23779. * {prohibited substitutions}, as defined in
  23780. * Type Derivation OK (Complex) ($3.4.6)
  23781. * (if it is a complex type definition),
  23782. * or given {disallowed substitutions} as defined in Type
  23783. * Derivation OK (Simple) ($3.14.6) (if it is a simple type
  23784. * definition)."
  23785. *
  23786. * {disallowed substitutions}: the "block" on the element decl.
  23787. * {prohibited substitutions}: the "block" on the type def.
  23788. */
  23789. /*
  23790. * OPTIMIZE TODO: We could map types already evaluated
  23791. * to be validly derived from other types to avoid checking
  23792. * this over and over for the same types.
  23793. */
  23794. if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
  23795. (elemDecl->subtypes->flags &
  23796. XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
  23797. set |= SUBSET_EXTENSION;
  23798. if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
  23799. (elemDecl->subtypes->flags &
  23800. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
  23801. set |= SUBSET_RESTRICTION;
  23802. /*
  23803. * REMOVED and CHANGED since this produced a parser context
  23804. * which adds to the string dict of the schema. So this would
  23805. * change the schema and we don't want this. We don't need
  23806. * the parser context anymore.
  23807. *
  23808. * if ((vctxt->pctxt == NULL) &&
  23809. * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
  23810. * return (-1);
  23811. */
  23812. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
  23813. elemDecl->subtypes, set) != 0) {
  23814. xmlChar *str = NULL;
  23815. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23816. XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
  23817. "The type definition '%s', specified by xsi:type, is "
  23818. "blocked or not validly derived from the type definition "
  23819. "of the element declaration",
  23820. xmlSchemaFormatQName(&str,
  23821. (*localType)->targetNamespace,
  23822. (*localType)->name),
  23823. NULL);
  23824. FREE_AND_NULL(str);
  23825. ret = vctxt->err;
  23826. *localType = NULL;
  23827. }
  23828. }
  23829. }
  23830. exit:
  23831. ACTIVATE_ELEM;
  23832. return (ret);
  23833. internal_error:
  23834. ACTIVATE_ELEM;
  23835. return (-1);
  23836. }
  23837. static int
  23838. xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
  23839. {
  23840. xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
  23841. xmlSchemaTypePtr actualType;
  23842. /*
  23843. * cvc-elt (3.3.4) : 1
  23844. */
  23845. if (elemDecl == NULL) {
  23846. VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
  23847. "No matching declaration available");
  23848. return (vctxt->err);
  23849. }
  23850. actualType = WXS_ELEM_TYPEDEF(elemDecl);
  23851. /*
  23852. * cvc-elt (3.3.4) : 2
  23853. */
  23854. if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
  23855. VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
  23856. "The element declaration is abstract");
  23857. return (vctxt->err);
  23858. }
  23859. if (actualType == NULL) {
  23860. VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
  23861. "The type definition is absent");
  23862. return (XML_SCHEMAV_CVC_TYPE_1);
  23863. }
  23864. if (vctxt->nbAttrInfos != 0) {
  23865. int ret;
  23866. xmlSchemaAttrInfoPtr iattr;
  23867. /*
  23868. * cvc-elt (3.3.4) : 3
  23869. * Handle 'xsi:nil'.
  23870. */
  23871. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  23872. XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
  23873. if (iattr) {
  23874. ACTIVATE_ATTRIBUTE(iattr);
  23875. /*
  23876. * Validate the value.
  23877. */
  23878. ret = xmlSchemaVCheckCVCSimpleType(
  23879. ACTXT_CAST vctxt, NULL,
  23880. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  23881. iattr->value, &(iattr->val), 1, 0, 0);
  23882. ACTIVATE_ELEM;
  23883. if (ret < 0) {
  23884. VERROR_INT("xmlSchemaValidateElemDecl",
  23885. "calling xmlSchemaVCheckCVCSimpleType() to "
  23886. "validate the attribute 'xsi:nil'");
  23887. return (-1);
  23888. }
  23889. if (ret == 0) {
  23890. if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
  23891. /*
  23892. * cvc-elt (3.3.4) : 3.1
  23893. */
  23894. VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
  23895. "The element is not 'nillable'");
  23896. /* Does not return an error on purpose. */
  23897. } else {
  23898. if (xmlSchemaValueGetAsBoolean(iattr->val)) {
  23899. /*
  23900. * cvc-elt (3.3.4) : 3.2.2
  23901. */
  23902. if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
  23903. (elemDecl->value != NULL)) {
  23904. VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
  23905. "The element cannot be 'nilled' because "
  23906. "there is a fixed value constraint defined "
  23907. "for it");
  23908. /* Does not return an error on purpose. */
  23909. } else
  23910. vctxt->inode->flags |=
  23911. XML_SCHEMA_ELEM_INFO_NILLED;
  23912. }
  23913. }
  23914. }
  23915. }
  23916. /*
  23917. * cvc-elt (3.3.4) : 4
  23918. * Handle 'xsi:type'.
  23919. */
  23920. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  23921. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  23922. if (iattr) {
  23923. xmlSchemaTypePtr localType = NULL;
  23924. ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
  23925. elemDecl);
  23926. if (ret != 0) {
  23927. if (ret == -1) {
  23928. VERROR_INT("xmlSchemaValidateElemDecl",
  23929. "calling xmlSchemaProcessXSIType() to "
  23930. "process the attribute 'xsi:type'");
  23931. return (-1);
  23932. }
  23933. /* Does not return an error on purpose. */
  23934. }
  23935. if (localType != NULL) {
  23936. vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
  23937. actualType = localType;
  23938. }
  23939. }
  23940. }
  23941. /*
  23942. * IDC: Register identity-constraint XPath matchers.
  23943. */
  23944. if ((elemDecl->idcs != NULL) &&
  23945. (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
  23946. return (-1);
  23947. /*
  23948. * No actual type definition.
  23949. */
  23950. if (actualType == NULL) {
  23951. VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
  23952. "The type definition is absent");
  23953. return (XML_SCHEMAV_CVC_TYPE_1);
  23954. }
  23955. /*
  23956. * Remember the actual type definition.
  23957. */
  23958. vctxt->inode->typeDef = actualType;
  23959. return (0);
  23960. }
  23961. static int
  23962. xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
  23963. {
  23964. xmlSchemaAttrInfoPtr iattr;
  23965. int ret = 0, i;
  23966. /*
  23967. * SPEC cvc-type (3.1.1)
  23968. * "The attributes of must be empty, excepting those whose namespace
  23969. * name is identical to http://www.w3.org/2001/XMLSchema-instance and
  23970. * whose local name is one of type, nil, schemaLocation or
  23971. * noNamespaceSchemaLocation."
  23972. */
  23973. if (vctxt->nbAttrInfos == 0)
  23974. return (0);
  23975. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  23976. iattr = vctxt->attrInfos[i];
  23977. if (! iattr->metaType) {
  23978. ACTIVATE_ATTRIBUTE(iattr)
  23979. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  23980. XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
  23981. ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
  23982. }
  23983. }
  23984. ACTIVATE_ELEM
  23985. return (ret);
  23986. }
  23987. /*
  23988. * Cleanup currently used attribute infos.
  23989. */
  23990. static void
  23991. xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
  23992. {
  23993. int i;
  23994. xmlSchemaAttrInfoPtr attr;
  23995. if (vctxt->nbAttrInfos == 0)
  23996. return;
  23997. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  23998. attr = vctxt->attrInfos[i];
  23999. if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
  24000. if (attr->localName != NULL)
  24001. xmlFree((xmlChar *) attr->localName);
  24002. if (attr->nsName != NULL)
  24003. xmlFree((xmlChar *) attr->nsName);
  24004. }
  24005. if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  24006. if (attr->value != NULL)
  24007. xmlFree((xmlChar *) attr->value);
  24008. }
  24009. if (attr->val != NULL) {
  24010. xmlSchemaFreeValue(attr->val);
  24011. attr->val = NULL;
  24012. }
  24013. memset(attr, 0, sizeof(xmlSchemaAttrInfo));
  24014. }
  24015. vctxt->nbAttrInfos = 0;
  24016. }
  24017. /*
  24018. * 3.4.4 Complex Type Definition Validation Rules
  24019. * Element Locally Valid (Complex Type) (cvc-complex-type)
  24020. * 3.2.4 Attribute Declaration Validation Rules
  24021. * Validation Rule: Attribute Locally Valid (cvc-attribute)
  24022. * Attribute Locally Valid (Use) (cvc-au)
  24023. *
  24024. * Only "assessed" attribute information items will be visible to
  24025. * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
  24026. */
  24027. static int
  24028. xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
  24029. {
  24030. xmlSchemaTypePtr type = vctxt->inode->typeDef;
  24031. xmlSchemaItemListPtr attrUseList;
  24032. xmlSchemaAttributeUsePtr attrUse = NULL;
  24033. xmlSchemaAttributePtr attrDecl = NULL;
  24034. xmlSchemaAttrInfoPtr iattr, tmpiattr;
  24035. int i, j, found, nbAttrs, nbUses;
  24036. int xpathRes = 0, res, wildIDs = 0, fixed;
  24037. xmlNodePtr defAttrOwnerElem = NULL;
  24038. /*
  24039. * SPEC (cvc-attribute)
  24040. * (1) "The declaration must not be `absent` (see Missing
  24041. * Sub-components ($5.3) for how this can fail to be
  24042. * the case)."
  24043. * (2) "Its {type definition} must not be absent."
  24044. *
  24045. * NOTE (1) + (2): This is not handled here, since we currently do not
  24046. * allow validation against schemas which have missing sub-components.
  24047. *
  24048. * SPEC (cvc-complex-type)
  24049. * (3) "For each attribute information item in the element information
  24050. * item's [attributes] excepting those whose [namespace name] is
  24051. * identical to http://www.w3.org/2001/XMLSchema-instance and whose
  24052. * [local name] is one of type, nil, schemaLocation or
  24053. * noNamespaceSchemaLocation, the appropriate case among the following
  24054. * must be true:
  24055. *
  24056. */
  24057. attrUseList = (xmlSchemaItemListPtr) type->attrUses;
  24058. /*
  24059. * @nbAttrs is the number of attributes present in the instance.
  24060. */
  24061. nbAttrs = vctxt->nbAttrInfos;
  24062. if (attrUseList != NULL)
  24063. nbUses = attrUseList->nbItems;
  24064. else
  24065. nbUses = 0;
  24066. for (i = 0; i < nbUses; i++) {
  24067. found = 0;
  24068. attrUse = attrUseList->items[i];
  24069. attrDecl = WXS_ATTRUSE_DECL(attrUse);
  24070. for (j = 0; j < nbAttrs; j++) {
  24071. iattr = vctxt->attrInfos[j];
  24072. /*
  24073. * SPEC (cvc-complex-type) (3)
  24074. * Skip meta attributes.
  24075. */
  24076. if (iattr->metaType)
  24077. continue;
  24078. if (iattr->localName[0] != attrDecl->name[0])
  24079. continue;
  24080. if (!xmlStrEqual(iattr->localName, attrDecl->name))
  24081. continue;
  24082. if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
  24083. continue;
  24084. found = 1;
  24085. /*
  24086. * SPEC (cvc-complex-type)
  24087. * (3.1) "If there is among the {attribute uses} an attribute
  24088. * use with an {attribute declaration} whose {name} matches
  24089. * the attribute information item's [local name] and whose
  24090. * {target namespace} is identical to the attribute information
  24091. * item's [namespace name] (where an `absent` {target namespace}
  24092. * is taken to be identical to a [namespace name] with no value),
  24093. * then the attribute information must be `valid` with respect
  24094. * to that attribute use as per Attribute Locally Valid (Use)
  24095. * ($3.5.4). In this case the {attribute declaration} of that
  24096. * attribute use is the `context-determined declaration` for the
  24097. * attribute information item with respect to Schema-Validity
  24098. * Assessment (Attribute) ($3.2.4) and
  24099. * Assessment Outcome (Attribute) ($3.2.5).
  24100. */
  24101. iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
  24102. iattr->use = attrUse;
  24103. /*
  24104. * Context-determined declaration.
  24105. */
  24106. iattr->decl = attrDecl;
  24107. iattr->typeDef = attrDecl->subtypes;
  24108. break;
  24109. }
  24110. if (found)
  24111. continue;
  24112. if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
  24113. /*
  24114. * Handle non-existent, required attributes.
  24115. *
  24116. * SPEC (cvc-complex-type)
  24117. * (4) "The {attribute declaration} of each attribute use in
  24118. * the {attribute uses} whose {required} is true matches one
  24119. * of the attribute information items in the element information
  24120. * item's [attributes] as per clause 3.1 above."
  24121. */
  24122. tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
  24123. if (tmpiattr == NULL) {
  24124. VERROR_INT(
  24125. "xmlSchemaVAttributesComplex",
  24126. "calling xmlSchemaGetFreshAttrInfo()");
  24127. return (-1);
  24128. }
  24129. tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
  24130. tmpiattr->use = attrUse;
  24131. tmpiattr->decl = attrDecl;
  24132. } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
  24133. ((attrUse->defValue != NULL) ||
  24134. (attrDecl->defValue != NULL))) {
  24135. /*
  24136. * Handle non-existent, optional, default/fixed attributes.
  24137. */
  24138. tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
  24139. if (tmpiattr == NULL) {
  24140. VERROR_INT(
  24141. "xmlSchemaVAttributesComplex",
  24142. "calling xmlSchemaGetFreshAttrInfo()");
  24143. return (-1);
  24144. }
  24145. tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
  24146. tmpiattr->use = attrUse;
  24147. tmpiattr->decl = attrDecl;
  24148. tmpiattr->typeDef = attrDecl->subtypes;
  24149. tmpiattr->localName = attrDecl->name;
  24150. tmpiattr->nsName = attrDecl->targetNamespace;
  24151. }
  24152. }
  24153. if (vctxt->nbAttrInfos == 0)
  24154. return (0);
  24155. /*
  24156. * Validate against the wildcard.
  24157. */
  24158. if (type->attributeWildcard != NULL) {
  24159. /*
  24160. * SPEC (cvc-complex-type)
  24161. * (3.2.1) "There must be an {attribute wildcard}."
  24162. */
  24163. for (i = 0; i < nbAttrs; i++) {
  24164. iattr = vctxt->attrInfos[i];
  24165. /*
  24166. * SPEC (cvc-complex-type) (3)
  24167. * Skip meta attributes.
  24168. */
  24169. if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
  24170. continue;
  24171. /*
  24172. * SPEC (cvc-complex-type)
  24173. * (3.2.2) "The attribute information item must be `valid` with
  24174. * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
  24175. *
  24176. * SPEC Item Valid (Wildcard) (cvc-wildcard)
  24177. * "... its [namespace name] must be `valid` with respect to
  24178. * the wildcard constraint, as defined in Wildcard allows
  24179. * Namespace Name ($3.10.4)."
  24180. */
  24181. if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
  24182. iattr->nsName) == 0) {
  24183. /*
  24184. * Handle processContents.
  24185. *
  24186. * SPEC (cvc-wildcard):
  24187. * processContents | context-determined declaration:
  24188. * "strict" "mustFind"
  24189. * "lax" "none"
  24190. * "skip" "skip"
  24191. */
  24192. if (type->attributeWildcard->processContents ==
  24193. XML_SCHEMAS_ANY_SKIP) {
  24194. /*
  24195. * context-determined declaration = "skip"
  24196. *
  24197. * SPEC PSVI Assessment Outcome (Attribute)
  24198. * [validity] = "notKnown"
  24199. * [validation attempted] = "none"
  24200. */
  24201. iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
  24202. continue;
  24203. }
  24204. /*
  24205. * Find an attribute declaration.
  24206. */
  24207. iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
  24208. iattr->localName, iattr->nsName);
  24209. if (iattr->decl != NULL) {
  24210. iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
  24211. /*
  24212. * SPEC (cvc-complex-type)
  24213. * (5) "Let [Definition:] the wild IDs be the set of
  24214. * all attribute information item to which clause 3.2
  24215. * applied and whose `validation` resulted in a
  24216. * `context-determined declaration` of mustFind or no
  24217. * `context-determined declaration` at all, and whose
  24218. * [local name] and [namespace name] resolve (as
  24219. * defined by QName resolution (Instance) ($3.15.4)) to
  24220. * an attribute declaration whose {type definition} is
  24221. * or is derived from ID. Then all of the following
  24222. * must be true:"
  24223. */
  24224. iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
  24225. if (xmlSchemaIsDerivedFromBuiltInType(
  24226. iattr->typeDef, XML_SCHEMAS_ID)) {
  24227. /*
  24228. * SPEC (5.1) "There must be no more than one
  24229. * item in `wild IDs`."
  24230. */
  24231. if (wildIDs != 0) {
  24232. /* VAL TODO */
  24233. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
  24234. TODO
  24235. continue;
  24236. }
  24237. wildIDs++;
  24238. /*
  24239. * SPEC (cvc-complex-type)
  24240. * (5.2) "If `wild IDs` is non-empty, there must not
  24241. * be any attribute uses among the {attribute uses}
  24242. * whose {attribute declaration}'s {type definition}
  24243. * is or is derived from ID."
  24244. */
  24245. if (attrUseList != NULL) {
  24246. for (j = 0; j < attrUseList->nbItems; j++) {
  24247. if (xmlSchemaIsDerivedFromBuiltInType(
  24248. WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
  24249. XML_SCHEMAS_ID)) {
  24250. /* URGENT VAL TODO: implement */
  24251. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
  24252. TODO
  24253. break;
  24254. }
  24255. }
  24256. }
  24257. }
  24258. } else if (type->attributeWildcard->processContents ==
  24259. XML_SCHEMAS_ANY_LAX) {
  24260. iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
  24261. /*
  24262. * SPEC PSVI Assessment Outcome (Attribute)
  24263. * [validity] = "notKnown"
  24264. * [validation attempted] = "none"
  24265. */
  24266. } else {
  24267. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
  24268. }
  24269. }
  24270. }
  24271. }
  24272. if (vctxt->nbAttrInfos == 0)
  24273. return (0);
  24274. /*
  24275. * Get the owner element; needed for creation of default attributes.
  24276. * This fixes bug #341337, reported by David Grohmann.
  24277. */
  24278. if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
  24279. xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
  24280. if (ielem && ielem->node && ielem->node->doc)
  24281. defAttrOwnerElem = ielem->node;
  24282. }
  24283. /*
  24284. * Validate values, create default attributes, evaluate IDCs.
  24285. */
  24286. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  24287. iattr = vctxt->attrInfos[i];
  24288. /*
  24289. * VAL TODO: Note that we won't try to resolve IDCs to
  24290. * "lax" and "skip" validated attributes. Check what to
  24291. * do in this case.
  24292. */
  24293. if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
  24294. (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
  24295. continue;
  24296. /*
  24297. * VAL TODO: What to do if the type definition is missing?
  24298. */
  24299. if (iattr->typeDef == NULL) {
  24300. iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
  24301. continue;
  24302. }
  24303. ACTIVATE_ATTRIBUTE(iattr);
  24304. fixed = 0;
  24305. xpathRes = 0;
  24306. if (vctxt->xpathStates != NULL) {
  24307. /*
  24308. * Evaluate IDCs.
  24309. */
  24310. xpathRes = xmlSchemaXPathEvaluate(vctxt,
  24311. XML_ATTRIBUTE_NODE);
  24312. if (xpathRes == -1) {
  24313. VERROR_INT("xmlSchemaVAttributesComplex",
  24314. "calling xmlSchemaXPathEvaluate()");
  24315. goto internal_error;
  24316. }
  24317. }
  24318. if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
  24319. /*
  24320. * Default/fixed attributes.
  24321. * We need the value only if we need to resolve IDCs or
  24322. * will create default attributes.
  24323. */
  24324. if ((xpathRes) || (defAttrOwnerElem)) {
  24325. if (iattr->use->defValue != NULL) {
  24326. iattr->value = (xmlChar *) iattr->use->defValue;
  24327. iattr->val = iattr->use->defVal;
  24328. } else {
  24329. iattr->value = (xmlChar *) iattr->decl->defValue;
  24330. iattr->val = iattr->decl->defVal;
  24331. }
  24332. /*
  24333. * IDCs will consume the precomputed default value,
  24334. * so we need to clone it.
  24335. */
  24336. if (iattr->val == NULL) {
  24337. VERROR_INT("xmlSchemaVAttributesComplex",
  24338. "default/fixed value on an attribute use was "
  24339. "not precomputed");
  24340. goto internal_error;
  24341. }
  24342. iattr->val = xmlSchemaCopyValue(iattr->val);
  24343. if (iattr->val == NULL) {
  24344. VERROR_INT("xmlSchemaVAttributesComplex",
  24345. "calling xmlSchemaCopyValue()");
  24346. goto internal_error;
  24347. }
  24348. }
  24349. /*
  24350. * PSVI: Add the default attribute to the current element.
  24351. * VAL TODO: Should we use the *normalized* value? This currently
  24352. * uses the *initial* value.
  24353. */
  24354. if (defAttrOwnerElem) {
  24355. xmlChar *normValue;
  24356. const xmlChar *value;
  24357. value = iattr->value;
  24358. /*
  24359. * Normalize the value.
  24360. */
  24361. normValue = xmlSchemaNormalizeValue(iattr->typeDef,
  24362. iattr->value);
  24363. if (normValue != NULL)
  24364. value = BAD_CAST normValue;
  24365. if (iattr->nsName == NULL) {
  24366. if (xmlNewProp(defAttrOwnerElem,
  24367. iattr->localName, value) == NULL) {
  24368. VERROR_INT("xmlSchemaVAttributesComplex",
  24369. "calling xmlNewProp()");
  24370. if (normValue != NULL)
  24371. xmlFree(normValue);
  24372. goto internal_error;
  24373. }
  24374. } else {
  24375. xmlNsPtr ns;
  24376. ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
  24377. defAttrOwnerElem, iattr->nsName);
  24378. if (ns == NULL) {
  24379. xmlChar prefix[12];
  24380. int counter = 0;
  24381. /*
  24382. * Create a namespace declaration on the validation
  24383. * root node if no namespace declaration is in scope.
  24384. */
  24385. do {
  24386. snprintf((char *) prefix, 12, "p%d", counter++);
  24387. ns = xmlSearchNs(defAttrOwnerElem->doc,
  24388. defAttrOwnerElem, BAD_CAST prefix);
  24389. if (counter > 1000) {
  24390. VERROR_INT(
  24391. "xmlSchemaVAttributesComplex",
  24392. "could not compute a ns prefix for a "
  24393. "default/fixed attribute");
  24394. if (normValue != NULL)
  24395. xmlFree(normValue);
  24396. goto internal_error;
  24397. }
  24398. } while (ns != NULL);
  24399. ns = xmlNewNs(vctxt->validationRoot,
  24400. iattr->nsName, BAD_CAST prefix);
  24401. }
  24402. /*
  24403. * TODO:
  24404. * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
  24405. * If we have QNames: do we need to ensure there's a
  24406. * prefix defined for the QName?
  24407. */
  24408. xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
  24409. }
  24410. if (normValue != NULL)
  24411. xmlFree(normValue);
  24412. }
  24413. /*
  24414. * Go directly to IDC evaluation.
  24415. */
  24416. goto eval_idcs;
  24417. }
  24418. /*
  24419. * Validate the value.
  24420. */
  24421. if (vctxt->value != NULL) {
  24422. /*
  24423. * Free last computed value; just for safety reasons.
  24424. */
  24425. xmlSchemaFreeValue(vctxt->value);
  24426. vctxt->value = NULL;
  24427. }
  24428. /*
  24429. * Note that the attribute *use* can be unavailable, if
  24430. * the attribute was a wild attribute.
  24431. */
  24432. if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
  24433. ((iattr->use != NULL) &&
  24434. (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
  24435. fixed = 1;
  24436. else
  24437. fixed = 0;
  24438. /*
  24439. * SPEC (cvc-attribute)
  24440. * (3) "The item's `normalized value` must be locally `valid`
  24441. * with respect to that {type definition} as per
  24442. * String Valid ($3.14.4)."
  24443. *
  24444. * VAL TODO: Do we already have the
  24445. * "normalized attribute value" here?
  24446. */
  24447. if (xpathRes || fixed) {
  24448. iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
  24449. /*
  24450. * Request a computed value.
  24451. */
  24452. res = xmlSchemaVCheckCVCSimpleType(
  24453. ACTXT_CAST vctxt,
  24454. iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
  24455. 1, 1, 0);
  24456. } else {
  24457. res = xmlSchemaVCheckCVCSimpleType(
  24458. ACTXT_CAST vctxt,
  24459. iattr->node, iattr->typeDef, iattr->value, NULL,
  24460. 1, 0, 0);
  24461. }
  24462. if (res != 0) {
  24463. if (res == -1) {
  24464. VERROR_INT("xmlSchemaVAttributesComplex",
  24465. "calling xmlSchemaStreamValidateSimpleTypeValue()");
  24466. goto internal_error;
  24467. }
  24468. iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
  24469. /*
  24470. * SPEC PSVI Assessment Outcome (Attribute)
  24471. * [validity] = "invalid"
  24472. */
  24473. goto eval_idcs;
  24474. }
  24475. if (fixed) {
  24476. /*
  24477. * SPEC Attribute Locally Valid (Use) (cvc-au)
  24478. * "For an attribute information item to be `valid`
  24479. * with respect to an attribute use its *normalized*
  24480. * value must match the *canonical* lexical
  24481. * representation of the attribute use's {value
  24482. * constraint}value, if it is present and fixed."
  24483. *
  24484. * VAL TODO: The requirement for the *canonical* value
  24485. * will be removed in XML Schema 1.1.
  24486. */
  24487. /*
  24488. * SPEC Attribute Locally Valid (cvc-attribute)
  24489. * (4) "The item's *actual* value must match the *value* of
  24490. * the {value constraint}, if it is present and fixed."
  24491. */
  24492. if (iattr->val == NULL) {
  24493. /* VAL TODO: A value was not precomputed. */
  24494. TODO
  24495. goto eval_idcs;
  24496. }
  24497. if ((iattr->use != NULL) &&
  24498. (iattr->use->defValue != NULL)) {
  24499. if (iattr->use->defVal == NULL) {
  24500. /* VAL TODO: A default value was not precomputed. */
  24501. TODO
  24502. goto eval_idcs;
  24503. }
  24504. iattr->vcValue = iattr->use->defValue;
  24505. /*
  24506. if (xmlSchemaCompareValuesWhtsp(attr->val,
  24507. (xmlSchemaWhitespaceValueType) ws,
  24508. attr->use->defVal,
  24509. (xmlSchemaWhitespaceValueType) ws) != 0) {
  24510. */
  24511. if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
  24512. iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
  24513. } else {
  24514. if (iattr->decl->defVal == NULL) {
  24515. /* VAL TODO: A default value was not precomputed. */
  24516. TODO
  24517. goto eval_idcs;
  24518. }
  24519. iattr->vcValue = iattr->decl->defValue;
  24520. /*
  24521. if (xmlSchemaCompareValuesWhtsp(attr->val,
  24522. (xmlSchemaWhitespaceValueType) ws,
  24523. attrDecl->defVal,
  24524. (xmlSchemaWhitespaceValueType) ws) != 0) {
  24525. */
  24526. if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
  24527. iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
  24528. }
  24529. /*
  24530. * [validity] = "valid"
  24531. */
  24532. }
  24533. eval_idcs:
  24534. /*
  24535. * Evaluate IDCs.
  24536. */
  24537. if (xpathRes) {
  24538. if (xmlSchemaXPathProcessHistory(vctxt,
  24539. vctxt->depth +1) == -1) {
  24540. VERROR_INT("xmlSchemaVAttributesComplex",
  24541. "calling xmlSchemaXPathEvaluate()");
  24542. goto internal_error;
  24543. }
  24544. } else if (vctxt->xpathStates != NULL)
  24545. xmlSchemaXPathPop(vctxt);
  24546. }
  24547. /*
  24548. * Report errors.
  24549. */
  24550. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  24551. iattr = vctxt->attrInfos[i];
  24552. if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
  24553. (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
  24554. (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
  24555. (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
  24556. continue;
  24557. ACTIVATE_ATTRIBUTE(iattr);
  24558. switch (iattr->state) {
  24559. case XML_SCHEMAS_ATTR_ERR_MISSING: {
  24560. xmlChar *str = NULL;
  24561. ACTIVATE_ELEM;
  24562. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24563. XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
  24564. "The attribute '%s' is required but missing",
  24565. xmlSchemaFormatQName(&str,
  24566. iattr->decl->targetNamespace,
  24567. iattr->decl->name),
  24568. NULL);
  24569. FREE_AND_NULL(str)
  24570. break;
  24571. }
  24572. case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
  24573. VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
  24574. "The type definition is absent");
  24575. break;
  24576. case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
  24577. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24578. XML_SCHEMAV_CVC_AU, NULL, NULL,
  24579. "The value '%s' does not match the fixed "
  24580. "value constraint '%s'",
  24581. iattr->value, iattr->vcValue);
  24582. break;
  24583. case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
  24584. VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
  24585. "No matching global attribute declaration available, but "
  24586. "demanded by the strict wildcard");
  24587. break;
  24588. case XML_SCHEMAS_ATTR_UNKNOWN:
  24589. if (iattr->metaType)
  24590. break;
  24591. /*
  24592. * MAYBE VAL TODO: One might report different error messages
  24593. * for the following errors.
  24594. */
  24595. if (type->attributeWildcard == NULL) {
  24596. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  24597. XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
  24598. } else {
  24599. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  24600. XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
  24601. }
  24602. break;
  24603. default:
  24604. break;
  24605. }
  24606. }
  24607. ACTIVATE_ELEM;
  24608. return (0);
  24609. internal_error:
  24610. ACTIVATE_ELEM;
  24611. return (-1);
  24612. }
  24613. static int
  24614. xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
  24615. int *skip)
  24616. {
  24617. xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
  24618. /*
  24619. * The namespace of the element was already identified to be
  24620. * matching the wildcard.
  24621. */
  24622. if ((skip == NULL) || (wild == NULL) ||
  24623. (wild->type != XML_SCHEMA_TYPE_ANY)) {
  24624. VERROR_INT("xmlSchemaValidateElemWildcard",
  24625. "bad arguments");
  24626. return (-1);
  24627. }
  24628. *skip = 0;
  24629. if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
  24630. /*
  24631. * URGENT VAL TODO: Either we need to position the stream to the
  24632. * next sibling, or walk the whole subtree.
  24633. */
  24634. *skip = 1;
  24635. return (0);
  24636. }
  24637. {
  24638. xmlSchemaElementPtr decl = NULL;
  24639. decl = xmlSchemaGetElem(vctxt->schema,
  24640. vctxt->inode->localName, vctxt->inode->nsName);
  24641. if (decl != NULL) {
  24642. vctxt->inode->decl = decl;
  24643. return (0);
  24644. }
  24645. }
  24646. if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
  24647. /* VAL TODO: Change to proper error code. */
  24648. VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
  24649. "No matching global element declaration available, but "
  24650. "demanded by the strict wildcard");
  24651. return (vctxt->err);
  24652. }
  24653. if (vctxt->nbAttrInfos != 0) {
  24654. xmlSchemaAttrInfoPtr iattr;
  24655. /*
  24656. * SPEC Validation Rule: Schema-Validity Assessment (Element)
  24657. * (1.2.1.2.1) - (1.2.1.2.3 )
  24658. *
  24659. * Use the xsi:type attribute for the type definition.
  24660. */
  24661. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  24662. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  24663. if (iattr != NULL) {
  24664. if (xmlSchemaProcessXSIType(vctxt, iattr,
  24665. &(vctxt->inode->typeDef), NULL) == -1) {
  24666. VERROR_INT("xmlSchemaValidateElemWildcard",
  24667. "calling xmlSchemaProcessXSIType() to "
  24668. "process the attribute 'xsi:nil'");
  24669. return (-1);
  24670. }
  24671. /*
  24672. * Don't return an error on purpose.
  24673. */
  24674. return (0);
  24675. }
  24676. }
  24677. /*
  24678. * SPEC Validation Rule: Schema-Validity Assessment (Element)
  24679. *
  24680. * Fallback to "anyType".
  24681. */
  24682. vctxt->inode->typeDef =
  24683. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  24684. return (0);
  24685. }
  24686. /*
  24687. * xmlSchemaCheckCOSValidDefault:
  24688. *
  24689. * This will be called if: not nilled, no content and a default/fixed
  24690. * value is provided.
  24691. */
  24692. static int
  24693. xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
  24694. const xmlChar *value,
  24695. xmlSchemaValPtr *val)
  24696. {
  24697. int ret = 0;
  24698. xmlSchemaNodeInfoPtr inode = vctxt->inode;
  24699. /*
  24700. * cos-valid-default:
  24701. * Schema Component Constraint: Element Default Valid (Immediate)
  24702. * For a string to be a valid default with respect to a type
  24703. * definition the appropriate case among the following must be true:
  24704. */
  24705. if WXS_IS_COMPLEX(inode->typeDef) {
  24706. /*
  24707. * Complex type.
  24708. *
  24709. * SPEC (2.1) "its {content type} must be a simple type definition
  24710. * or mixed."
  24711. * SPEC (2.2.2) "If the {content type} is mixed, then the {content
  24712. * type}'s particle must be `emptiable` as defined by
  24713. * Particle Emptiable ($3.9.6)."
  24714. */
  24715. if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
  24716. ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
  24717. (! WXS_EMPTIABLE(inode->typeDef)))) {
  24718. ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
  24719. /* NOTE that this covers (2.2.2) as well. */
  24720. VERROR(ret, NULL,
  24721. "For a string to be a valid default, the type definition "
  24722. "must be a simple type or a complex type with simple content "
  24723. "or mixed content and a particle emptiable");
  24724. return(ret);
  24725. }
  24726. }
  24727. /*
  24728. * 1 If the type definition is a simple type definition, then the string
  24729. * must be `valid` with respect to that definition as defined by String
  24730. * Valid ($3.14.4).
  24731. *
  24732. * AND
  24733. *
  24734. * 2.2.1 If the {content type} is a simple type definition, then the
  24735. * string must be `valid` with respect to that simple type definition
  24736. * as defined by String Valid ($3.14.4).
  24737. */
  24738. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24739. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
  24740. NULL, inode->typeDef, value, val, 1, 1, 0);
  24741. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24742. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
  24743. NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
  24744. }
  24745. if (ret < 0) {
  24746. VERROR_INT("xmlSchemaCheckCOSValidDefault",
  24747. "calling xmlSchemaVCheckCVCSimpleType()");
  24748. }
  24749. return (ret);
  24750. }
  24751. static void
  24752. xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
  24753. const xmlChar * name ATTRIBUTE_UNUSED,
  24754. void *transdata, void *inputdata)
  24755. {
  24756. xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
  24757. xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
  24758. inode->decl = item;
  24759. #ifdef DEBUG_CONTENT
  24760. {
  24761. xmlChar *str = NULL;
  24762. if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
  24763. xmlGenericError(xmlGenericErrorContext,
  24764. "AUTOMATON callback for '%s' [declaration]\n",
  24765. xmlSchemaFormatQName(&str,
  24766. inode->localName, inode->nsName));
  24767. } else {
  24768. xmlGenericError(xmlGenericErrorContext,
  24769. "AUTOMATON callback for '%s' [wildcard]\n",
  24770. xmlSchemaFormatQName(&str,
  24771. inode->localName, inode->nsName));
  24772. }
  24773. FREE_AND_NULL(str)
  24774. }
  24775. #endif
  24776. }
  24777. static int
  24778. xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
  24779. {
  24780. vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
  24781. if (vctxt->inode == NULL) {
  24782. VERROR_INT("xmlSchemaValidatorPushElem",
  24783. "calling xmlSchemaGetFreshElemInfo()");
  24784. return (-1);
  24785. }
  24786. vctxt->nbAttrInfos = 0;
  24787. return (0);
  24788. }
  24789. static int
  24790. xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
  24791. xmlSchemaNodeInfoPtr inode,
  24792. xmlSchemaTypePtr type,
  24793. const xmlChar *value)
  24794. {
  24795. if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
  24796. return (xmlSchemaVCheckCVCSimpleType(
  24797. ACTXT_CAST vctxt, NULL,
  24798. type, value, &(inode->val), 1, 1, 0));
  24799. else
  24800. return (xmlSchemaVCheckCVCSimpleType(
  24801. ACTXT_CAST vctxt, NULL,
  24802. type, value, NULL, 1, 0, 0));
  24803. }
  24804. /*
  24805. * Process END of element.
  24806. */
  24807. static int
  24808. xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
  24809. {
  24810. int ret = 0;
  24811. xmlSchemaNodeInfoPtr inode = vctxt->inode;
  24812. if (vctxt->nbAttrInfos != 0)
  24813. xmlSchemaClearAttrInfos(vctxt);
  24814. if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
  24815. /*
  24816. * This element was not expected;
  24817. * we will not validate child elements of broken parents.
  24818. * Skip validation of all content of the parent.
  24819. */
  24820. vctxt->skipDepth = vctxt->depth -1;
  24821. goto end_elem;
  24822. }
  24823. if ((inode->typeDef == NULL) ||
  24824. (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
  24825. /*
  24826. * 1. the type definition might be missing if the element was
  24827. * error prone
  24828. * 2. it might be abstract.
  24829. */
  24830. goto end_elem;
  24831. }
  24832. /*
  24833. * Check the content model.
  24834. */
  24835. if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
  24836. (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
  24837. /*
  24838. * Workaround for "anyType".
  24839. */
  24840. if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
  24841. goto character_content;
  24842. if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
  24843. xmlChar *values[10];
  24844. int terminal, nbval = 10, nbneg;
  24845. if (inode->regexCtxt == NULL) {
  24846. /*
  24847. * Create the regex context.
  24848. */
  24849. inode->regexCtxt =
  24850. xmlRegNewExecCtxt(inode->typeDef->contModel,
  24851. xmlSchemaVContentModelCallback, vctxt);
  24852. if (inode->regexCtxt == NULL) {
  24853. VERROR_INT("xmlSchemaValidatorPopElem",
  24854. "failed to create a regex context");
  24855. goto internal_error;
  24856. }
  24857. #ifdef DEBUG_AUTOMATA
  24858. xmlGenericError(xmlGenericErrorContext,
  24859. "AUTOMATON create on '%s'\n", inode->localName);
  24860. #endif
  24861. }
  24862. /*
  24863. * Do not check further content if the node has been nilled
  24864. */
  24865. if (INODE_NILLED(inode)) {
  24866. ret = 0;
  24867. #ifdef DEBUG_AUTOMATA
  24868. xmlGenericError(xmlGenericErrorContext,
  24869. "AUTOMATON succeeded on nilled '%s'\n",
  24870. inode->localName);
  24871. #endif
  24872. goto skip_nilled;
  24873. }
  24874. /*
  24875. * Get hold of the still expected content, since a further
  24876. * call to xmlRegExecPushString() will lose this information.
  24877. */
  24878. xmlRegExecNextValues(inode->regexCtxt,
  24879. &nbval, &nbneg, &values[0], &terminal);
  24880. ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
  24881. if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
  24882. /*
  24883. * Still missing something.
  24884. */
  24885. ret = 1;
  24886. inode->flags |=
  24887. XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
  24888. xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
  24889. XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
  24890. "Missing child element(s)",
  24891. nbval, nbneg, values);
  24892. #ifdef DEBUG_AUTOMATA
  24893. xmlGenericError(xmlGenericErrorContext,
  24894. "AUTOMATON missing ERROR on '%s'\n",
  24895. inode->localName);
  24896. #endif
  24897. } else {
  24898. /*
  24899. * Content model is satisfied.
  24900. */
  24901. ret = 0;
  24902. #ifdef DEBUG_AUTOMATA
  24903. xmlGenericError(xmlGenericErrorContext,
  24904. "AUTOMATON succeeded on '%s'\n",
  24905. inode->localName);
  24906. #endif
  24907. }
  24908. }
  24909. }
  24910. skip_nilled:
  24911. if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
  24912. goto end_elem;
  24913. character_content:
  24914. if (vctxt->value != NULL) {
  24915. xmlSchemaFreeValue(vctxt->value);
  24916. vctxt->value = NULL;
  24917. }
  24918. /*
  24919. * Check character content.
  24920. */
  24921. if (inode->decl == NULL) {
  24922. /*
  24923. * Speedup if no declaration exists.
  24924. */
  24925. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24926. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24927. inode, inode->typeDef, inode->value);
  24928. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24929. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24930. inode, inode->typeDef->contentTypeDef,
  24931. inode->value);
  24932. }
  24933. if (ret < 0) {
  24934. VERROR_INT("xmlSchemaValidatorPopElem",
  24935. "calling xmlSchemaVCheckCVCSimpleType()");
  24936. goto internal_error;
  24937. }
  24938. goto end_elem;
  24939. }
  24940. /*
  24941. * cvc-elt (3.3.4) : 5
  24942. * The appropriate case among the following must be true:
  24943. */
  24944. /*
  24945. * cvc-elt (3.3.4) : 5.1
  24946. * If the declaration has a {value constraint},
  24947. * the item has neither element nor character [children] and
  24948. * clause 3.2 has not applied, then all of the following must be true:
  24949. */
  24950. if ((inode->decl->value != NULL) &&
  24951. (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
  24952. (! INODE_NILLED(inode))) {
  24953. /*
  24954. * cvc-elt (3.3.4) : 5.1.1
  24955. * If the `actual type definition` is a `local type definition`
  24956. * then the canonical lexical representation of the {value constraint}
  24957. * value must be a valid default for the `actual type definition` as
  24958. * defined in Element Default Valid (Immediate) ($3.3.6).
  24959. */
  24960. /*
  24961. * NOTE: 'local' above means types acquired by xsi:type.
  24962. * NOTE: Although the *canonical* value is stated, it is not
  24963. * relevant if canonical or not. Additionally XML Schema 1.1
  24964. * will removed this requirement as well.
  24965. */
  24966. if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
  24967. ret = xmlSchemaCheckCOSValidDefault(vctxt,
  24968. inode->decl->value, &(inode->val));
  24969. if (ret != 0) {
  24970. if (ret < 0) {
  24971. VERROR_INT("xmlSchemaValidatorPopElem",
  24972. "calling xmlSchemaCheckCOSValidDefault()");
  24973. goto internal_error;
  24974. }
  24975. goto end_elem;
  24976. }
  24977. /*
  24978. * Stop here, to avoid redundant validation of the value
  24979. * (see following).
  24980. */
  24981. goto default_psvi;
  24982. }
  24983. /*
  24984. * cvc-elt (3.3.4) : 5.1.2
  24985. * The element information item with the canonical lexical
  24986. * representation of the {value constraint} value used as its
  24987. * `normalized value` must be `valid` with respect to the
  24988. * `actual type definition` as defined by Element Locally Valid (Type)
  24989. * ($3.3.4).
  24990. */
  24991. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24992. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24993. inode, inode->typeDef, inode->decl->value);
  24994. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24995. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24996. inode, inode->typeDef->contentTypeDef,
  24997. inode->decl->value);
  24998. }
  24999. if (ret != 0) {
  25000. if (ret < 0) {
  25001. VERROR_INT("xmlSchemaValidatorPopElem",
  25002. "calling xmlSchemaVCheckCVCSimpleType()");
  25003. goto internal_error;
  25004. }
  25005. goto end_elem;
  25006. }
  25007. default_psvi:
  25008. /*
  25009. * PSVI: Create a text node on the instance element.
  25010. */
  25011. if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
  25012. (inode->node != NULL)) {
  25013. xmlNodePtr textChild;
  25014. xmlChar *normValue;
  25015. /*
  25016. * VAL TODO: Normalize the value.
  25017. */
  25018. normValue = xmlSchemaNormalizeValue(inode->typeDef,
  25019. inode->decl->value);
  25020. if (normValue != NULL) {
  25021. textChild = xmlNewText(BAD_CAST normValue);
  25022. xmlFree(normValue);
  25023. } else
  25024. textChild = xmlNewText(inode->decl->value);
  25025. if (textChild == NULL) {
  25026. VERROR_INT("xmlSchemaValidatorPopElem",
  25027. "calling xmlNewText()");
  25028. goto internal_error;
  25029. } else
  25030. xmlAddChild(inode->node, textChild);
  25031. }
  25032. } else if (! INODE_NILLED(inode)) {
  25033. /*
  25034. * 5.2.1 The element information item must be `valid` with respect
  25035. * to the `actual type definition` as defined by Element Locally
  25036. * Valid (Type) ($3.3.4).
  25037. */
  25038. if (WXS_IS_SIMPLE(inode->typeDef)) {
  25039. /*
  25040. * SPEC (cvc-type) (3.1)
  25041. * "If the type definition is a simple type definition, ..."
  25042. * (3.1.3) "If clause 3.2 of Element Locally Valid
  25043. * (Element) ($3.3.4) did not apply, then the `normalized value`
  25044. * must be `valid` with respect to the type definition as defined
  25045. * by String Valid ($3.14.4).
  25046. */
  25047. ret = xmlSchemaVCheckINodeDataType(vctxt,
  25048. inode, inode->typeDef, inode->value);
  25049. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  25050. /*
  25051. * SPEC (cvc-type) (3.2) "If the type definition is a complex type
  25052. * definition, then the element information item must be
  25053. * `valid` with respect to the type definition as per
  25054. * Element Locally Valid (Complex Type) ($3.4.4);"
  25055. *
  25056. * SPEC (cvc-complex-type) (2.2)
  25057. * "If the {content type} is a simple type definition, ...
  25058. * the `normalized value` of the element information item is
  25059. * `valid` with respect to that simple type definition as
  25060. * defined by String Valid ($3.14.4)."
  25061. */
  25062. ret = xmlSchemaVCheckINodeDataType(vctxt,
  25063. inode, inode->typeDef->contentTypeDef, inode->value);
  25064. }
  25065. if (ret != 0) {
  25066. if (ret < 0) {
  25067. VERROR_INT("xmlSchemaValidatorPopElem",
  25068. "calling xmlSchemaVCheckCVCSimpleType()");
  25069. goto internal_error;
  25070. }
  25071. goto end_elem;
  25072. }
  25073. /*
  25074. * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
  25075. * not applied, all of the following must be true:
  25076. */
  25077. if ((inode->decl->value != NULL) &&
  25078. (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
  25079. /*
  25080. * TODO: We will need a computed value, when comparison is
  25081. * done on computed values.
  25082. */
  25083. /*
  25084. * 5.2.2.1 The element information item must have no element
  25085. * information item [children].
  25086. */
  25087. if (inode->flags &
  25088. XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
  25089. ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
  25090. VERROR(ret, NULL,
  25091. "The content must not contain element nodes since "
  25092. "there is a fixed value constraint");
  25093. goto end_elem;
  25094. } else {
  25095. /*
  25096. * 5.2.2.2 The appropriate case among the following must
  25097. * be true:
  25098. */
  25099. if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
  25100. /*
  25101. * 5.2.2.2.1 If the {content type} of the `actual type
  25102. * definition` is mixed, then the *initial value* of the
  25103. * item must match the canonical lexical representation
  25104. * of the {value constraint} value.
  25105. *
  25106. * ... the *initial value* of an element information
  25107. * item is the string composed of, in order, the
  25108. * [character code] of each character information item in
  25109. * the [children] of that element information item.
  25110. */
  25111. if (! xmlStrEqual(inode->value, inode->decl->value)){
  25112. /*
  25113. * VAL TODO: Report invalid & expected values as well.
  25114. * VAL TODO: Implement the canonical stuff.
  25115. */
  25116. ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
  25117. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  25118. ret, NULL, NULL,
  25119. "The initial value '%s' does not match the fixed "
  25120. "value constraint '%s'",
  25121. inode->value, inode->decl->value);
  25122. goto end_elem;
  25123. }
  25124. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  25125. /*
  25126. * 5.2.2.2.2 If the {content type} of the `actual type
  25127. * definition` is a simple type definition, then the
  25128. * *actual value* of the item must match the canonical
  25129. * lexical representation of the {value constraint} value.
  25130. */
  25131. /*
  25132. * VAL TODO: *actual value* is the normalized value, impl.
  25133. * this.
  25134. * VAL TODO: Report invalid & expected values as well.
  25135. * VAL TODO: Implement a comparison with the computed values.
  25136. */
  25137. if (! xmlStrEqual(inode->value,
  25138. inode->decl->value)) {
  25139. ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
  25140. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  25141. ret, NULL, NULL,
  25142. "The actual value '%s' does not match the fixed "
  25143. "value constraint '%s'",
  25144. inode->value,
  25145. inode->decl->value);
  25146. goto end_elem;
  25147. }
  25148. }
  25149. }
  25150. }
  25151. }
  25152. end_elem:
  25153. if (vctxt->depth < 0) {
  25154. /* TODO: raise error? */
  25155. return (0);
  25156. }
  25157. if (vctxt->depth == vctxt->skipDepth)
  25158. vctxt->skipDepth = -1;
  25159. /*
  25160. * Evaluate the history of XPath state objects.
  25161. */
  25162. if (inode->appliedXPath &&
  25163. (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
  25164. goto internal_error;
  25165. /*
  25166. * MAYBE TODO:
  25167. * SPEC (6) "The element information item must be `valid` with
  25168. * respect to each of the {identity-constraint definitions} as per
  25169. * Identity-constraint Satisfied ($3.11.4)."
  25170. */
  25171. /*
  25172. * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
  25173. * need to be built in any case.
  25174. * We will currently build IDC node-tables and bubble them only if
  25175. * keyrefs do exist.
  25176. */
  25177. /*
  25178. * Add the current IDC target-nodes to the IDC node-tables.
  25179. */
  25180. if ((inode->idcMatchers != NULL) &&
  25181. (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
  25182. {
  25183. if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
  25184. goto internal_error;
  25185. }
  25186. /*
  25187. * Validate IDC keyrefs.
  25188. */
  25189. if (vctxt->inode->hasKeyrefs)
  25190. if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
  25191. goto internal_error;
  25192. /*
  25193. * Merge/free the IDC table.
  25194. */
  25195. if (inode->idcTable != NULL) {
  25196. #ifdef DEBUG_IDC_NODE_TABLE
  25197. xmlSchemaDebugDumpIDCTable(stdout,
  25198. inode->nsName,
  25199. inode->localName,
  25200. inode->idcTable);
  25201. #endif
  25202. if ((vctxt->depth > 0) &&
  25203. (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
  25204. {
  25205. /*
  25206. * Merge the IDC node table with the table of the parent node.
  25207. */
  25208. if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
  25209. goto internal_error;
  25210. }
  25211. }
  25212. /*
  25213. * Clear the current ielem.
  25214. * VAL TODO: Don't free the PSVI IDC tables if they are
  25215. * requested for the PSVI.
  25216. */
  25217. xmlSchemaClearElemInfo(vctxt, inode);
  25218. /*
  25219. * Skip further processing if we are on the validation root.
  25220. */
  25221. if (vctxt->depth == 0) {
  25222. vctxt->depth--;
  25223. vctxt->inode = NULL;
  25224. return (0);
  25225. }
  25226. /*
  25227. * Reset the keyrefDepth if needed.
  25228. */
  25229. if (vctxt->aidcs != NULL) {
  25230. xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
  25231. do {
  25232. if (aidc->keyrefDepth == vctxt->depth) {
  25233. /*
  25234. * A 'keyrefDepth' of a key/unique IDC matches the current
  25235. * depth, this means that we are leaving the scope of the
  25236. * top-most keyref IDC which refers to this IDC.
  25237. */
  25238. aidc->keyrefDepth = -1;
  25239. }
  25240. aidc = aidc->next;
  25241. } while (aidc != NULL);
  25242. }
  25243. vctxt->depth--;
  25244. vctxt->inode = vctxt->elemInfos[vctxt->depth];
  25245. /*
  25246. * VAL TODO: 7 If the element information item is the `validation root`, it must be
  25247. * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
  25248. */
  25249. return (ret);
  25250. internal_error:
  25251. vctxt->err = -1;
  25252. return (-1);
  25253. }
  25254. /*
  25255. * 3.4.4 Complex Type Definition Validation Rules
  25256. * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
  25257. */
  25258. static int
  25259. xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
  25260. {
  25261. xmlSchemaNodeInfoPtr pielem;
  25262. xmlSchemaTypePtr ptype;
  25263. int ret = 0;
  25264. if (vctxt->depth <= 0) {
  25265. VERROR_INT("xmlSchemaValidateChildElem",
  25266. "not intended for the validation root");
  25267. return (-1);
  25268. }
  25269. pielem = vctxt->elemInfos[vctxt->depth -1];
  25270. if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25271. pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25272. /*
  25273. * Handle 'nilled' elements.
  25274. */
  25275. if (INODE_NILLED(pielem)) {
  25276. /*
  25277. * SPEC (cvc-elt) (3.3.4) : (3.2.1)
  25278. */
  25279. ACTIVATE_PARENT_ELEM;
  25280. ret = XML_SCHEMAV_CVC_ELT_3_2_1;
  25281. VERROR(ret, NULL,
  25282. "Neither character nor element content is allowed, "
  25283. "because the element was 'nilled'");
  25284. ACTIVATE_ELEM;
  25285. goto unexpected_elem;
  25286. }
  25287. ptype = pielem->typeDef;
  25288. if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
  25289. /*
  25290. * Workaround for "anyType": we have currently no content model
  25291. * assigned for "anyType", so handle it explicitly.
  25292. * "anyType" has an unbounded, lax "any" wildcard.
  25293. */
  25294. vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
  25295. vctxt->inode->localName,
  25296. vctxt->inode->nsName);
  25297. if (vctxt->inode->decl == NULL) {
  25298. xmlSchemaAttrInfoPtr iattr;
  25299. /*
  25300. * Process "xsi:type".
  25301. * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
  25302. */
  25303. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  25304. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  25305. if (iattr != NULL) {
  25306. ret = xmlSchemaProcessXSIType(vctxt, iattr,
  25307. &(vctxt->inode->typeDef), NULL);
  25308. if (ret != 0) {
  25309. if (ret == -1) {
  25310. VERROR_INT("xmlSchemaValidateChildElem",
  25311. "calling xmlSchemaProcessXSIType() to "
  25312. "process the attribute 'xsi:nil'");
  25313. return (-1);
  25314. }
  25315. return (ret);
  25316. }
  25317. } else {
  25318. /*
  25319. * Fallback to "anyType".
  25320. *
  25321. * SPEC (cvc-assess-elt)
  25322. * "If the item cannot be `strictly assessed`, [...]
  25323. * an element information item's schema validity may be laxly
  25324. * assessed if its `context-determined declaration` is not
  25325. * skip by `validating` with respect to the `ur-type
  25326. * definition` as per Element Locally Valid (Type) ($3.3.4)."
  25327. */
  25328. vctxt->inode->typeDef =
  25329. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  25330. }
  25331. }
  25332. return (0);
  25333. }
  25334. switch (ptype->contentType) {
  25335. case XML_SCHEMA_CONTENT_EMPTY:
  25336. /*
  25337. * SPEC (2.1) "If the {content type} is empty, then the
  25338. * element information item has no character or element
  25339. * information item [children]."
  25340. */
  25341. ACTIVATE_PARENT_ELEM
  25342. ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
  25343. VERROR(ret, NULL,
  25344. "Element content is not allowed, "
  25345. "because the content type is empty");
  25346. ACTIVATE_ELEM
  25347. goto unexpected_elem;
  25348. break;
  25349. case XML_SCHEMA_CONTENT_MIXED:
  25350. case XML_SCHEMA_CONTENT_ELEMENTS: {
  25351. xmlRegExecCtxtPtr regexCtxt;
  25352. xmlChar *values[10];
  25353. int terminal, nbval = 10, nbneg;
  25354. /* VAL TODO: Optimized "anyType" validation.*/
  25355. if (ptype->contModel == NULL) {
  25356. VERROR_INT("xmlSchemaValidateChildElem",
  25357. "type has elem content but no content model");
  25358. return (-1);
  25359. }
  25360. /*
  25361. * Safety belt for evaluation if the cont. model was already
  25362. * examined to be invalid.
  25363. */
  25364. if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
  25365. VERROR_INT("xmlSchemaValidateChildElem",
  25366. "validating elem, but elem content is already invalid");
  25367. return (-1);
  25368. }
  25369. regexCtxt = pielem->regexCtxt;
  25370. if (regexCtxt == NULL) {
  25371. /*
  25372. * Create the regex context.
  25373. */
  25374. regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
  25375. xmlSchemaVContentModelCallback, vctxt);
  25376. if (regexCtxt == NULL) {
  25377. VERROR_INT("xmlSchemaValidateChildElem",
  25378. "failed to create a regex context");
  25379. return (-1);
  25380. }
  25381. pielem->regexCtxt = regexCtxt;
  25382. #ifdef DEBUG_AUTOMATA
  25383. xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
  25384. pielem->localName);
  25385. #endif
  25386. }
  25387. /*
  25388. * SPEC (2.4) "If the {content type} is element-only or mixed,
  25389. * then the sequence of the element information item's
  25390. * element information item [children], if any, taken in
  25391. * order, is `valid` with respect to the {content type}'s
  25392. * particle, as defined in Element Sequence Locally Valid
  25393. * (Particle) ($3.9.4)."
  25394. */
  25395. ret = xmlRegExecPushString2(regexCtxt,
  25396. vctxt->inode->localName,
  25397. vctxt->inode->nsName,
  25398. vctxt->inode);
  25399. #ifdef DEBUG_AUTOMATA
  25400. if (ret < 0)
  25401. xmlGenericError(xmlGenericErrorContext,
  25402. "AUTOMATON push ERROR for '%s' on '%s'\n",
  25403. vctxt->inode->localName, pielem->localName);
  25404. else
  25405. xmlGenericError(xmlGenericErrorContext,
  25406. "AUTOMATON push OK for '%s' on '%s'\n",
  25407. vctxt->inode->localName, pielem->localName);
  25408. #endif
  25409. if (vctxt->err == XML_SCHEMAV_INTERNAL) {
  25410. VERROR_INT("xmlSchemaValidateChildElem",
  25411. "calling xmlRegExecPushString2()");
  25412. return (-1);
  25413. }
  25414. if (ret < 0) {
  25415. xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
  25416. &values[0], &terminal);
  25417. xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
  25418. XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
  25419. "This element is not expected",
  25420. nbval, nbneg, values);
  25421. ret = vctxt->err;
  25422. goto unexpected_elem;
  25423. } else
  25424. ret = 0;
  25425. }
  25426. break;
  25427. case XML_SCHEMA_CONTENT_SIMPLE:
  25428. case XML_SCHEMA_CONTENT_BASIC:
  25429. ACTIVATE_PARENT_ELEM
  25430. if (WXS_IS_COMPLEX(ptype)) {
  25431. /*
  25432. * SPEC (cvc-complex-type) (2.2)
  25433. * "If the {content type} is a simple type definition, then
  25434. * the element information item has no element information
  25435. * item [children], ..."
  25436. */
  25437. ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
  25438. VERROR(ret, NULL, "Element content is not allowed, "
  25439. "because the content type is a simple type definition");
  25440. } else {
  25441. /*
  25442. * SPEC (cvc-type) (3.1.2) "The element information item must
  25443. * have no element information item [children]."
  25444. */
  25445. ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
  25446. VERROR(ret, NULL, "Element content is not allowed, "
  25447. "because the type definition is simple");
  25448. }
  25449. ACTIVATE_ELEM
  25450. ret = vctxt->err;
  25451. goto unexpected_elem;
  25452. break;
  25453. default:
  25454. break;
  25455. }
  25456. return (ret);
  25457. unexpected_elem:
  25458. /*
  25459. * Pop this element and set the skipDepth to skip
  25460. * all further content of the parent element.
  25461. */
  25462. vctxt->skipDepth = vctxt->depth;
  25463. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
  25464. pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
  25465. return (ret);
  25466. }
  25467. #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
  25468. #define XML_SCHEMA_PUSH_TEXT_CREATED 2
  25469. #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
  25470. static int
  25471. xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
  25472. int nodeType, const xmlChar *value, int len,
  25473. int mode, int *consumed)
  25474. {
  25475. /*
  25476. * Unfortunately we have to duplicate the text sometimes.
  25477. * OPTIMIZE: Maybe we could skip it, if:
  25478. * 1. content type is simple
  25479. * 2. whitespace is "collapse"
  25480. * 3. it consists of whitespace only
  25481. *
  25482. * Process character content.
  25483. */
  25484. if (consumed != NULL)
  25485. *consumed = 0;
  25486. if (INODE_NILLED(vctxt->inode)) {
  25487. /*
  25488. * SPEC cvc-elt (3.3.4 - 3.2.1)
  25489. * "The element information item must have no character or
  25490. * element information item [children]."
  25491. */
  25492. VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
  25493. "Neither character nor element content is allowed "
  25494. "because the element is 'nilled'");
  25495. return (vctxt->err);
  25496. }
  25497. /*
  25498. * SPEC (2.1) "If the {content type} is empty, then the
  25499. * element information item has no character or element
  25500. * information item [children]."
  25501. */
  25502. if (vctxt->inode->typeDef->contentType ==
  25503. XML_SCHEMA_CONTENT_EMPTY) {
  25504. VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
  25505. "Character content is not allowed, "
  25506. "because the content type is empty");
  25507. return (vctxt->err);
  25508. }
  25509. if (vctxt->inode->typeDef->contentType ==
  25510. XML_SCHEMA_CONTENT_ELEMENTS) {
  25511. if ((nodeType != XML_TEXT_NODE) ||
  25512. (! xmlSchemaIsBlank((xmlChar *) value, len))) {
  25513. /*
  25514. * SPEC cvc-complex-type (2.3)
  25515. * "If the {content type} is element-only, then the
  25516. * element information item has no character information
  25517. * item [children] other than those whose [character
  25518. * code] is defined as a white space in [XML 1.0 (Second
  25519. * Edition)]."
  25520. */
  25521. VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
  25522. "Character content other than whitespace is not allowed "
  25523. "because the content type is 'element-only'");
  25524. return (vctxt->err);
  25525. }
  25526. return (0);
  25527. }
  25528. if ((value == NULL) || (value[0] == 0))
  25529. return (0);
  25530. /*
  25531. * Save the value.
  25532. * NOTE that even if the content type is *mixed*, we need the
  25533. * *initial value* for default/fixed value constraints.
  25534. */
  25535. if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  25536. ((vctxt->inode->decl == NULL) ||
  25537. (vctxt->inode->decl->value == NULL)))
  25538. return (0);
  25539. if (vctxt->inode->value == NULL) {
  25540. /*
  25541. * Set the value.
  25542. */
  25543. switch (mode) {
  25544. case XML_SCHEMA_PUSH_TEXT_PERSIST:
  25545. /*
  25546. * When working on a tree.
  25547. */
  25548. vctxt->inode->value = value;
  25549. break;
  25550. case XML_SCHEMA_PUSH_TEXT_CREATED:
  25551. /*
  25552. * When working with the reader.
  25553. * The value will be freed by the element info.
  25554. */
  25555. vctxt->inode->value = value;
  25556. if (consumed != NULL)
  25557. *consumed = 1;
  25558. vctxt->inode->flags |=
  25559. XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25560. break;
  25561. case XML_SCHEMA_PUSH_TEXT_VOLATILE:
  25562. /*
  25563. * When working with SAX.
  25564. * The value will be freed by the element info.
  25565. */
  25566. if (len != -1)
  25567. vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
  25568. else
  25569. vctxt->inode->value = BAD_CAST xmlStrdup(value);
  25570. vctxt->inode->flags |=
  25571. XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25572. break;
  25573. default:
  25574. break;
  25575. }
  25576. } else {
  25577. if (len < 0)
  25578. len = xmlStrlen(value);
  25579. /*
  25580. * Concat the value.
  25581. */
  25582. if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  25583. vctxt->inode->value = BAD_CAST xmlStrncat(
  25584. (xmlChar *) vctxt->inode->value, value, len);
  25585. } else {
  25586. vctxt->inode->value =
  25587. BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
  25588. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25589. }
  25590. }
  25591. return (0);
  25592. }
  25593. static int
  25594. xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
  25595. {
  25596. int ret = 0;
  25597. if ((vctxt->skipDepth != -1) &&
  25598. (vctxt->depth >= vctxt->skipDepth)) {
  25599. VERROR_INT("xmlSchemaValidateElem",
  25600. "in skip-state");
  25601. goto internal_error;
  25602. }
  25603. if (vctxt->xsiAssemble) {
  25604. /*
  25605. * We will stop validation if there was an error during
  25606. * dynamic schema construction.
  25607. * Note that we simply set @skipDepth to 0, this could
  25608. * mean that a streaming document via SAX would be
  25609. * still read to the end but it won't be validated any more.
  25610. * TODO: If we are sure how to stop the validation at once
  25611. * for all input scenarios, then this should be changed to
  25612. * instantly stop the validation.
  25613. */
  25614. ret = xmlSchemaAssembleByXSI(vctxt);
  25615. if (ret != 0) {
  25616. if (ret == -1)
  25617. goto internal_error;
  25618. vctxt->skipDepth = 0;
  25619. return(ret);
  25620. }
  25621. /*
  25622. * Augment the IDC definitions for the main schema and all imported ones
  25623. * NOTE: main schema is the first in the imported list
  25624. */
  25625. xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
  25626. vctxt);
  25627. }
  25628. if (vctxt->depth > 0) {
  25629. /*
  25630. * Validate this element against the content model
  25631. * of the parent.
  25632. */
  25633. ret = xmlSchemaValidateChildElem(vctxt);
  25634. if (ret != 0) {
  25635. if (ret < 0) {
  25636. VERROR_INT("xmlSchemaValidateElem",
  25637. "calling xmlSchemaStreamValidateChildElement()");
  25638. goto internal_error;
  25639. }
  25640. goto exit;
  25641. }
  25642. if (vctxt->depth == vctxt->skipDepth)
  25643. goto exit;
  25644. if ((vctxt->inode->decl == NULL) &&
  25645. (vctxt->inode->typeDef == NULL)) {
  25646. VERROR_INT("xmlSchemaValidateElem",
  25647. "the child element was valid but neither the "
  25648. "declaration nor the type was set");
  25649. goto internal_error;
  25650. }
  25651. } else {
  25652. /*
  25653. * Get the declaration of the validation root.
  25654. */
  25655. vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
  25656. vctxt->inode->localName,
  25657. vctxt->inode->nsName);
  25658. if (vctxt->inode->decl == NULL) {
  25659. ret = XML_SCHEMAV_CVC_ELT_1;
  25660. VERROR(ret, NULL,
  25661. "No matching global declaration available "
  25662. "for the validation root");
  25663. goto exit;
  25664. }
  25665. }
  25666. if (vctxt->inode->decl == NULL)
  25667. goto type_validation;
  25668. if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
  25669. int skip;
  25670. /*
  25671. * Wildcards.
  25672. */
  25673. ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
  25674. if (ret != 0) {
  25675. if (ret < 0) {
  25676. VERROR_INT("xmlSchemaValidateElem",
  25677. "calling xmlSchemaValidateElemWildcard()");
  25678. goto internal_error;
  25679. }
  25680. goto exit;
  25681. }
  25682. if (skip) {
  25683. vctxt->skipDepth = vctxt->depth;
  25684. goto exit;
  25685. }
  25686. /*
  25687. * The declaration might be set by the wildcard validation,
  25688. * when the processContents is "lax" or "strict".
  25689. */
  25690. if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
  25691. /*
  25692. * Clear the "decl" field to not confuse further processing.
  25693. */
  25694. vctxt->inode->decl = NULL;
  25695. goto type_validation;
  25696. }
  25697. }
  25698. /*
  25699. * Validate against the declaration.
  25700. */
  25701. ret = xmlSchemaValidateElemDecl(vctxt);
  25702. if (ret != 0) {
  25703. if (ret < 0) {
  25704. VERROR_INT("xmlSchemaValidateElem",
  25705. "calling xmlSchemaValidateElemDecl()");
  25706. goto internal_error;
  25707. }
  25708. goto exit;
  25709. }
  25710. /*
  25711. * Validate against the type definition.
  25712. */
  25713. type_validation:
  25714. if (vctxt->inode->typeDef == NULL) {
  25715. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
  25716. ret = XML_SCHEMAV_CVC_TYPE_1;
  25717. VERROR(ret, NULL,
  25718. "The type definition is absent");
  25719. goto exit;
  25720. }
  25721. if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
  25722. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
  25723. ret = XML_SCHEMAV_CVC_TYPE_2;
  25724. VERROR(ret, NULL,
  25725. "The type definition is abstract");
  25726. goto exit;
  25727. }
  25728. /*
  25729. * Evaluate IDCs. Do it here, since new IDC matchers are registered
  25730. * during validation against the declaration. This must be done
  25731. * _before_ attribute validation.
  25732. */
  25733. if (vctxt->xpathStates != NULL) {
  25734. ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
  25735. vctxt->inode->appliedXPath = 1;
  25736. if (ret == -1) {
  25737. VERROR_INT("xmlSchemaValidateElem",
  25738. "calling xmlSchemaXPathEvaluate()");
  25739. goto internal_error;
  25740. }
  25741. }
  25742. /*
  25743. * Validate attributes.
  25744. */
  25745. if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
  25746. if ((vctxt->nbAttrInfos != 0) ||
  25747. (vctxt->inode->typeDef->attrUses != NULL)) {
  25748. ret = xmlSchemaVAttributesComplex(vctxt);
  25749. }
  25750. } else if (vctxt->nbAttrInfos != 0) {
  25751. ret = xmlSchemaVAttributesSimple(vctxt);
  25752. }
  25753. /*
  25754. * Clear registered attributes.
  25755. */
  25756. if (vctxt->nbAttrInfos != 0)
  25757. xmlSchemaClearAttrInfos(vctxt);
  25758. if (ret == -1) {
  25759. VERROR_INT("xmlSchemaValidateElem",
  25760. "calling attributes validation");
  25761. goto internal_error;
  25762. }
  25763. /*
  25764. * Don't return an error if attributes are invalid on purpose.
  25765. */
  25766. ret = 0;
  25767. exit:
  25768. if (ret != 0)
  25769. vctxt->skipDepth = vctxt->depth;
  25770. return (ret);
  25771. internal_error:
  25772. return (-1);
  25773. }
  25774. #ifdef XML_SCHEMA_READER_ENABLED
  25775. static int
  25776. xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
  25777. {
  25778. const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
  25779. int depth, nodeType, ret = 0, consumed;
  25780. xmlSchemaNodeInfoPtr ielem;
  25781. vctxt->depth = -1;
  25782. ret = xmlTextReaderRead(vctxt->reader);
  25783. /*
  25784. * Move to the document element.
  25785. */
  25786. while (ret == 1) {
  25787. nodeType = xmlTextReaderNodeType(vctxt->reader);
  25788. if (nodeType == XML_ELEMENT_NODE)
  25789. goto root_found;
  25790. ret = xmlTextReaderRead(vctxt->reader);
  25791. }
  25792. goto exit;
  25793. root_found:
  25794. do {
  25795. depth = xmlTextReaderDepth(vctxt->reader);
  25796. nodeType = xmlTextReaderNodeType(vctxt->reader);
  25797. if (nodeType == XML_ELEMENT_NODE) {
  25798. vctxt->depth++;
  25799. if (xmlSchemaValidatorPushElem(vctxt) == -1) {
  25800. VERROR_INT("xmlSchemaVReaderWalk",
  25801. "calling xmlSchemaValidatorPushElem()");
  25802. goto internal_error;
  25803. }
  25804. ielem = vctxt->inode;
  25805. ielem->localName = xmlTextReaderLocalName(vctxt->reader);
  25806. ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
  25807. ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
  25808. /*
  25809. * Is the element empty?
  25810. */
  25811. ret = xmlTextReaderIsEmptyElement(vctxt->reader);
  25812. if (ret == -1) {
  25813. VERROR_INT("xmlSchemaVReaderWalk",
  25814. "calling xmlTextReaderIsEmptyElement()");
  25815. goto internal_error;
  25816. }
  25817. if (ret) {
  25818. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  25819. }
  25820. /*
  25821. * Register attributes.
  25822. */
  25823. vctxt->nbAttrInfos = 0;
  25824. ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
  25825. if (ret == -1) {
  25826. VERROR_INT("xmlSchemaVReaderWalk",
  25827. "calling xmlTextReaderMoveToFirstAttribute()");
  25828. goto internal_error;
  25829. }
  25830. if (ret == 1) {
  25831. do {
  25832. /*
  25833. * VAL TODO: How do we know that the reader works on a
  25834. * node tree, to be able to pass a node here?
  25835. */
  25836. if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
  25837. (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
  25838. xmlTextReaderNamespaceUri(vctxt->reader), 1,
  25839. xmlTextReaderValue(vctxt->reader), 1) == -1) {
  25840. VERROR_INT("xmlSchemaVReaderWalk",
  25841. "calling xmlSchemaValidatorPushAttribute()");
  25842. goto internal_error;
  25843. }
  25844. ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
  25845. if (ret == -1) {
  25846. VERROR_INT("xmlSchemaVReaderWalk",
  25847. "calling xmlTextReaderMoveToFirstAttribute()");
  25848. goto internal_error;
  25849. }
  25850. } while (ret == 1);
  25851. /*
  25852. * Back to element position.
  25853. */
  25854. ret = xmlTextReaderMoveToElement(vctxt->reader);
  25855. if (ret == -1) {
  25856. VERROR_INT("xmlSchemaVReaderWalk",
  25857. "calling xmlTextReaderMoveToElement()");
  25858. goto internal_error;
  25859. }
  25860. }
  25861. /*
  25862. * Validate the element.
  25863. */
  25864. ret= xmlSchemaValidateElem(vctxt);
  25865. if (ret != 0) {
  25866. if (ret == -1) {
  25867. VERROR_INT("xmlSchemaVReaderWalk",
  25868. "calling xmlSchemaValidateElem()");
  25869. goto internal_error;
  25870. }
  25871. goto exit;
  25872. }
  25873. if (vctxt->depth == vctxt->skipDepth) {
  25874. int curDepth;
  25875. /*
  25876. * Skip all content.
  25877. */
  25878. if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
  25879. ret = xmlTextReaderRead(vctxt->reader);
  25880. curDepth = xmlTextReaderDepth(vctxt->reader);
  25881. while ((ret == 1) && (curDepth != depth)) {
  25882. ret = xmlTextReaderRead(vctxt->reader);
  25883. curDepth = xmlTextReaderDepth(vctxt->reader);
  25884. }
  25885. if (ret < 0) {
  25886. /*
  25887. * VAL TODO: A reader error occurred; what to do here?
  25888. */
  25889. ret = 1;
  25890. goto exit;
  25891. }
  25892. }
  25893. goto leave_elem;
  25894. }
  25895. /*
  25896. * READER VAL TODO: Is an END_ELEM really never called
  25897. * if the elem is empty?
  25898. */
  25899. if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25900. goto leave_elem;
  25901. } else if (nodeType == END_ELEM) {
  25902. /*
  25903. * Process END of element.
  25904. */
  25905. leave_elem:
  25906. ret = xmlSchemaValidatorPopElem(vctxt);
  25907. if (ret != 0) {
  25908. if (ret < 0) {
  25909. VERROR_INT("xmlSchemaVReaderWalk",
  25910. "calling xmlSchemaValidatorPopElem()");
  25911. goto internal_error;
  25912. }
  25913. goto exit;
  25914. }
  25915. if (vctxt->depth >= 0)
  25916. ielem = vctxt->inode;
  25917. else
  25918. ielem = NULL;
  25919. } else if ((nodeType == XML_TEXT_NODE) ||
  25920. (nodeType == XML_CDATA_SECTION_NODE) ||
  25921. (nodeType == WHTSP) ||
  25922. (nodeType == SIGN_WHTSP)) {
  25923. /*
  25924. * Process character content.
  25925. */
  25926. xmlChar *value;
  25927. if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
  25928. nodeType = XML_TEXT_NODE;
  25929. value = xmlTextReaderValue(vctxt->reader);
  25930. ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
  25931. -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
  25932. if (! consumed)
  25933. xmlFree(value);
  25934. if (ret == -1) {
  25935. VERROR_INT("xmlSchemaVReaderWalk",
  25936. "calling xmlSchemaVPushText()");
  25937. goto internal_error;
  25938. }
  25939. } else if ((nodeType == XML_ENTITY_NODE) ||
  25940. (nodeType == XML_ENTITY_REF_NODE)) {
  25941. /*
  25942. * VAL TODO: What to do with entities?
  25943. */
  25944. TODO
  25945. }
  25946. /*
  25947. * Read next node.
  25948. */
  25949. ret = xmlTextReaderRead(vctxt->reader);
  25950. } while (ret == 1);
  25951. exit:
  25952. return (ret);
  25953. internal_error:
  25954. return (-1);
  25955. }
  25956. #endif
  25957. /************************************************************************
  25958. * *
  25959. * SAX validation handlers *
  25960. * *
  25961. ************************************************************************/
  25962. /*
  25963. * Process text content.
  25964. */
  25965. static void
  25966. xmlSchemaSAXHandleText(void *ctx,
  25967. const xmlChar * ch,
  25968. int len)
  25969. {
  25970. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25971. if (vctxt->depth < 0)
  25972. return;
  25973. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25974. return;
  25975. if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25976. vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25977. if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
  25978. XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
  25979. VERROR_INT("xmlSchemaSAXHandleCDataSection",
  25980. "calling xmlSchemaVPushText()");
  25981. vctxt->err = -1;
  25982. xmlStopParser(vctxt->parserCtxt);
  25983. }
  25984. }
  25985. /*
  25986. * Process CDATA content.
  25987. */
  25988. static void
  25989. xmlSchemaSAXHandleCDataSection(void *ctx,
  25990. const xmlChar * ch,
  25991. int len)
  25992. {
  25993. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25994. if (vctxt->depth < 0)
  25995. return;
  25996. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25997. return;
  25998. if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25999. vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  26000. if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
  26001. XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
  26002. VERROR_INT("xmlSchemaSAXHandleCDataSection",
  26003. "calling xmlSchemaVPushText()");
  26004. vctxt->err = -1;
  26005. xmlStopParser(vctxt->parserCtxt);
  26006. }
  26007. }
  26008. static void
  26009. xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
  26010. const xmlChar * name ATTRIBUTE_UNUSED)
  26011. {
  26012. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  26013. if (vctxt->depth < 0)
  26014. return;
  26015. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  26016. return;
  26017. /* SAX VAL TODO: What to do here? */
  26018. TODO
  26019. }
  26020. static void
  26021. xmlSchemaSAXHandleStartElementNs(void *ctx,
  26022. const xmlChar * localname,
  26023. const xmlChar * prefix ATTRIBUTE_UNUSED,
  26024. const xmlChar * URI,
  26025. int nb_namespaces,
  26026. const xmlChar ** namespaces,
  26027. int nb_attributes,
  26028. int nb_defaulted ATTRIBUTE_UNUSED,
  26029. const xmlChar ** attributes)
  26030. {
  26031. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  26032. int ret;
  26033. xmlSchemaNodeInfoPtr ielem;
  26034. int i, j;
  26035. /*
  26036. * SAX VAL TODO: What to do with nb_defaulted?
  26037. */
  26038. /*
  26039. * Skip elements if inside a "skip" wildcard or invalid.
  26040. */
  26041. vctxt->depth++;
  26042. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  26043. return;
  26044. /*
  26045. * Push the element.
  26046. */
  26047. if (xmlSchemaValidatorPushElem(vctxt) == -1) {
  26048. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  26049. "calling xmlSchemaValidatorPushElem()");
  26050. goto internal_error;
  26051. }
  26052. ielem = vctxt->inode;
  26053. /*
  26054. * TODO: Is this OK?
  26055. */
  26056. ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
  26057. ielem->localName = localname;
  26058. ielem->nsName = URI;
  26059. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  26060. /*
  26061. * Register namespaces on the elem info.
  26062. */
  26063. if (nb_namespaces != 0) {
  26064. /*
  26065. * Although the parser builds its own namespace list,
  26066. * we have no access to it, so we'll use an own one.
  26067. */
  26068. for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
  26069. /*
  26070. * Store prefix and namespace name.
  26071. */
  26072. if (ielem->nsBindings == NULL) {
  26073. ielem->nsBindings =
  26074. (const xmlChar **) xmlMalloc(10 *
  26075. sizeof(const xmlChar *));
  26076. if (ielem->nsBindings == NULL) {
  26077. xmlSchemaVErrMemory(vctxt,
  26078. "allocating namespace bindings for SAX validation",
  26079. NULL);
  26080. goto internal_error;
  26081. }
  26082. ielem->nbNsBindings = 0;
  26083. ielem->sizeNsBindings = 5;
  26084. } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
  26085. ielem->sizeNsBindings *= 2;
  26086. ielem->nsBindings =
  26087. (const xmlChar **) xmlRealloc(
  26088. (void *) ielem->nsBindings,
  26089. ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
  26090. if (ielem->nsBindings == NULL) {
  26091. xmlSchemaVErrMemory(vctxt,
  26092. "re-allocating namespace bindings for SAX validation",
  26093. NULL);
  26094. goto internal_error;
  26095. }
  26096. }
  26097. ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
  26098. if (namespaces[j+1][0] == 0) {
  26099. /*
  26100. * Handle xmlns="".
  26101. */
  26102. ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
  26103. } else
  26104. ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
  26105. namespaces[j+1];
  26106. ielem->nbNsBindings++;
  26107. }
  26108. }
  26109. /*
  26110. * Register attributes.
  26111. * SAX VAL TODO: We are not adding namespace declaration
  26112. * attributes yet.
  26113. */
  26114. if (nb_attributes != 0) {
  26115. int valueLen, k, l;
  26116. xmlChar *value;
  26117. for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
  26118. /*
  26119. * Duplicate the value, changing any &#38; to a literal ampersand.
  26120. *
  26121. * libxml2 differs from normal SAX here in that it escapes all ampersands
  26122. * as &#38; instead of delivering the raw converted string. Changing the
  26123. * behavior at this point would break applications that use this API, so
  26124. * we are forced to work around it.
  26125. */
  26126. valueLen = attributes[j+4] - attributes[j+3];
  26127. value = xmlMallocAtomic(valueLen + 1);
  26128. if (value == NULL) {
  26129. xmlSchemaVErrMemory(vctxt,
  26130. "allocating string for decoded attribute",
  26131. NULL);
  26132. goto internal_error;
  26133. }
  26134. for (k = 0, l = 0; k < valueLen; l++) {
  26135. if (k < valueLen - 4 &&
  26136. attributes[j+3][k+0] == '&' &&
  26137. attributes[j+3][k+1] == '#' &&
  26138. attributes[j+3][k+2] == '3' &&
  26139. attributes[j+3][k+3] == '8' &&
  26140. attributes[j+3][k+4] == ';') {
  26141. value[l] = '&';
  26142. k += 5;
  26143. } else {
  26144. value[l] = attributes[j+3][k];
  26145. k++;
  26146. }
  26147. }
  26148. value[l] = '\0';
  26149. /*
  26150. * TODO: Set the node line.
  26151. */
  26152. ret = xmlSchemaValidatorPushAttribute(vctxt,
  26153. NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
  26154. value, 1);
  26155. if (ret == -1) {
  26156. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  26157. "calling xmlSchemaValidatorPushAttribute()");
  26158. goto internal_error;
  26159. }
  26160. }
  26161. }
  26162. /*
  26163. * Validate the element.
  26164. */
  26165. ret = xmlSchemaValidateElem(vctxt);
  26166. if (ret != 0) {
  26167. if (ret == -1) {
  26168. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  26169. "calling xmlSchemaValidateElem()");
  26170. goto internal_error;
  26171. }
  26172. goto exit;
  26173. }
  26174. exit:
  26175. return;
  26176. internal_error:
  26177. vctxt->err = -1;
  26178. xmlStopParser(vctxt->parserCtxt);
  26179. return;
  26180. }
  26181. static void
  26182. xmlSchemaSAXHandleEndElementNs(void *ctx,
  26183. const xmlChar * localname ATTRIBUTE_UNUSED,
  26184. const xmlChar * prefix ATTRIBUTE_UNUSED,
  26185. const xmlChar * URI ATTRIBUTE_UNUSED)
  26186. {
  26187. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  26188. int res;
  26189. /*
  26190. * Skip elements if inside a "skip" wildcard or if invalid.
  26191. */
  26192. if (vctxt->skipDepth != -1) {
  26193. if (vctxt->depth > vctxt->skipDepth) {
  26194. vctxt->depth--;
  26195. return;
  26196. } else
  26197. vctxt->skipDepth = -1;
  26198. }
  26199. /*
  26200. * SAX VAL TODO: Just a temporary check.
  26201. */
  26202. if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
  26203. (!xmlStrEqual(vctxt->inode->nsName, URI))) {
  26204. VERROR_INT("xmlSchemaSAXHandleEndElementNs",
  26205. "elem pop mismatch");
  26206. }
  26207. res = xmlSchemaValidatorPopElem(vctxt);
  26208. if (res != 0) {
  26209. if (res < 0) {
  26210. VERROR_INT("xmlSchemaSAXHandleEndElementNs",
  26211. "calling xmlSchemaValidatorPopElem()");
  26212. goto internal_error;
  26213. }
  26214. goto exit;
  26215. }
  26216. exit:
  26217. return;
  26218. internal_error:
  26219. vctxt->err = -1;
  26220. xmlStopParser(vctxt->parserCtxt);
  26221. return;
  26222. }
  26223. /************************************************************************
  26224. * *
  26225. * Validation interfaces *
  26226. * *
  26227. ************************************************************************/
  26228. /**
  26229. * xmlSchemaNewValidCtxt:
  26230. * @schema: a precompiled XML Schemas
  26231. *
  26232. * Create an XML Schemas validation context based on the given schema.
  26233. *
  26234. * Returns the validation context or NULL in case of error
  26235. */
  26236. xmlSchemaValidCtxtPtr
  26237. xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
  26238. {
  26239. xmlSchemaValidCtxtPtr ret;
  26240. ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
  26241. if (ret == NULL) {
  26242. xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
  26243. return (NULL);
  26244. }
  26245. memset(ret, 0, sizeof(xmlSchemaValidCtxt));
  26246. ret->type = XML_SCHEMA_CTXT_VALIDATOR;
  26247. ret->dict = xmlDictCreate();
  26248. ret->nodeQNames = xmlSchemaItemListCreate();
  26249. ret->schema = schema;
  26250. return (ret);
  26251. }
  26252. /**
  26253. * xmlSchemaValidateSetFilename:
  26254. * @vctxt: the schema validation context
  26255. * @filename: the file name
  26256. *
  26257. * Workaround to provide file error reporting information when this is
  26258. * not provided by current APIs
  26259. */
  26260. void
  26261. xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
  26262. if (vctxt == NULL)
  26263. return;
  26264. if (vctxt->filename != NULL)
  26265. xmlFree(vctxt->filename);
  26266. if (filename != NULL)
  26267. vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
  26268. else
  26269. vctxt->filename = NULL;
  26270. }
  26271. /**
  26272. * xmlSchemaClearValidCtxt:
  26273. * @vctxt: the schema validation context
  26274. *
  26275. * Free the resources associated to the schema validation context;
  26276. * leaves some fields alive intended for reuse of the context.
  26277. */
  26278. static void
  26279. xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
  26280. {
  26281. if (vctxt == NULL)
  26282. return;
  26283. /*
  26284. * TODO: Should we clear the flags?
  26285. * Might be problematic if one reuses the context
  26286. * and assumes that the options remain the same.
  26287. */
  26288. vctxt->flags = 0;
  26289. vctxt->validationRoot = NULL;
  26290. vctxt->doc = NULL;
  26291. #ifdef LIBXML_READER_ENABLED
  26292. vctxt->reader = NULL;
  26293. #endif
  26294. vctxt->hasKeyrefs = 0;
  26295. if (vctxt->value != NULL) {
  26296. xmlSchemaFreeValue(vctxt->value);
  26297. vctxt->value = NULL;
  26298. }
  26299. /*
  26300. * Augmented IDC information.
  26301. */
  26302. if (vctxt->aidcs != NULL) {
  26303. xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
  26304. do {
  26305. next = cur->next;
  26306. xmlFree(cur);
  26307. cur = next;
  26308. } while (cur != NULL);
  26309. vctxt->aidcs = NULL;
  26310. }
  26311. if (vctxt->idcMatcherCache != NULL) {
  26312. xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
  26313. while (matcher) {
  26314. tmp = matcher;
  26315. matcher = matcher->nextCached;
  26316. xmlSchemaIDCFreeMatcherList(tmp);
  26317. }
  26318. vctxt->idcMatcherCache = NULL;
  26319. }
  26320. if (vctxt->idcNodes != NULL) {
  26321. int i;
  26322. xmlSchemaPSVIIDCNodePtr item;
  26323. for (i = 0; i < vctxt->nbIdcNodes; i++) {
  26324. item = vctxt->idcNodes[i];
  26325. xmlFree(item->keys);
  26326. xmlFree(item);
  26327. }
  26328. xmlFree(vctxt->idcNodes);
  26329. vctxt->idcNodes = NULL;
  26330. vctxt->nbIdcNodes = 0;
  26331. vctxt->sizeIdcNodes = 0;
  26332. }
  26333. if (vctxt->idcKeys != NULL) {
  26334. int i;
  26335. for (i = 0; i < vctxt->nbIdcKeys; i++)
  26336. xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
  26337. xmlFree(vctxt->idcKeys);
  26338. vctxt->idcKeys = NULL;
  26339. vctxt->nbIdcKeys = 0;
  26340. vctxt->sizeIdcKeys = 0;
  26341. }
  26342. /*
  26343. * Note that we won't delete the XPath state pool here.
  26344. */
  26345. if (vctxt->xpathStates != NULL) {
  26346. xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
  26347. vctxt->xpathStates = NULL;
  26348. }
  26349. /*
  26350. * Attribute info.
  26351. */
  26352. if (vctxt->nbAttrInfos != 0) {
  26353. xmlSchemaClearAttrInfos(vctxt);
  26354. }
  26355. /*
  26356. * Element info.
  26357. */
  26358. if (vctxt->elemInfos != NULL) {
  26359. int i;
  26360. xmlSchemaNodeInfoPtr ei;
  26361. for (i = 0; i < vctxt->sizeElemInfos; i++) {
  26362. ei = vctxt->elemInfos[i];
  26363. if (ei == NULL)
  26364. break;
  26365. xmlSchemaClearElemInfo(vctxt, ei);
  26366. }
  26367. }
  26368. xmlSchemaItemListClear(vctxt->nodeQNames);
  26369. /* Recreate the dict. */
  26370. xmlDictFree(vctxt->dict);
  26371. /*
  26372. * TODO: Is is save to recreate it? Do we have a scenario
  26373. * where the user provides the dict?
  26374. */
  26375. vctxt->dict = xmlDictCreate();
  26376. if (vctxt->filename != NULL) {
  26377. xmlFree(vctxt->filename);
  26378. vctxt->filename = NULL;
  26379. }
  26380. }
  26381. /**
  26382. * xmlSchemaFreeValidCtxt:
  26383. * @ctxt: the schema validation context
  26384. *
  26385. * Free the resources associated to the schema validation context
  26386. */
  26387. void
  26388. xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
  26389. {
  26390. if (ctxt == NULL)
  26391. return;
  26392. if (ctxt->value != NULL)
  26393. xmlSchemaFreeValue(ctxt->value);
  26394. if (ctxt->pctxt != NULL)
  26395. xmlSchemaFreeParserCtxt(ctxt->pctxt);
  26396. if (ctxt->idcNodes != NULL) {
  26397. int i;
  26398. xmlSchemaPSVIIDCNodePtr item;
  26399. for (i = 0; i < ctxt->nbIdcNodes; i++) {
  26400. item = ctxt->idcNodes[i];
  26401. xmlFree(item->keys);
  26402. xmlFree(item);
  26403. }
  26404. xmlFree(ctxt->idcNodes);
  26405. }
  26406. if (ctxt->idcKeys != NULL) {
  26407. int i;
  26408. for (i = 0; i < ctxt->nbIdcKeys; i++)
  26409. xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
  26410. xmlFree(ctxt->idcKeys);
  26411. }
  26412. if (ctxt->xpathStates != NULL) {
  26413. xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
  26414. ctxt->xpathStates = NULL;
  26415. }
  26416. if (ctxt->xpathStatePool != NULL) {
  26417. xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
  26418. ctxt->xpathStatePool = NULL;
  26419. }
  26420. /*
  26421. * Augmented IDC information.
  26422. */
  26423. if (ctxt->aidcs != NULL) {
  26424. xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
  26425. do {
  26426. next = cur->next;
  26427. xmlFree(cur);
  26428. cur = next;
  26429. } while (cur != NULL);
  26430. }
  26431. if (ctxt->attrInfos != NULL) {
  26432. int i;
  26433. xmlSchemaAttrInfoPtr attr;
  26434. /* Just a paranoid call to the cleanup. */
  26435. if (ctxt->nbAttrInfos != 0)
  26436. xmlSchemaClearAttrInfos(ctxt);
  26437. for (i = 0; i < ctxt->sizeAttrInfos; i++) {
  26438. attr = ctxt->attrInfos[i];
  26439. xmlFree(attr);
  26440. }
  26441. xmlFree(ctxt->attrInfos);
  26442. }
  26443. if (ctxt->elemInfos != NULL) {
  26444. int i;
  26445. xmlSchemaNodeInfoPtr ei;
  26446. for (i = 0; i < ctxt->sizeElemInfos; i++) {
  26447. ei = ctxt->elemInfos[i];
  26448. if (ei == NULL)
  26449. break;
  26450. xmlSchemaClearElemInfo(ctxt, ei);
  26451. xmlFree(ei);
  26452. }
  26453. xmlFree(ctxt->elemInfos);
  26454. }
  26455. if (ctxt->nodeQNames != NULL)
  26456. xmlSchemaItemListFree(ctxt->nodeQNames);
  26457. if (ctxt->dict != NULL)
  26458. xmlDictFree(ctxt->dict);
  26459. if (ctxt->filename != NULL)
  26460. xmlFree(ctxt->filename);
  26461. xmlFree(ctxt);
  26462. }
  26463. /**
  26464. * xmlSchemaIsValid:
  26465. * @ctxt: the schema validation context
  26466. *
  26467. * Check if any error was detected during validation.
  26468. *
  26469. * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
  26470. * of internal error.
  26471. */
  26472. int
  26473. xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
  26474. {
  26475. if (ctxt == NULL)
  26476. return(-1);
  26477. return(ctxt->err == 0);
  26478. }
  26479. /**
  26480. * xmlSchemaSetValidErrors:
  26481. * @ctxt: a schema validation context
  26482. * @err: the error function
  26483. * @warn: the warning function
  26484. * @ctx: the functions context
  26485. *
  26486. * Set the error and warning callback information
  26487. */
  26488. void
  26489. xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
  26490. xmlSchemaValidityErrorFunc err,
  26491. xmlSchemaValidityWarningFunc warn, void *ctx)
  26492. {
  26493. if (ctxt == NULL)
  26494. return;
  26495. ctxt->error = err;
  26496. ctxt->warning = warn;
  26497. ctxt->errCtxt = ctx;
  26498. if (ctxt->pctxt != NULL)
  26499. xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
  26500. }
  26501. /**
  26502. * xmlSchemaSetValidStructuredErrors:
  26503. * @ctxt: a schema validation context
  26504. * @serror: the structured error function
  26505. * @ctx: the functions context
  26506. *
  26507. * Set the structured error callback
  26508. */
  26509. void
  26510. xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
  26511. xmlStructuredErrorFunc serror, void *ctx)
  26512. {
  26513. if (ctxt == NULL)
  26514. return;
  26515. ctxt->serror = serror;
  26516. ctxt->error = NULL;
  26517. ctxt->warning = NULL;
  26518. ctxt->errCtxt = ctx;
  26519. if (ctxt->pctxt != NULL)
  26520. xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
  26521. }
  26522. /**
  26523. * xmlSchemaGetValidErrors:
  26524. * @ctxt: a XML-Schema validation context
  26525. * @err: the error function result
  26526. * @warn: the warning function result
  26527. * @ctx: the functions context result
  26528. *
  26529. * Get the error and warning callback information
  26530. *
  26531. * Returns -1 in case of error and 0 otherwise
  26532. */
  26533. int
  26534. xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
  26535. xmlSchemaValidityErrorFunc * err,
  26536. xmlSchemaValidityWarningFunc * warn, void **ctx)
  26537. {
  26538. if (ctxt == NULL)
  26539. return (-1);
  26540. if (err != NULL)
  26541. *err = ctxt->error;
  26542. if (warn != NULL)
  26543. *warn = ctxt->warning;
  26544. if (ctx != NULL)
  26545. *ctx = ctxt->errCtxt;
  26546. return (0);
  26547. }
  26548. /**
  26549. * xmlSchemaSetValidOptions:
  26550. * @ctxt: a schema validation context
  26551. * @options: a combination of xmlSchemaValidOption
  26552. *
  26553. * Sets the options to be used during the validation.
  26554. *
  26555. * Returns 0 in case of success, -1 in case of an
  26556. * API error.
  26557. */
  26558. int
  26559. xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
  26560. int options)
  26561. {
  26562. int i;
  26563. if (ctxt == NULL)
  26564. return (-1);
  26565. /*
  26566. * WARNING: Change the start value if adding to the
  26567. * xmlSchemaValidOption.
  26568. * TODO: Is there an other, more easy to maintain,
  26569. * way?
  26570. */
  26571. for (i = 1; i < (int) sizeof(int) * 8; i++) {
  26572. if (options & 1<<i)
  26573. return (-1);
  26574. }
  26575. ctxt->options = options;
  26576. return (0);
  26577. }
  26578. /**
  26579. * xmlSchemaValidCtxtGetOptions:
  26580. * @ctxt: a schema validation context
  26581. *
  26582. * Get the validation context options.
  26583. *
  26584. * Returns the option combination or -1 on error.
  26585. */
  26586. int
  26587. xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
  26588. {
  26589. if (ctxt == NULL)
  26590. return (-1);
  26591. else
  26592. return (ctxt->options);
  26593. }
  26594. static int
  26595. xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
  26596. {
  26597. xmlAttrPtr attr;
  26598. int ret = 0;
  26599. xmlSchemaNodeInfoPtr ielem = NULL;
  26600. xmlNodePtr node, valRoot;
  26601. const xmlChar *nsName;
  26602. /* DOC VAL TODO: Move this to the start function. */
  26603. if (vctxt->validationRoot != NULL)
  26604. valRoot = vctxt->validationRoot;
  26605. else
  26606. valRoot = xmlDocGetRootElement(vctxt->doc);
  26607. if (valRoot == NULL) {
  26608. /* VAL TODO: Error code? */
  26609. VERROR(1, NULL, "The document has no document element");
  26610. return (1);
  26611. }
  26612. vctxt->depth = -1;
  26613. vctxt->validationRoot = valRoot;
  26614. node = valRoot;
  26615. while (node != NULL) {
  26616. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  26617. goto next_sibling;
  26618. if (node->type == XML_ELEMENT_NODE) {
  26619. /*
  26620. * Init the node-info.
  26621. */
  26622. vctxt->depth++;
  26623. if (xmlSchemaValidatorPushElem(vctxt) == -1)
  26624. goto internal_error;
  26625. ielem = vctxt->inode;
  26626. ielem->node = node;
  26627. ielem->nodeLine = node->line;
  26628. ielem->localName = node->name;
  26629. if (node->ns != NULL)
  26630. ielem->nsName = node->ns->href;
  26631. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  26632. /*
  26633. * Register attributes.
  26634. * DOC VAL TODO: We do not register namespace declaration
  26635. * attributes yet.
  26636. */
  26637. vctxt->nbAttrInfos = 0;
  26638. if (node->properties != NULL) {
  26639. attr = node->properties;
  26640. do {
  26641. if (attr->ns != NULL)
  26642. nsName = attr->ns->href;
  26643. else
  26644. nsName = NULL;
  26645. ret = xmlSchemaValidatorPushAttribute(vctxt,
  26646. (xmlNodePtr) attr,
  26647. /*
  26648. * Note that we give it the line number of the
  26649. * parent element.
  26650. */
  26651. ielem->nodeLine,
  26652. attr->name, nsName, 0,
  26653. xmlNodeListGetString(attr->doc, attr->children, 1), 1);
  26654. if (ret == -1) {
  26655. VERROR_INT("xmlSchemaDocWalk",
  26656. "calling xmlSchemaValidatorPushAttribute()");
  26657. goto internal_error;
  26658. }
  26659. attr = attr->next;
  26660. } while (attr);
  26661. }
  26662. /*
  26663. * Validate the element.
  26664. */
  26665. ret = xmlSchemaValidateElem(vctxt);
  26666. if (ret != 0) {
  26667. if (ret == -1) {
  26668. VERROR_INT("xmlSchemaDocWalk",
  26669. "calling xmlSchemaValidateElem()");
  26670. goto internal_error;
  26671. }
  26672. /*
  26673. * Don't stop validation; just skip the content
  26674. * of this element.
  26675. */
  26676. goto leave_node;
  26677. }
  26678. if ((vctxt->skipDepth != -1) &&
  26679. (vctxt->depth >= vctxt->skipDepth))
  26680. goto leave_node;
  26681. } else if ((node->type == XML_TEXT_NODE) ||
  26682. (node->type == XML_CDATA_SECTION_NODE)) {
  26683. /*
  26684. * Process character content.
  26685. */
  26686. if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
  26687. ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  26688. ret = xmlSchemaVPushText(vctxt, node->type, node->content,
  26689. -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
  26690. if (ret < 0) {
  26691. VERROR_INT("xmlSchemaVDocWalk",
  26692. "calling xmlSchemaVPushText()");
  26693. goto internal_error;
  26694. }
  26695. /*
  26696. * DOC VAL TODO: Should we skip further validation of the
  26697. * element content here?
  26698. */
  26699. } else if ((node->type == XML_ENTITY_NODE) ||
  26700. (node->type == XML_ENTITY_REF_NODE)) {
  26701. /*
  26702. * DOC VAL TODO: What to do with entities?
  26703. */
  26704. VERROR_INT("xmlSchemaVDocWalk",
  26705. "there is at least one entity reference in the node-tree "
  26706. "currently being validated. Processing of entities with "
  26707. "this XML Schema processor is not supported (yet). Please "
  26708. "substitute entities before validation.");
  26709. goto internal_error;
  26710. } else {
  26711. goto leave_node;
  26712. /*
  26713. * DOC VAL TODO: XInclude nodes, etc.
  26714. */
  26715. }
  26716. /*
  26717. * Walk the doc.
  26718. */
  26719. if (node->children != NULL) {
  26720. node = node->children;
  26721. continue;
  26722. }
  26723. leave_node:
  26724. if (node->type == XML_ELEMENT_NODE) {
  26725. /*
  26726. * Leaving the scope of an element.
  26727. */
  26728. if (node != vctxt->inode->node) {
  26729. VERROR_INT("xmlSchemaVDocWalk",
  26730. "element position mismatch");
  26731. goto internal_error;
  26732. }
  26733. ret = xmlSchemaValidatorPopElem(vctxt);
  26734. if (ret != 0) {
  26735. if (ret < 0) {
  26736. VERROR_INT("xmlSchemaVDocWalk",
  26737. "calling xmlSchemaValidatorPopElem()");
  26738. goto internal_error;
  26739. }
  26740. }
  26741. if (node == valRoot)
  26742. goto exit;
  26743. }
  26744. next_sibling:
  26745. if (node->next != NULL)
  26746. node = node->next;
  26747. else {
  26748. node = node->parent;
  26749. goto leave_node;
  26750. }
  26751. }
  26752. exit:
  26753. return (ret);
  26754. internal_error:
  26755. return (-1);
  26756. }
  26757. static int
  26758. xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
  26759. /*
  26760. * Some initialization.
  26761. */
  26762. vctxt->err = 0;
  26763. vctxt->nberrors = 0;
  26764. vctxt->depth = -1;
  26765. vctxt->skipDepth = -1;
  26766. vctxt->hasKeyrefs = 0;
  26767. #ifdef ENABLE_IDC_NODE_TABLES_TEST
  26768. vctxt->createIDCNodeTables = 1;
  26769. #else
  26770. vctxt->createIDCNodeTables = 0;
  26771. #endif
  26772. /*
  26773. * Create a schema + parser if necessary.
  26774. */
  26775. if (vctxt->schema == NULL) {
  26776. xmlSchemaParserCtxtPtr pctxt;
  26777. vctxt->xsiAssemble = 1;
  26778. /*
  26779. * If not schema was given then we will create a schema
  26780. * dynamically using XSI schema locations.
  26781. *
  26782. * Create the schema parser context.
  26783. */
  26784. if ((vctxt->pctxt == NULL) &&
  26785. (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
  26786. return (-1);
  26787. pctxt = vctxt->pctxt;
  26788. pctxt->xsiAssemble = 1;
  26789. /*
  26790. * Create the schema.
  26791. */
  26792. vctxt->schema = xmlSchemaNewSchema(pctxt);
  26793. if (vctxt->schema == NULL)
  26794. return (-1);
  26795. /*
  26796. * Create the schema construction context.
  26797. */
  26798. pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
  26799. if (pctxt->constructor == NULL)
  26800. return(-1);
  26801. pctxt->constructor->mainSchema = vctxt->schema;
  26802. /*
  26803. * Take ownership of the constructor to be able to free it.
  26804. */
  26805. pctxt->ownsConstructor = 1;
  26806. }
  26807. /*
  26808. * Augment the IDC definitions for the main schema and all imported ones
  26809. * NOTE: main schema if the first in the imported list
  26810. */
  26811. xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
  26812. vctxt);
  26813. return(0);
  26814. }
  26815. static void
  26816. xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
  26817. if (vctxt->xsiAssemble) {
  26818. if (vctxt->schema != NULL) {
  26819. xmlSchemaFree(vctxt->schema);
  26820. vctxt->schema = NULL;
  26821. }
  26822. }
  26823. xmlSchemaClearValidCtxt(vctxt);
  26824. }
  26825. static int
  26826. xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
  26827. {
  26828. int ret = 0;
  26829. if (xmlSchemaPreRun(vctxt) < 0)
  26830. return(-1);
  26831. if (vctxt->doc != NULL) {
  26832. /*
  26833. * Tree validation.
  26834. */
  26835. ret = xmlSchemaVDocWalk(vctxt);
  26836. #ifdef LIBXML_READER_ENABLED
  26837. } else if (vctxt->reader != NULL) {
  26838. /*
  26839. * XML Reader validation.
  26840. */
  26841. #ifdef XML_SCHEMA_READER_ENABLED
  26842. ret = xmlSchemaVReaderWalk(vctxt);
  26843. #endif
  26844. #endif
  26845. } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
  26846. /*
  26847. * SAX validation.
  26848. */
  26849. ret = xmlParseDocument(vctxt->parserCtxt);
  26850. } else {
  26851. VERROR_INT("xmlSchemaVStart",
  26852. "no instance to validate");
  26853. ret = -1;
  26854. }
  26855. xmlSchemaPostRun(vctxt);
  26856. if (ret == 0)
  26857. ret = vctxt->err;
  26858. return (ret);
  26859. }
  26860. /**
  26861. * xmlSchemaValidateOneElement:
  26862. * @ctxt: a schema validation context
  26863. * @elem: an element node
  26864. *
  26865. * Validate a branch of a tree, starting with the given @elem.
  26866. *
  26867. * Returns 0 if the element and its subtree is valid, a positive error
  26868. * code number otherwise and -1 in case of an internal or API error.
  26869. */
  26870. int
  26871. xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
  26872. {
  26873. if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
  26874. return (-1);
  26875. if (ctxt->schema == NULL)
  26876. return (-1);
  26877. ctxt->doc = elem->doc;
  26878. ctxt->node = elem;
  26879. ctxt->validationRoot = elem;
  26880. return(xmlSchemaVStart(ctxt));
  26881. }
  26882. /**
  26883. * xmlSchemaValidateDoc:
  26884. * @ctxt: a schema validation context
  26885. * @doc: a parsed document tree
  26886. *
  26887. * Validate a document tree in memory.
  26888. *
  26889. * Returns 0 if the document is schemas valid, a positive error code
  26890. * number otherwise and -1 in case of internal or API error.
  26891. */
  26892. int
  26893. xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
  26894. {
  26895. if ((ctxt == NULL) || (doc == NULL))
  26896. return (-1);
  26897. ctxt->doc = doc;
  26898. ctxt->node = xmlDocGetRootElement(doc);
  26899. if (ctxt->node == NULL) {
  26900. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  26901. XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
  26902. (xmlNodePtr) doc, NULL,
  26903. "The document has no document element", NULL, NULL);
  26904. return (ctxt->err);
  26905. }
  26906. ctxt->validationRoot = ctxt->node;
  26907. return (xmlSchemaVStart(ctxt));
  26908. }
  26909. /************************************************************************
  26910. * *
  26911. * Function and data for SAX streaming API *
  26912. * *
  26913. ************************************************************************/
  26914. typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
  26915. typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
  26916. struct _xmlSchemaSplitSAXData {
  26917. xmlSAXHandlerPtr user_sax;
  26918. void *user_data;
  26919. xmlSchemaValidCtxtPtr ctxt;
  26920. xmlSAXHandlerPtr schemas_sax;
  26921. };
  26922. #define XML_SAX_PLUG_MAGIC 0xdc43ba21
  26923. struct _xmlSchemaSAXPlug {
  26924. unsigned int magic;
  26925. /* the original callbacks information */
  26926. xmlSAXHandlerPtr *user_sax_ptr;
  26927. xmlSAXHandlerPtr user_sax;
  26928. void **user_data_ptr;
  26929. void *user_data;
  26930. /* the block plugged back and validation information */
  26931. xmlSAXHandler schemas_sax;
  26932. xmlSchemaValidCtxtPtr ctxt;
  26933. };
  26934. /* All those functions just bounces to the user provided SAX handlers */
  26935. static void
  26936. internalSubsetSplit(void *ctx, const xmlChar *name,
  26937. const xmlChar *ExternalID, const xmlChar *SystemID)
  26938. {
  26939. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26940. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26941. (ctxt->user_sax->internalSubset != NULL))
  26942. ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
  26943. SystemID);
  26944. }
  26945. static int
  26946. isStandaloneSplit(void *ctx)
  26947. {
  26948. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26949. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26950. (ctxt->user_sax->isStandalone != NULL))
  26951. return(ctxt->user_sax->isStandalone(ctxt->user_data));
  26952. return(0);
  26953. }
  26954. static int
  26955. hasInternalSubsetSplit(void *ctx)
  26956. {
  26957. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26958. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26959. (ctxt->user_sax->hasInternalSubset != NULL))
  26960. return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
  26961. return(0);
  26962. }
  26963. static int
  26964. hasExternalSubsetSplit(void *ctx)
  26965. {
  26966. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26967. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26968. (ctxt->user_sax->hasExternalSubset != NULL))
  26969. return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
  26970. return(0);
  26971. }
  26972. static void
  26973. externalSubsetSplit(void *ctx, const xmlChar *name,
  26974. const xmlChar *ExternalID, const xmlChar *SystemID)
  26975. {
  26976. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26977. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26978. (ctxt->user_sax->externalSubset != NULL))
  26979. ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
  26980. SystemID);
  26981. }
  26982. static xmlParserInputPtr
  26983. resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
  26984. {
  26985. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26986. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26987. (ctxt->user_sax->resolveEntity != NULL))
  26988. return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
  26989. systemId));
  26990. return(NULL);
  26991. }
  26992. static xmlEntityPtr
  26993. getEntitySplit(void *ctx, const xmlChar *name)
  26994. {
  26995. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26996. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26997. (ctxt->user_sax->getEntity != NULL))
  26998. return(ctxt->user_sax->getEntity(ctxt->user_data, name));
  26999. return(NULL);
  27000. }
  27001. static xmlEntityPtr
  27002. getParameterEntitySplit(void *ctx, const xmlChar *name)
  27003. {
  27004. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27005. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27006. (ctxt->user_sax->getParameterEntity != NULL))
  27007. return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
  27008. return(NULL);
  27009. }
  27010. static void
  27011. entityDeclSplit(void *ctx, const xmlChar *name, int type,
  27012. const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
  27013. {
  27014. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27015. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27016. (ctxt->user_sax->entityDecl != NULL))
  27017. ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
  27018. systemId, content);
  27019. }
  27020. static void
  27021. attributeDeclSplit(void *ctx, const xmlChar * elem,
  27022. const xmlChar * name, int type, int def,
  27023. const xmlChar * defaultValue, xmlEnumerationPtr tree)
  27024. {
  27025. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27026. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27027. (ctxt->user_sax->attributeDecl != NULL)) {
  27028. ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
  27029. def, defaultValue, tree);
  27030. } else {
  27031. xmlFreeEnumeration(tree);
  27032. }
  27033. }
  27034. static void
  27035. elementDeclSplit(void *ctx, const xmlChar *name, int type,
  27036. xmlElementContentPtr content)
  27037. {
  27038. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27039. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27040. (ctxt->user_sax->elementDecl != NULL))
  27041. ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
  27042. }
  27043. static void
  27044. notationDeclSplit(void *ctx, const xmlChar *name,
  27045. const xmlChar *publicId, const xmlChar *systemId)
  27046. {
  27047. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27048. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27049. (ctxt->user_sax->notationDecl != NULL))
  27050. ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
  27051. systemId);
  27052. }
  27053. static void
  27054. unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
  27055. const xmlChar *publicId, const xmlChar *systemId,
  27056. const xmlChar *notationName)
  27057. {
  27058. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27059. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27060. (ctxt->user_sax->unparsedEntityDecl != NULL))
  27061. ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
  27062. systemId, notationName);
  27063. }
  27064. static void
  27065. setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
  27066. {
  27067. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27068. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27069. (ctxt->user_sax->setDocumentLocator != NULL))
  27070. ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
  27071. }
  27072. static void
  27073. startDocumentSplit(void *ctx)
  27074. {
  27075. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27076. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27077. (ctxt->user_sax->startDocument != NULL))
  27078. ctxt->user_sax->startDocument(ctxt->user_data);
  27079. }
  27080. static void
  27081. endDocumentSplit(void *ctx)
  27082. {
  27083. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27084. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27085. (ctxt->user_sax->endDocument != NULL))
  27086. ctxt->user_sax->endDocument(ctxt->user_data);
  27087. }
  27088. static void
  27089. processingInstructionSplit(void *ctx, const xmlChar *target,
  27090. const xmlChar *data)
  27091. {
  27092. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27093. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27094. (ctxt->user_sax->processingInstruction != NULL))
  27095. ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
  27096. }
  27097. static void
  27098. commentSplit(void *ctx, const xmlChar *value)
  27099. {
  27100. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27101. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27102. (ctxt->user_sax->comment != NULL))
  27103. ctxt->user_sax->comment(ctxt->user_data, value);
  27104. }
  27105. /*
  27106. * Varargs error callbacks to the user application, harder ...
  27107. */
  27108. static void XMLCDECL
  27109. warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  27110. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27111. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27112. (ctxt->user_sax->warning != NULL)) {
  27113. TODO
  27114. }
  27115. }
  27116. static void XMLCDECL
  27117. errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  27118. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27119. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27120. (ctxt->user_sax->error != NULL)) {
  27121. TODO
  27122. }
  27123. }
  27124. static void XMLCDECL
  27125. fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  27126. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27127. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27128. (ctxt->user_sax->fatalError != NULL)) {
  27129. TODO
  27130. }
  27131. }
  27132. /*
  27133. * Those are function where both the user handler and the schemas handler
  27134. * need to be called.
  27135. */
  27136. static void
  27137. charactersSplit(void *ctx, const xmlChar *ch, int len)
  27138. {
  27139. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27140. if (ctxt == NULL)
  27141. return;
  27142. if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
  27143. ctxt->user_sax->characters(ctxt->user_data, ch, len);
  27144. if (ctxt->ctxt != NULL)
  27145. xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
  27146. }
  27147. static void
  27148. ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
  27149. {
  27150. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27151. if (ctxt == NULL)
  27152. return;
  27153. if ((ctxt->user_sax != NULL) &&
  27154. (ctxt->user_sax->ignorableWhitespace != NULL))
  27155. ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
  27156. if (ctxt->ctxt != NULL)
  27157. xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
  27158. }
  27159. static void
  27160. cdataBlockSplit(void *ctx, const xmlChar *value, int len)
  27161. {
  27162. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27163. if (ctxt == NULL)
  27164. return;
  27165. if ((ctxt->user_sax != NULL) &&
  27166. (ctxt->user_sax->cdataBlock != NULL))
  27167. ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
  27168. if (ctxt->ctxt != NULL)
  27169. xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
  27170. }
  27171. static void
  27172. referenceSplit(void *ctx, const xmlChar *name)
  27173. {
  27174. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27175. if (ctxt == NULL)
  27176. return;
  27177. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  27178. (ctxt->user_sax->reference != NULL))
  27179. ctxt->user_sax->reference(ctxt->user_data, name);
  27180. if (ctxt->ctxt != NULL)
  27181. xmlSchemaSAXHandleReference(ctxt->user_data, name);
  27182. }
  27183. static void
  27184. startElementNsSplit(void *ctx, const xmlChar * localname,
  27185. const xmlChar * prefix, const xmlChar * URI,
  27186. int nb_namespaces, const xmlChar ** namespaces,
  27187. int nb_attributes, int nb_defaulted,
  27188. const xmlChar ** attributes) {
  27189. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27190. if (ctxt == NULL)
  27191. return;
  27192. if ((ctxt->user_sax != NULL) &&
  27193. (ctxt->user_sax->startElementNs != NULL))
  27194. ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
  27195. URI, nb_namespaces, namespaces,
  27196. nb_attributes, nb_defaulted,
  27197. attributes);
  27198. if (ctxt->ctxt != NULL)
  27199. xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
  27200. URI, nb_namespaces, namespaces,
  27201. nb_attributes, nb_defaulted,
  27202. attributes);
  27203. }
  27204. static void
  27205. endElementNsSplit(void *ctx, const xmlChar * localname,
  27206. const xmlChar * prefix, const xmlChar * URI) {
  27207. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27208. if (ctxt == NULL)
  27209. return;
  27210. if ((ctxt->user_sax != NULL) &&
  27211. (ctxt->user_sax->endElementNs != NULL))
  27212. ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
  27213. if (ctxt->ctxt != NULL)
  27214. xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
  27215. }
  27216. /**
  27217. * xmlSchemaSAXPlug:
  27218. * @ctxt: a schema validation context
  27219. * @sax: a pointer to the original xmlSAXHandlerPtr
  27220. * @user_data: a pointer to the original SAX user data pointer
  27221. *
  27222. * Plug a SAX based validation layer in a SAX parsing event flow.
  27223. * The original @saxptr and @dataptr data are replaced by new pointers
  27224. * but the calls to the original will be maintained.
  27225. *
  27226. * Returns a pointer to a data structure needed to unplug the validation layer
  27227. * or NULL in case of errors.
  27228. */
  27229. xmlSchemaSAXPlugPtr
  27230. xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
  27231. xmlSAXHandlerPtr *sax, void **user_data)
  27232. {
  27233. xmlSchemaSAXPlugPtr ret;
  27234. xmlSAXHandlerPtr old_sax;
  27235. if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
  27236. return(NULL);
  27237. /*
  27238. * We only allow to plug into SAX2 event streams
  27239. */
  27240. old_sax = *sax;
  27241. if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
  27242. return(NULL);
  27243. if ((old_sax != NULL) &&
  27244. (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
  27245. ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
  27246. return(NULL);
  27247. /*
  27248. * everything seems right allocate the local data needed for that layer
  27249. */
  27250. ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
  27251. if (ret == NULL) {
  27252. return(NULL);
  27253. }
  27254. memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
  27255. ret->magic = XML_SAX_PLUG_MAGIC;
  27256. ret->schemas_sax.initialized = XML_SAX2_MAGIC;
  27257. ret->ctxt = ctxt;
  27258. ret->user_sax_ptr = sax;
  27259. ret->user_sax = old_sax;
  27260. if (old_sax == NULL) {
  27261. /*
  27262. * go direct, no need for the split block and functions.
  27263. */
  27264. ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
  27265. ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
  27266. /*
  27267. * Note that we use the same text-function for both, to prevent
  27268. * the parser from testing for ignorable whitespace.
  27269. */
  27270. ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
  27271. ret->schemas_sax.characters = xmlSchemaSAXHandleText;
  27272. ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
  27273. ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
  27274. ret->user_data = ctxt;
  27275. *user_data = ctxt;
  27276. } else {
  27277. /*
  27278. * for each callback unused by Schemas initialize it to the Split
  27279. * routine only if non NULL in the user block, this can speed up
  27280. * things at the SAX level.
  27281. */
  27282. if (old_sax->internalSubset != NULL)
  27283. ret->schemas_sax.internalSubset = internalSubsetSplit;
  27284. if (old_sax->isStandalone != NULL)
  27285. ret->schemas_sax.isStandalone = isStandaloneSplit;
  27286. if (old_sax->hasInternalSubset != NULL)
  27287. ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
  27288. if (old_sax->hasExternalSubset != NULL)
  27289. ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
  27290. if (old_sax->resolveEntity != NULL)
  27291. ret->schemas_sax.resolveEntity = resolveEntitySplit;
  27292. if (old_sax->getEntity != NULL)
  27293. ret->schemas_sax.getEntity = getEntitySplit;
  27294. if (old_sax->entityDecl != NULL)
  27295. ret->schemas_sax.entityDecl = entityDeclSplit;
  27296. if (old_sax->notationDecl != NULL)
  27297. ret->schemas_sax.notationDecl = notationDeclSplit;
  27298. if (old_sax->attributeDecl != NULL)
  27299. ret->schemas_sax.attributeDecl = attributeDeclSplit;
  27300. if (old_sax->elementDecl != NULL)
  27301. ret->schemas_sax.elementDecl = elementDeclSplit;
  27302. if (old_sax->unparsedEntityDecl != NULL)
  27303. ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
  27304. if (old_sax->setDocumentLocator != NULL)
  27305. ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
  27306. if (old_sax->startDocument != NULL)
  27307. ret->schemas_sax.startDocument = startDocumentSplit;
  27308. if (old_sax->endDocument != NULL)
  27309. ret->schemas_sax.endDocument = endDocumentSplit;
  27310. if (old_sax->processingInstruction != NULL)
  27311. ret->schemas_sax.processingInstruction = processingInstructionSplit;
  27312. if (old_sax->comment != NULL)
  27313. ret->schemas_sax.comment = commentSplit;
  27314. if (old_sax->warning != NULL)
  27315. ret->schemas_sax.warning = warningSplit;
  27316. if (old_sax->error != NULL)
  27317. ret->schemas_sax.error = errorSplit;
  27318. if (old_sax->fatalError != NULL)
  27319. ret->schemas_sax.fatalError = fatalErrorSplit;
  27320. if (old_sax->getParameterEntity != NULL)
  27321. ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
  27322. if (old_sax->externalSubset != NULL)
  27323. ret->schemas_sax.externalSubset = externalSubsetSplit;
  27324. /*
  27325. * the 6 schemas callback have to go to the splitter functions
  27326. * Note that we use the same text-function for ignorableWhitespace
  27327. * if possible, to prevent the parser from testing for ignorable
  27328. * whitespace.
  27329. */
  27330. ret->schemas_sax.characters = charactersSplit;
  27331. if ((old_sax->ignorableWhitespace != NULL) &&
  27332. (old_sax->ignorableWhitespace != old_sax->characters))
  27333. ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
  27334. else
  27335. ret->schemas_sax.ignorableWhitespace = charactersSplit;
  27336. ret->schemas_sax.cdataBlock = cdataBlockSplit;
  27337. ret->schemas_sax.reference = referenceSplit;
  27338. ret->schemas_sax.startElementNs = startElementNsSplit;
  27339. ret->schemas_sax.endElementNs = endElementNsSplit;
  27340. ret->user_data_ptr = user_data;
  27341. ret->user_data = *user_data;
  27342. *user_data = ret;
  27343. }
  27344. /*
  27345. * plug the pointers back.
  27346. */
  27347. *sax = &(ret->schemas_sax);
  27348. ctxt->sax = *sax;
  27349. ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
  27350. xmlSchemaPreRun(ctxt);
  27351. return(ret);
  27352. }
  27353. /**
  27354. * xmlSchemaSAXUnplug:
  27355. * @plug: a data structure returned by xmlSchemaSAXPlug
  27356. *
  27357. * Unplug a SAX based validation layer in a SAX parsing event flow.
  27358. * The original pointers used in the call are restored.
  27359. *
  27360. * Returns 0 in case of success and -1 in case of failure.
  27361. */
  27362. int
  27363. xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
  27364. {
  27365. xmlSAXHandlerPtr *sax;
  27366. void **user_data;
  27367. if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
  27368. return(-1);
  27369. plug->magic = 0;
  27370. xmlSchemaPostRun(plug->ctxt);
  27371. /* restore the data */
  27372. sax = plug->user_sax_ptr;
  27373. *sax = plug->user_sax;
  27374. if (plug->user_sax != NULL) {
  27375. user_data = plug->user_data_ptr;
  27376. *user_data = plug->user_data;
  27377. }
  27378. /* free and return */
  27379. xmlFree(plug);
  27380. return(0);
  27381. }
  27382. /**
  27383. * xmlSchemaValidateSetLocator:
  27384. * @vctxt: a schema validation context
  27385. * @f: the locator function pointer
  27386. * @ctxt: the locator context
  27387. *
  27388. * Allows to set a locator function to the validation context,
  27389. * which will be used to provide file and line information since
  27390. * those are not provided as part of the SAX validation flow
  27391. * Setting @f to NULL disable the locator.
  27392. */
  27393. void
  27394. xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
  27395. xmlSchemaValidityLocatorFunc f,
  27396. void *ctxt)
  27397. {
  27398. if (vctxt == NULL) return;
  27399. vctxt->locFunc = f;
  27400. vctxt->locCtxt = ctxt;
  27401. }
  27402. /**
  27403. * xmlSchemaValidateStreamLocator:
  27404. * @ctx: the xmlTextReaderPtr used
  27405. * @file: returned file information
  27406. * @line: returned line information
  27407. *
  27408. * Internal locator function for the readers
  27409. *
  27410. * Returns 0 in case the Schema validation could be (de)activated and
  27411. * -1 in case of error.
  27412. */
  27413. static int
  27414. xmlSchemaValidateStreamLocator(void *ctx, const char **file,
  27415. unsigned long *line) {
  27416. xmlParserCtxtPtr ctxt;
  27417. if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
  27418. return(-1);
  27419. if (file != NULL)
  27420. *file = NULL;
  27421. if (line != NULL)
  27422. *line = 0;
  27423. ctxt = (xmlParserCtxtPtr) ctx;
  27424. if (ctxt->input != NULL) {
  27425. if (file != NULL)
  27426. *file = ctxt->input->filename;
  27427. if (line != NULL)
  27428. *line = ctxt->input->line;
  27429. return(0);
  27430. }
  27431. return(-1);
  27432. }
  27433. /**
  27434. * xmlSchemaValidateStream:
  27435. * @ctxt: a schema validation context
  27436. * @input: the input to use for reading the data
  27437. * @enc: an optional encoding information
  27438. * @sax: a SAX handler for the resulting events
  27439. * @user_data: the context to provide to the SAX handler.
  27440. *
  27441. * Validate an input based on a flow of SAX event from the parser
  27442. * and forward the events to the @sax handler with the provided @user_data
  27443. * the user provided @sax handler must be a SAX2 one.
  27444. *
  27445. * Returns 0 if the document is schemas valid, a positive error code
  27446. * number otherwise and -1 in case of internal or API error.
  27447. */
  27448. int
  27449. xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
  27450. xmlParserInputBufferPtr input, xmlCharEncoding enc,
  27451. xmlSAXHandlerPtr sax, void *user_data)
  27452. {
  27453. xmlSchemaSAXPlugPtr plug = NULL;
  27454. xmlSAXHandlerPtr old_sax = NULL;
  27455. xmlParserCtxtPtr pctxt = NULL;
  27456. xmlParserInputPtr inputStream = NULL;
  27457. int ret;
  27458. if ((ctxt == NULL) || (input == NULL))
  27459. return (-1);
  27460. /*
  27461. * prepare the parser
  27462. */
  27463. pctxt = xmlNewParserCtxt();
  27464. if (pctxt == NULL)
  27465. return (-1);
  27466. old_sax = pctxt->sax;
  27467. pctxt->sax = sax;
  27468. pctxt->userData = user_data;
  27469. #if 0
  27470. if (options)
  27471. xmlCtxtUseOptions(pctxt, options);
  27472. #endif
  27473. pctxt->linenumbers = 1;
  27474. xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
  27475. inputStream = xmlNewIOInputStream(pctxt, input, enc);;
  27476. if (inputStream == NULL) {
  27477. ret = -1;
  27478. goto done;
  27479. }
  27480. inputPush(pctxt, inputStream);
  27481. ctxt->parserCtxt = pctxt;
  27482. ctxt->input = input;
  27483. /*
  27484. * Plug the validation and launch the parsing
  27485. */
  27486. plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
  27487. if (plug == NULL) {
  27488. ret = -1;
  27489. goto done;
  27490. }
  27491. ctxt->input = input;
  27492. ctxt->enc = enc;
  27493. ctxt->sax = pctxt->sax;
  27494. ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
  27495. ret = xmlSchemaVStart(ctxt);
  27496. if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
  27497. ret = ctxt->parserCtxt->errNo;
  27498. if (ret == 0)
  27499. ret = 1;
  27500. }
  27501. done:
  27502. ctxt->parserCtxt = NULL;
  27503. ctxt->sax = NULL;
  27504. ctxt->input = NULL;
  27505. if (plug != NULL) {
  27506. xmlSchemaSAXUnplug(plug);
  27507. }
  27508. /* cleanup */
  27509. if (pctxt != NULL) {
  27510. pctxt->sax = old_sax;
  27511. xmlFreeParserCtxt(pctxt);
  27512. }
  27513. return (ret);
  27514. }
  27515. /**
  27516. * xmlSchemaValidateFile:
  27517. * @ctxt: a schema validation context
  27518. * @filename: the URI of the instance
  27519. * @options: a future set of options, currently unused
  27520. *
  27521. * Do a schemas validation of the given resource, it will use the
  27522. * SAX streamable validation internally.
  27523. *
  27524. * Returns 0 if the document is valid, a positive error code
  27525. * number otherwise and -1 in case of an internal or API error.
  27526. */
  27527. int
  27528. xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
  27529. const char * filename,
  27530. int options ATTRIBUTE_UNUSED)
  27531. {
  27532. int ret;
  27533. xmlParserInputBufferPtr input;
  27534. if ((ctxt == NULL) || (filename == NULL))
  27535. return (-1);
  27536. input = xmlParserInputBufferCreateFilename(filename,
  27537. XML_CHAR_ENCODING_NONE);
  27538. if (input == NULL)
  27539. return (-1);
  27540. ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
  27541. NULL, NULL);
  27542. return (ret);
  27543. }
  27544. /**
  27545. * xmlSchemaValidCtxtGetParserCtxt:
  27546. * @ctxt: a schema validation context
  27547. *
  27548. * allow access to the parser context of the schema validation context
  27549. *
  27550. * Returns the parser context of the schema validation context or NULL
  27551. * in case of error.
  27552. */
  27553. xmlParserCtxtPtr
  27554. xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
  27555. {
  27556. if (ctxt == NULL)
  27557. return(NULL);
  27558. return (ctxt->parserCtxt);
  27559. }
  27560. #define bottom_xmlschemas
  27561. #include "elfgcchack.h"
  27562. #endif /* LIBXML_SCHEMAS_ENABLED */